第6章 簡単なメニュー


今までのプログラムでは何か物足りない感じがしますね。 1つにはメニューバーがないからです。 Windowsのプログラミングでは、メニュー、ダイアログボックス、 カーソル、アイコンなどはリソースと呼ばれています。

メニューやら、ダイアログボックスを作るにはメインになる プログラムの他に、リソース・スクリプトといわれるものを書かなくてはいけません。 今回は、簡単なメニューの作り方を解説します。

1.リソース・スクリプトを書く 2.ヘッダー・ファイルを書く 3.ソース・ファイルの修正

と、いうことになります。まずリソース・スクリプトの書き方ですが たいていのコンパイラではメニュー・エディタとかそれに類したものが ついているはずです。これを使ってスクリプトを作ってもよいでしょう。 VC++の場合、少し問題もあります。ある程度エディタに作らせておいて あとで手動で修正してもかまいません。 リソース・スクリプトの拡張子はrcです。

// sample02.rc #include <windows.h> #include "sample02.h" //IDM_ENDの値を定義する // メニュー SAMPLE02 MENU PRELOAD FIXED BEGIN MENUITEM "終了" IDM_END END

スクリプトの書き方はこんな感じです。 ヘッダーファイルは次のように書きます

// sample02.h #define IDM_END 100

ここで、IDM_ENDというのは、筆者が勝手に付けた名前です。 シンボルコードといいます。メニュー関係は「IDM_何とか」 というように名前を付けるとわかりやすいですね。 リソーススクリプトは

メニューの名前 MENU メモリオプション BEGIN MENUITEM "実際に表示されるメニュー項目" シンポルコード END

というようになります。メモリオプションは

PRELOAD プログラム起動時にメモリにロードされる DISCARDABLE 不要になったらメモリから廃棄される FIXED メモリ上で固定 MOVEABLE メモリ上で移動可能

この位知っていれば十分でしょう。

さて、VC++4.2ではこのリソーススクリプトを プロジェクトに挿入する必要があります。 「挿入」「プロジェクトへファイルを追加」を選択して sample02.rcを追加して下さい。

さて、次はソース・ファイルの修正です。 ウィンドウクラスの定義のところで

myProg.lpszMenuName = "SAMPLE02";

のようにメニュー名を指定して下さい。 これだけで、ビルドするとメニュー付きの ウィンドウができるはずです。ただし、メニューは 機能しません。(当たり前ですが・・)

次に、プロシージャを修正します。 メニュー項目がクリックされるとWindowsは WM_COMMAND メッセージを発生します。これを プロシージャのところで捕まえてやればよいですね。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; } break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: ShowMyText(hWnd); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }

WM_COMMANDメッセージを捕まえたらwParamの下位ワードを調べます。 ここに、IDM_何とかがあります。この場合捕まえるシンボルは 「IDM_END」なのでこれを捕まえます。捕まえたら SendMessage関数でWM_CLOSEメッセージを送り出します。 このメッセージがDefWindowProc関数にわたるとDestroyWindow関数 が呼び出されウィンドウが破棄されます。 このへんの所は、あとでもう少し詳しく解説する予定です。 今のところは、終了するときのパターンであると覚えておきましょう。 さて、このソースファイルにもIDM_ENDが登場するので

#include "sample02.h"

が必要です。

// sample02.cpp #include <windows.h> #include <string.h> #include "sample02.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void ShowMyText(HWND); char szClassNme[] = "ウィンドウクラス・ネーム"; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hWnd; MSG msg; WNDCLASS myProg; if (!hPreInst) { myProg.style =CS_HREDRAW | CS_VREDRAW; myProg.lpfnWndProc =WndProc; myProg.cbClsExtra =0; myProg.cbWndExtra =0; myProg.hInstance =hInstance; myProg.hIcon =NULL; myProg.hCursor =LoadCursor(NULL, IDC_ARROW); myProg.hbrBackground =GetStockObject(WHITE_BRUSH); myProg.lpszMenuName ="SAMPLE02"; myProg.lpszClassName =szClassNme; if (!RegisterClass(&myProg)) return FALSE; } hWnd = CreateWindow(szClassNme, "猫でもわかるプログラミング", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (msg.wParam); } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; } break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: ShowMyText(hWnd); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); } void ShowMyText(HWND hWnd) { HDC hdc; char *str_org = "left=%d top=%d right=%d bottom=%d"; char strx[256]; PAINTSTRUCT paint; RECT rt; LPCSTR str = "猫でもわかるプログラミング\n粂井康孝 制作\n" "わかりやすくてためになる!"; GetClientRect(hWnd, &rt); wsprintf((LPSTR)strx, (LPCSTR)str_org, rt.left, rt.top, rt.right, rt.bottom); rt.top += 40; rt.bottom -= 40; rt.right -= 40; rt.left += 40; hdc = BeginPaint(hWnd, &paint); SetTextColor(hdc, RGB(255, 0, 0)); TextOut(hdc, 10, 10, (LPSTR)strx, strlen(strx)); SetTextColor(hdc, RGB(0, 0, 255)); DrawText(hdc, str, -1, &rt, DT_WORDBREAK); ValidateRect(hWnd, NULL); EndPaint(hWnd, &paint); return; }

では、プログラムを実行してみましょう。

はい。メニューがつきましたね。「終了」をクリックすると ちゃんと?終了します。


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

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