<Previous> <Next> <SDK Top> <Top>
4章.2節.コンボボックスに使用できるフォントを並べてみよう
コンボボックスに使用できるフォント名を並べていきましょう.
しかも今回は,コンボボックスに表示される文字もコンパクトにしてやりましょう.
コンボボックスのIDは前回と同じですね.
(IDの作り方を知らない方は,「別章.2節.ストリングテーブルを編集してみよう」を先に読んでください.)
ID | キャプション |
IDC_COMBO | コンボボックス |
今回のポイントは,
@コンボボックスの文字をどうやってコンパクトにみせるの?
Aコンボボックスに使用できるフォントを並べるの?
というところです.
では,プログラムを見ましょう.
#include "stdafx.h" #include <commctrl.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") #define MAX_LOADSTRING 100 #define TOOL_HEIGHT (30) // グローバル変数: HINSTANCE hInst; // 現在のインスタンス TCHAR szTitle[MAX_LOADSTRING]; // タイトル バー テキスト TCHAR szWindowClass[MAX_LOADSTRING]; // タイトル バー テキスト // このコード モジュールに含まれる関数の前宣言: ATOM MyRegisterClass( HINSTANCE hInstance ); BOOL InitInstance( HINSTANCE, int ); LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); HWND ToolBarCreate(HWND hWnd); HWND ComboBoxCreate(int id, HWND hParent, int nX, int nY, int nWidth, int nHeight); void ComboBoxSetTopString(char *pszBuf); void ComboBoxEnumFonts(HWND hWnd); int CALLBACK EnumFontsProc(LOGFONT *lplf,TEXTMETRIC *lptm,DWORD dwType,LPARAM lpData); HWND hToolBar; HWND hCombo; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MSG msg; HACCEL hAccelTable; // グローバル ストリングを初期化します LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_SAMPLE, szWindowClass, MAX_LOADSTRING); MyRegisterClass( hInstance ); // アプリケーションの初期化を行います: if( !InitInstance( hInstance, nCmdShow ) ) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SAMPLE); // メイン メッセージ ループ: while( GetMessage(&msg, NULL, 0, 0) ) { if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } return msg.wParam; } ATOM MyRegisterClass( HINSTANCE hInstance ) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SAMPLE); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_SAMPLE; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx( &wcex ); } BOOL InitInstance( HINSTANCE hInstance, int nCmdShow ) { HWND hWnd; hInst = hInstance; // グローバル変数にインスタンス ハンドルを保存します hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if( !hWnd ) { return FALSE; } ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; static char szBuf[256]=""; switch( message ) { case WM_CREATE: // ツールバーを作る hToolBar = ToolBarCreate( hWnd ); // コンボボックスを作る hCombo = ComboBoxCreate(IDC_COMBO, hToolBar, 0, 0, 200, 200); // コンボボックスに使用できるフォント名を追加する ComboBoxEnumFonts(hWnd); // コンボボックスの初期表示文字列を決める ComboBoxSetTopString("MS ゴシック"); break; case WM_SIZE: MoveWindow(hToolBar, 0, 0, LOWORD(lParam), TOOL_HEIGHT, TRUE); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } HWND ToolBarCreate(HWND hWnd) { HWND hTool; InitCommonControls(); hTool = CreateWindowEx( WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | CCS_NORESIZE,//| TBSTYLE_FLAT*/, 0,0,0,0, hWnd, NULL, hInst, NULL); SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); return hTool; } HWND ComboBoxCreate(int id, HWND hParent, int nX, int nY, int nWidth, int nHeight) { hCombo = CreateWindow( "COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_AUTOHSCROLL| WS_CLIPSIBLINGS | WS_VSCROLL, nX, nY, nWidth, nHeight, hParent, (HMENU)id, (HINSTANCE)hInst, NULL); return hCombo; } void ComboBoxSetTopString(char *pszBuf) { WPARAM index; index = SendMessage(hCombo, CB_FINDSTRINGEXACT, -1, (LPARAM)pszBuf); SendMessage(hCombo, CB_SETCURSEL, index, 0); } void ComboBoxEnumFonts(HWND hWnd) { HDC hdc; SendMessage(hCombo, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(FALSE, 0)); hdc = GetDC(hWnd); EnumFontFamilies(hdc, NULL, (FONTENUMPROC)EnumFontsProc,NULL); ReleaseDC(hWnd, hdc); } int CALLBACK EnumFontsProc(LOGFONT *lplf, TEXTMETRIC *lptm, DWORD dwType, LPARAM lpData) { if (lplf->lfFaceName[0] != '@') SendMessage( hCombo, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName ); return TRUE; }
☆プログラムの解説☆ @コンボボックスの文字をどうやってコンパクトにみせるの? // コンボボックスに使用できるフォント名を追加する ComboBoxEnumFonts(hWnd); ComboBoxEnumFonts関数を自作しました. void ComboBoxEnumFonts(HWND hWnd) { HDC hdc; SendMessage(hCombo, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(FALSE, 0)); hdc = GetDC(hWnd); EnumFontFamilies(hdc, NULL, (FONTENUMPROC)EnumFontsProc,NULL); ReleaseDC(hWnd, hdc); } 関数の中に,SendMessageがありますね. ここで,コンボボックスにWM_SETFONTというメッセージを送っています. このメッセージは,コンボボックスのフォントを変更しろ!と言っているんです. GetStockObject(DEFAULT_GUI_FONT)のDEFAULT_GUI_FONTは, メニューバーなどで使われるユーザーインターフェイス用のデフォルトフォント なんです.コンパクトで見やすいですよね.他にもあるんで,調べてみてください. 関数の他の処理は,Aの内容ですので次を見てください. Aコンボボックスに使用できるフォントを並べるの? void ComboBoxEnumFonts(HWND hWnd) { HDC hdc; SendMessage(hCombo, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(FALSE, 0)); hdc = GetDC(hWnd); EnumFontFamilies(hdc, NULL, (FONTENUMPROC)EnumFontsProc,NULL); ReleaseDC(hWnd, hdc); } 先ほどの関数ですね. SendMessage以降では,EnumFontFamilies(API)を使うために,デバイスコンテキストを取得したりしています. このEnumFontFamilies関数ですが, 使用できるフォントを列挙してくれるAPIなんです!! こんなAPIがあるんですね. その関数の引数の中で気になるのが,EnumFontsProc関数という自作関数です. 引数に関数を指定することがあるんですね.(←実体はアドレスなんですが) その使用できるフォントは,EnumFontsProcにそのフォントの数だけ送られます. int CALLBACK EnumFontsProc(LOGFONT *lplf, TEXTMETRIC *lptm, DWORD dwType, LPARAM lpData) { SendMessage( hCombo, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName ); return TRUE; } 例えば,"MS ゴシック"という有名なフォントがこのEnumFontsProcに送れらてきたとします. そのフォント名を保持している変数は,lplfです. lplf->lfFaceNameがその文字列へのポインタであり,前回と同じSendMessageを使ってコンボボックスに追加しています. つまり,使用できるフォント数が100あるとこのEnumFontsProc関数は100回呼ばれ,SendMessageも100回呼ばれるわけですね.![]()
![]()
![]()
------------------------------------------------------------------------------------------------
当ページの一部または全部を転載、複写、複製することを禁じます。
また,当サイトを利用した結果に関するトラブル等は、一切関与いたしませんのでご容赦下さい。
Update 04/03/12 By 松本義弘
------------------------------------------------------------------------------------------------