SAMPLE
ポップアップメニュー
■ リソーススクリプトで定義
Menu // ID なし
subMenu // ID あり
POINT
Window に指定できる 唯一のリソース。
WNDCLASSEX.lpszMenuName で Resource と関連づける
( WindowClass に登録した Menu を ClassMenu という )
SYNTAX
id MENU [[optional-statements]] { item-definitions... }
id : 識別子
item-definitions... : menuItem 定義
// menu の直下の POPUP menu 作成
POPUP text, [[optionlist]] { item-definitions . . . }
MENUITEM text id
optional list : menu item の外見を決定するパラメータ
メニューの内容を Resource Script にかく
メモ帳でかいて VisualStudio の Project に追加すれば
自動でコンパイルしてくれる
ID_MENU_0 MENU
{
POPUP "test"
{
MENUITEM "sub menu test", ID_MENUITEM_0 // id は WM_COMMAND に送信される
}
}
ウィンドウクラスの設定時にリソースのメニューを設定しておく。
WNDCLASSEX c;
// ResourceScript のメニューを指定する
c.lpszMenuName = MAKEINTRESOURCE( ID_MENU_0 );
c.lpszMenuName = "MyMenu";
RegisterClassEx( &cls );
WndProc でメニューが選択された場合の処理を記述する
if ( msg == WM_COMMAND ) {
// リソーススクリプトで指定した ID を選択する
if ( LOWORD(wp) == IDM_TEST ) {
MessageBox( NULL, "menu test", "menu test", MB_OK );
}
return 0;
}
-> CreateWindow( ARG9 ) は NULL で OK
■ LoadMenu
SYNTAX
HMENU LoadMenu(
HINSTANCE hInstance, // モジュールのハンドル
LPCTSTR name // メニュー名またはリソースの識別子
);
DESC
アプリケーションのインスタンスに関連付けられている実行可能ファイルから
指定されたメニューリソースをロードする
アプリケーションが終了する前に
DestroyMenu() 使ってメニューを破棄し、ロード済みのメモリが利用していたメモリを解放する
ClassMenu と違って動的に読み込むことができる
LoadMenu( hInstance, MAKEINTRESOURCE( IDC_D ) ),
BOOL DestroyMenu( HMENU ); // メモリ解放
BOOL SetMenu( HWND, HMENU );
ShortCutKey は (&C) で設定.
AcceleratorKey ( HotKey )をセットする.
AcceleratorKeyTable を ResourceScript に記述.
LoadAccelerators() で Load
MessageLoop で TranslateAccelerator() で
AcceleratorKey -> WM_COMMAND | WM_SYSCOMMAND に変換.
-> とると WM_COMMAND こない
SE > リソースファイル > RMB > 追加 > 新しい項目の追加
作成された xxx.rc file に対して,
■ menu を消去する
SYNTAX
BOOL DeleteMenu(
HMENU hMenu, // メニュー項目を持つメニューのハンドル
UINT uPosition, //
UINT uFlags // MF_BYCOMMAND | MF_BYPOSITION
);
BOOL DestroyMenu(
HMENU hMenu
);
DESC
Program からメニューオブジェクトを削除する。
メニューオブジェクトを解放する
windowにbindされないmenuは消去する必要がある。
RET
!0 : 成功
0 : 失敗
■ SetMenu
SYNTAX
SetMenu( HWND, HMENU );
DESC
メニューをきりかえる
■ 右クリックメニュー(Popup.RightClick)
SYNTAX
HMENU GetSubMenu(
HMENU hMenu, // 親メニューのハンドル
int nPos // DropDown Menu の サブ項目のインデックス
);
DESC
クライアント領域で右クリックすると, 表示されるメニュー
単一のポップアップメニュー表示される。
■ TrackPopupMenu
SYNTAX
BOOL TrackPopupMenu(
HMENU hMenu ,
UINT uFlags ,
int x, y , // Screen座標系での位置
int nReserved, // 指定は不要
HWND hWnd,
CONST RECT *prcRect // 指定は不要
);
DESC
PopUp Menu を表示
初期化でメニュー(サブメニュー)をロードして、ハンドルを保持しておく。
static HMENU hMenu, hSubMenu;
case: WM_CREATE:
{
hMenu = LoadMenu( (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE ), "ID_MENU_0" );
hSubMenu = GetSubMenu( hMenu, 0 );
break;
}
右クリックを押したら、スクリーン座標系の位置でメニューを表示。
case WM_RBUTTONDOWN:
{
// Click 位置を Screen 座標に変換
POINT pt;
pt.x = LOWORD( lp ); pt.y = HIWORD( lp );
ClientToScreen( hWnd, &pt );
TrackPopupMenu( hSubMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL );
break;
}
メニューが選択されと WM_COMMAND が届くので処理をする。
case WM_COMMAND:
{
MessageBox( hWnd, "ポップアップメニュー", "ポップアップメニュー", MB_OK );
break;
}
■ GetMenu
SYNTAX
HMENU GetMenu( HWND ); // ChildWindow は Menu をもたないので禁止.
POINT
MENU 項目を動的に変化させる
状態によって Menu 項目を禁止したい場合に使う
DESC
HMENU 取得.
WM_INITMENU ( Menu 項目が選択された瞬間に変化 )
// 確認すみ
Dialog が開いてる -> OPENMENU OFF
Dialog が閉じている -> CLOSEMENU OFF