第39章 ChooseFont関数の具体例


今回は、ChooseFont関数の具体例を示します。

// font03.cpp #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, LPCSTR, int); int setcf(CHOOSEFONT *); int draw_on = 0; CHOOSEFONT cf; LOGFONT logfont; HWND hParent;

このプログラムでは、ヘッダーファイルはresource.hに任せています。 また、親ウィンドウのハンドルをコピーしておくためのhParentも グローバル変数に用意しておきます。

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; char szClassName[] = "font03"; //ウィンドウクラス if (!hPrevInst) { if (!InitApp(hCurInst, szClassName)) return FALSE; } if (!InitInstance(hCurInst, szClassName, nCmdShow)) { return FALSE; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }

ここは、いつもと同じです。

//ウィンドウ・クラスの登録 BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; //インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MYMENU"; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClass(&wc)); }

ここも、いつもと同じです。

//ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるフォント", //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 CW_USEDEFAULT, //幅 CW_USEDEFAULT, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hParent = hWnd; strcpy(logfont.lfFaceName, "MS ゴシック"); setcf(&cf); return TRUE; }

親のウィンドウを作り終わった後で、少しだけログフォント構造体の メンバを設定しています。ここでは、"MS ゴシック"と設定しています。 こうすることによって、一番最初にダイアログボックスが現れたときに、 "MS ゴシック"が選択された状態になります。(別に設定しなくてもよい) 次に自作関数setcfによって、CHOOSEFONT構造体の設定をしています。 (中身は後述)

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static draw_on = 0; int id; HDC hdc; PAINTSTRUCT ps; HFONT hFont, hOldf; COLORREF crOldc; switch (msg) { case WM_COMMAND: switch (LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0L, 0L); break; case IDM_FONT: if(ChooseFont(&cf) ==TRUE) { InvalidateRect(hWnd, NULL, TRUE); draw_on = 1; } break; } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); hFont = CreateFontIndirect(cf.lpLogFont); hOldf = SelectObject(hdc, hFont); crOldc = SetTextColor(hdc, cf.rgbColors); if(draw_on) TextOut(hdc, 10, 10, (LPCTSTR)"猫でもわかる", 12); SelectObject(hdc, hOldf); SetTextColor(hdc, crOldc); DeleteObject(hFont); EndPaint(hWnd, &ps); break; case WM_CLOSE: id = MessageBox(hWnd, (LPCTSTR)"終了してもよいですか", (LPCTSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

メニューの中のIDM_FONTが選ばれたときChooseFont関数が 実行されます。そして、この関数がTRUEを返したとき(OKボタンが 押されたとき)クライアント領域全体を書き直しています。

WM_PAINTメッセージが来たら、いつものように BeginPaintとEndPaintの間に描画関数を書きます。 書き終わったら、元の色とかフォントに戻しています。 (この場合、戻さなくても支障はない)

int setcf(CHOOSEFONT *cf) { cf->lStructSize = sizeof(CHOOSEFONT); cf->hwndOwner = hParent; cf->lpLogFont = &logfont; cf->Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; cf->rgbColors = RGB(0, 0, 0); cf->nFontType = SCREEN_FONTTYPE; return 0; }

この関数では、必要なメンバを設定しています。cfはグローバル変数なので、 設定したメンバ以外は0で埋まっています。

最後に、メニューのリソースを見てみます。

VC++のリソースエジタ(APP STUDIO)でメニューを作ります。 このとき、メニューIDは必ずダブルクォーテーションで囲ってください。 例のように"MYMENU"としてください。余談ですがダイアログボックスの時も ダブルクォーテーションで囲って置いてください。その方が後で楽です。 どういう風に楽かは、後の章で解説するかもしれません。 そして、リソース・ビューで確認してください。
確かに、MYMENUがダブルクォーテーションで囲まれていますね。
メニューアイテムのIDは左の図のように「終了」は、IDM_ENDに、 「フォント」はIDM_FONTに設定してください。 こういう作業をするときは左上の「ピン」を刺しておくと楽です。 全部のIDを決めたら、名前を付けて保存してください。 この場合、font03.rcとしました。そして、このfont03.rcを 忘れずに、プロジェクトに加えてください。 (もちろんソースファイルfont03.cppも)
あとは、ビルドボタンを押せばプログラムができあがります。 なお、リソースの作り方は第14章も参照してください。
このプログラムを実行すると前章で示したようなかっこいい ダイアログボックスが出てきます。フォントについていろいろ設定して、 OKボタンを押すと左の図のように表示する文字に反映されます。


[SDK Index] [総合Index] [Previous Chapter] [Next Chapter]

Update May/22/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。