[index] [詰め合わせ] [ダイアログボックス] [メニュー] [アクセラレータ] [String Table] [その他]
メニュー(menu)
"メイン"のメニューを選択したときに"ドロップダウン"されるメニューは "ポップアップメニュー" とか "ドロップダウンメニュー" などといいます。CreatePopupMenu() 関数なんかは文字通り、"ポップアップメニュー" を 動的 に作成してしまう関数です。
"
メニュー1" や、"例ファイル(&F)" などは項目表示ですが、それぞれの項目は "メニューアイテム" といいます。
#include <windows.h> // #include <commctrl.h> // #include "myprog.h" #define IDM_MENU1 101 #define IDM_MENU2 102 #define IDM_MENU3 103 MYMENU1 MENU DISCARDABLE BEGIN MENUITEM "例ダミー(&Dummy)" MENUITEM SEPARATOR MENUITEM "メニュー1" , IDM_MENU1 POPUP "例ファイル(&F)" BEGIN MENUITEM "メニュー2" , IDM_MENU2 ,CHECKED,GRAYED POPUP "新規作成(&New)" BEGIN MENUITEM "メニュー3" , IDM_MENU3 // IDOK IDCANCEL END END END
IDM_MENU1 IDM_MENU2 IDM_MENU3 の各定数のマクロ定義 (#define のところ) は、自分の myprog.h などの記述し、#include "myprog.h" とします。myprog.h をリソーススクリプト(.rc) と同じ場所におかない場合は、#include "directory\myprog.h" 、つまりフルパスにします。この例では、このままコンパイルができるように、自分のヘッダファイルを使わず、わざとこのようにしてあります。
MYMENU1 は自由につける名前です。 MENU DISCARDABLE は両者とも構文上のキーワードです。MENUITEM などもみんなキーワードです。
ポップアップ表示するメニュー(下記) でない、通常のメニューは、各ウィンドウに一つ、のように、1つのウィンドウに属するという考え方になります。属するウィンドウの指定は、ウィンドウクラスの登録部分( RegisterClass() 関数 )や、ダイアログボックスのリソーススクリプトにおけるメニューの指定で行われることになります。
[ アイテムのID (番号) ]
MENUITEM "例ダミー(&Dummy)" のように アイテムID を省くこともできます。一時的にデザインを確かめたり場所だけ確保しておこうというときに活用できます。アイテムの表示文字列はそれぞれ、「メニュー1」、「例ダミー(&Dummy)」 となります。ID には、あらかじめ定義されている IDOK(1) や IDCANCEL(2) などの定数 (マクロ定数) を使うこともできます。
[ セパレータ ]
[ POPUP : ドロップダウンメニュー ]
ドロップダウンされるポップアップ項目です。ポップアップ項目は BEGIN と END でくくります。BEGIN と END の組は、{ と } の組でも大丈夫です。POP'UP' なのか DROP'DOWN' なのかはっきりしてくれといいたいところですが、意味するところは同じ。
[ ショートカットキーの指定 ]
MENUITEM "例ダミー(&Dummy)" では、メニュー表示中、 'D' のキーを押すとアイテムを選択したことと同じになります。ただしこのメニューアイテムは ID を指定していないので選択してもなにも起こりません。
POPUP "例ファイル(&F)" では、同じく メニュー表示中、'F' のキーを押すとアイテムを選択したことになり、この場合はポップアップ項目が更に展開 (ドロップダウン) されることになります。
[ メニューの状態(概観) ]
メニューアイテムの状態を(デフォルトで)、グレー色(選択不可)にしたり、チェック状態にしたりできます。上の例、
この方法はあまり紹介されておらず、ほとんどの例では、プログラム内で CheckMenuItem() 関数や EnableMenuItem() によりプログラマティカリーに行っています。つまりお得な情報です。そしてまた、遥かに楽です。
更に、状態を変えるための総合的な関数である SetMenuItemInfo() 関数がありますが、とくにこの関数の feature を利用しないのであれば、ModifyMenu() 関数のほうがはるかに使いやすいです。
[最後に]
キーワードは上で示したほかに、
さらに、
MENU のかわりに MENUEX キーワードを使うと POPUP の項目にも アイテムID が付けられるようですが、個人的な経験では MENUEX キーワードを使ってメニューを作ってもうまく表示できませんでした。
[ アイテムが選択された時の処理 ]
: WM_COMMAND と メニューアイテムのID
アイテムが選択されたときの ID の役割が重要です。アイテムが選択されると、メニューのくっついている親のウィンドウに WM_COMMAND メッセージが送られます。すなわち、WndProc (ウィンドウプロシージャ) で受け取ります。ウィンドウプロシージャを眺めたことがあると少しはわかりいいですが、ウィンドウプロシージャの第3引数 wParam の下位16ビット にこの ID が格納されています。WM_COMMAND の処理の仕方は定番なので心配は無用です。コントロールアイテムの場合と全くおんなじです。( 〜 case WM_COMMAND : switch( LOWORD(wParam)) { case IDM_MENU1 : ... break ; 〜 )
[ ポップアップするメニュー ]
このように記述したメニューの利用法は、スケルトンコード のウィンドウクラスの登録のところで、wc.lpszMenuName = "MYMENU1" ; のような指定に用いるか、 [ダイアログボックス] のスクリプトでのメニューの指定で使うのが主です。(ダイアログボックス本体にもメニューを持たすことができる)
今言ったのは、トップレベルのウィンドウに属するメイン(の)メニューの話で、ウィンドウ上で右クリックしたら現れるというような、ポップアップするメニューの場合は、マウスが押されたときの処理からメニューの表示、そしてメニューの破棄まで、一連の処理を記述しなくてはなりません。
ただこの場合も、このリソーススクリプトの記述を利用します(できます)。
さて、これに関してはヒントとして関数を処理の順番とともに挙げて終わりにすることもできますが、折角なのでサンプルコードとともに簡単に説明しましょう (わたくしにとっては案外楽なのです)。アイテムが選択された時 の WM_COMMAND の処理のことも含まれますので、そのためのに参考してもいいでしょう。
[ポップアップするメニューの作り方]
[トップ] [level4:言葉] [index]