タイプフェイス


フォント名の列挙

CreateFont() 関数には、フォントの識別子であるタイプフェイスを指定する引数があります
ユーザーが、システムから故意にフォントを削除するようなことをしていなければ
Windows システムがデフォルトで搭載しているフォントの名前は確実に指定できます

しかし、例えそうだとしても、やはり確実といえるものではありません
システムが保有するフォントは、実行される環境によって異なることを理解し
ユーザーにフォントを選択させる場合、利用できるタイプフェイスを取得する必要があります

Win32 API は指定された条件に適合するフォントを列挙する
EnumFontFamiliesEx() 関数を提供しています
名前からわかるように、この関数は EnumFontFamilies() というを拡張したものです
EnumFontFamilies() は、いまはもう推奨されない関数なので説明はしません
int EnumFontFamiliesEx(
	HDC hdc , LPLOGFONT lpLogfont ,
	FONTENUMPROC lpEnumFontFamExProc,
	LPARAM lParam , DWORD dwFlags
);
hdc にはデバイスコンテキストのハンドルを指定します
lpLogfont は、フォントを検索する条件となる LOGFONT 構造体へのポインタです
ただし、有効なメンバは lfCharSet、lfFaceName、lfPitchAndFamily の3つです

lpEnumFontFamExProc は、コールバック関数へのポインタを指定します
実は、フォントが見つかる毎にここで設定されたコールバック関数が
検索されたフォントの情報を渡されて呼び出されます

lParam には、コールバック関数に、開発者が独自のデータを送れる領域です
例えば、リストウィンドウのハンドルをコールバック関数に渡し
コールバック関数内で、タイプフェイスをリストに追加するという方法があります
dwFlags は予約されている引数で、常に 0 を指定します
戻り値は、コールバック関数が最後に返した値になります

コールバック関数は FONTENUMPROC 型として定義されているもので
これは、次のような型になっています
int CALLBACK EnumFontFamExProc(
	ENUMLOGFONTEX *lpelfe,
	NEWTEXTMETRICEX *lpntme,
	int FontType , LPARAM lParam
);
lpelfe は、ENUMLOGFONTEX 構造体へのポインタです
この構造体は、次のように定義されています
typedef struct tagENUMLOGFONTEX {
    LOGFONT  elfLogFont;
    BCHAR  elfFullName[LF_FULLFACESIZE];
    BCHAR  elfStyle[LF_FACESIZE];
    BCHAR  elfScript[LF_FACESIZE];
} ENUMLOGFONTEX;
elfLogFont は、フォントの情報を表す LOGFONT 構造体
elfFullName には、フォントの完全な名前の文字列を表します
elfStyle はフォントのスタイルで "Bold" や "Italic" などを格納します
elfScript はフォントのスクリプトを表すメンバで、"日本語" や "欧文" などがあります

lpntme は、フォントの物理的属性を表す
NEWTEXTMETRICEX 構造体を表します
ただし、TrueType 以外のフォントであれば TEXTMETRIC 構造体になります
実は、NEWTEXTMETRICEX は TEXTMETRIC に互換性があります
typedef struct tagNEWTEXTMETRICEX {
    NEWTEXTMETRIC  ntmentm;
    FONTSIGNATURE  ntmeFontSignature;
} NEWTEXTMETRICEX;
ntmentm は、TEXTMETRIC 構造体を拡張した NEWTEXTMETRIC 構造体で
ntmeFontSignature はフォントの範囲を指定している FONTSIGNATURE 構造体です
ただし、Windows 95 では、NEWTEXTMETRICEX はサポートされていません
この場合は NEWTEXTMETRIC 構造体を利用してください

NEWTEXTMETRIC は、TEXTMETRIC 互換でメンバを付け足したものです
これは、次のような定義になっています
typedef struct tagNEWTEXTMETRIC { // ntm 
    LONG   tmHeight; 
    LONG   tmAscent; 
    LONG   tmDescent; 
    LONG   tmInternalLeading; 
    LONG   tmExternalLeading; 
    LONG   tmAveCharWidth; 
    LONG   tmMaxCharWidth; 
    LONG   tmWeight; 
    LONG   tmOverhang; 
    LONG   tmDigitizedAspectX; 
    LONG   tmDigitizedAspectY; 
    BCHAR  tmFirstChar; 
    BCHAR  tmLastChar; 
    BCHAR  tmDefaultChar; 
    BCHAR  tmBreakChar; 
    BYTE   tmItalic; 
    BYTE   tmUnderlined; 
    BYTE   tmStruckOut; 
    BYTE   tmPitchAndFamily; 
    BYTE   tmCharSet; 
    DWORD  ntmFlags; 
    UINT   ntmSizeEM; 
    UINT   ntmCellHeight; 
    UINT   ntmAvgWidth; 
} NEWTEXTMETRIC;
tmCharSet までは TEXTMETRIC と同じなので、そちらを参照してください
ntmFlags はフォントの属性をあらわすビットマスクを格納します
ビットマスクは、次のように定義されています

ビット解説
0斜体
1下線付き
2反転
3袋文字
4打消し線付き
5太字

ntmSizeEM は論理単位でフォントの全角のサイズ
ntmCellHeight は ntmSizeEM と比較したフォントの高さ
ntmAvgWidth は ntmSizeEM と比較した、フォントキャラクタの平均幅を表します

FONTSIGNATURE 構造体は次のように定義されています
typedef struct tagFONTSIGNATURE {
    DWORD  fsUsb[4];
    DWORD  fsCsb[2];
} FONTSIGNATURE;
fsUsb は、128 ビットで Unicode Subset Bitfield (USB) を表します
fsCsb は、64 ビットで Code-Page Bitfield (CPB) を表します
これらについては Microsoft の MSDN ライブラリなどを参照してください
また、Unicode についても Win32 API の分野ではないので、この場で説明はしません

再びコールバック関数の引数の説明に戻ります
FontType は、フォントのタイプが格納されています
これを用いれば、フォントが TrueType かビットマップフォント化などを調べられます

定数解説
EVICE_FONTTYPE デバイスフォント
RASTER_FONTTYPE ラストフォント
TRUETYPE_FONTTYPE TrueType フォント

lParam には、EnumFontFamiliesEx() の lParam 引数で指定した値が入ります
この引数を使って、独自のパラメータの受け渡しをすることができるということです

コールバック関数は、列挙を続けるならば 0 以外を
列挙を中断するならば 0 を指定します
#include <windows.h>

#define TITLE TEXT("Kitty on your lap")

int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe ,
			NEWTEXTMETRICEX *lpntme ,
			int FontType , LPARAM lParam) {
	TCHAR strAdd[LF_FACESIZE * 3];
	wsprintf(strAdd , "%s %s %s" , lpelfe->elfLogFont.lfFaceName ,
			lpelfe->elfStyle , lpelfe->elfScript);
	SendMessage((HWND)lParam , LB_ADDSTRING , 0 , (long)strAdd);
	return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;
	HWND hList;
	static LOGFONT lfFont;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		hList = CreateWindow(
			TEXT("LISTBOX") , NULL , 
			WS_CHILD | WS_VISIBLE | LBS_STANDARD , 
			0 , 0 , 400 , 100 , hWnd , (HMENU)1 ,
			((LPCREATESTRUCT)(lp))->hInstance , NULL
		);

		lfFont.lfCharSet = DEFAULT_CHARSET;
		lfFont.lfFaceName[0] = 0;
		lfFont.lfPitchAndFamily = 0;
		hdc = GetDC(hWnd);
		EnumFontFamiliesEx(hdc , &lfFont ,
			EnumFontFamExProc , (LPARAM)hList , 0);
		ReleaseDC(hWnd , hdc);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hWnd , &ps);

		EndPaint(hWnd , &ps);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;

	winc.style 		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc		= WndProc;
	winc.cbClsExtra		= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return 1;

	hWnd = CreateWindow(
			TEXT("KITTY") , TITLE ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);

	if (hWnd == NULL) return 1;

	while (GetMessage(&msg , NULL , 0 , 0 )) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


このプログラムは、リストボックスに使用可能なタイプフェイスを列挙するものです
こので列挙されるフォントは、実行される環境によって異なるでしょう

EnumFontFamiliesEx() 関数が実行されると、条件を元にフォントを検索し
フォントが検索されるごとに EnumFontFamExProc() が呼び出されます
このコールバック関数では lParam に渡されたリストボックスのハンドルに
LB_ADDSTRING メッセージを送信して、検索されたフォントのタイプフェイスを追加しています


EnumFontFamiliesEx()

int EnumFontFamiliesEx(
	HDC hdc , LPLOGFONT lpLogfont ,
	FONTENUMPROC lpEnumFontFamExProc,
	LPARAM lParam , DWORD dwFlags
);
指定した条件に一致したフォントを列挙します

hdc - デバイスコンテキストのハンドルを指定します
lpLogfont - 検索の条件となる LOGFONT 構造体へのポインタを指定します
lpEnumFontFamExProc - 一致した情報を渡す関数へのポインタを指定します
lParam - lpEnumFontFamExProc に渡す追加情報を指定します
dwFlags - 予約されています。必ず 0 を指定しなければなりません

戻り値 - コールバック関数が最後に返した値

EnumFontFamExProc()

int CALLBACK EnumFontFamExProc(
	ENUMLOGFONTEX *lpelfe,
	NEWTEXTMETRICEX *lpntme,
	int FontType , LPARAM lParam
);
EnumFontFamiliesEx() と組み合わせて使う
ユーザー定義のコールバック関数です

lpelfe - 論理的な情報が入った ENUMLOGFONTEX 構造体へのポインタです
lpntme - 物理的な情報が入った NEWTEXTMETRICEX 構造体へのポインタです
FontType - フォントの種類を示します
lParam - EnumFontFamiliesEx() の lParam パラメータで指定した値が入ります

戻り値 - 列挙を続けるなら 0 以外。そうでなければ 0

FontType には次の定数の組み合わせが入ります

定数解説
EVICE_FONTTYPE デバイスフォント
RASTER_FONTTYPE ラストフォント
TRUETYPE_FONTTYPE TrueType フォント



前のページへ戻る次のページへ