メニューアイテムの設定
メニューの各項目は様々な設定が可能です。
例えば項目に表示される文字列や画像、チェックマークのオン/オフや無効状態といったものです。
SetMenuItemInfo関数
メニュー項目を設定するにはSetMenuItemInfo関数を使用します。
- BOOL SetMenuItemInfoW(
HMENU hmenu,
UINT item,
BOOL fByPositon,
LPCMENUITEMINFOW lpmii
); - メニューハンドルhmenuのメニュー項目itemの情報をlpmiiに設定する。
成功した場合は0以外を、失敗した場合は0を返す。
hmenuはメニューハンドルです。
itemはメニュー項目を指定するための値ですが、これは次の引数fByPositonの値によって意味が変わります。
fByPositonがFALSE(0)の場合、itemはメニュー項目の識別子を意味します。
TRUE(0以外)の場合は先頭からのインデックス(番号)を意味します。
lpmiiはMENUITEMINFO構造体へのポインタです。
GetMenuItemInfo関数
メニュー項目の設定を取得するにはGetMenuItemInfo関数を使用します。
- BOOL GetMenuItemInfoW(
HMENU hmenu,
UINT item,
BOOL fByPosition,
LPMENUITEMINFOW lpmii
); - メニューハンドルhmenuのメニュー項目itemの情報をlpmiiに格納する。
成功した場合は0以外を、失敗した場合は0を返す。
引数の意味はSetMenuItemInfo関数と同じです。
MENUITEMINFO構造体
MENUITEMINFO構造体はメニュー項目の情報を格納する構造体です。
- typedef struct tagMENUITEMINFOW {
UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
ULONG_PTR dwItemData;
LPWSTR dwTypeData;
UINT cch;
HBITMAP hbmpItem;
} MENUITEMINFOW, *LPMENUITEMINFOW; - メニュー項目の情報を格納する構造体。
cbSizeメンバはこの構造体のサイズです。
つまりsizeof(MENUITEMINFO)を指定します。
fMaskメンバは取得または設定するメンバを指定します。
MENUITEMINFO構造体は多くの状態を一度に取得/設定可能ですが、毎回全ての設定を読み書きする必要はなく、この設定で必要な情報だけを取得/設定できます。
(ここで設定しなかったメンバは無視される)
以下の定数のいずれか、あるいは組み合わせを指定します。
| 定数 | 説明 |
|---|---|
| MIIM_FTYPE | fTypeメンバの取得/設定 |
| MIIM_STATE | fStateメンバの取得/設定 |
| MIIM_ID | wIDメンバの取得/設定 |
| MIIM_SUBMENU | hSubMenuメンバの取得/設定 |
| MIIM_CHECKMARKS | hbmpChecked、hbmpUncheckedメンバの取得/設定 |
| MIIM_DATA | dwItemDataメンバの取得/設定 |
| MIIM_STRING | dwTypeDataメンバの取得/設定 |
| MIIM_BITMAP | hbmpItemメンバの取得/設定 |
| MIIM_TYPE | fType、dwTypeDataメンバの取得/設定MIIM_FTYPEと紛らわしいので非推奨( MIIM_FTYPE | MIIM_STRINGを使用する) |
fTypeメンバはメニュー項目の種類を表します。
これは以下の定数のいずれか、または組み合わせを指定します。
ただしMFT_BITMAP、MFT_SEPARATOR、MFT_STRINGは互いに組み合わせることはできません。
| 定数 | 説明 |
|---|---|
| MFT_STRING | 文字列を項目に表示する。 (既定) dwTypeDataメンバはNULL終端文字列へのポインタ、cchメンバはその文字列の長さを表す。 |
| MFT_BITMAP |
ビットマップを項目に表示する。
ビットマップを表示する場合はこのフラグよりもfMaskメンバの |
| MFT_MENUBARBREAK | メニュー項目を新しい行に配置する。 ドロップダウンメニュー、サブメニュー、ショートカットメニューの場合は新しい列に配置し、縦線で区切る。 |
| MFT_MENUBREAK | メニュー項目を新しい行に配置する。 ドロップダウンメニュー、サブメニュー、ショートカットメニューの場合は新しい列に配置し、縦線で区切らない。 |
| MFT_OWNERDRAW | オーナードローメニュー項目。 |
| MFT_RADIOCHECK | チェックマークの代わりにラジオボタンマークを表示する。 ( hbmpCheckedメンバがNULLの場合) |
| MFT_SEPARATOR | セパレーター項目。 ドロップダウンメニュー、サブメニュー、ショートカットメニューで有効。 dwTypeData、cchメンバは無視される。 |
| MFT_RIGHTORDER | メニューは右から左へ読み書きされる。 (アラビア語などの右から左に読み書きする言語用) |
| MFT_RIGHTJUSTIFY | メニュー項目の右揃え。 メニューバー内の項目にのみ有効。 |
fStateメンバはメニュー項目の状態を表します。
これは以下の定数のいずれか、または組み合わせを指定します。
| 定数 | 説明 |
|---|---|
| MFS_ENABLED MFS_UNCHECKED MFS_UNHILITE |
項目は有効、 チェックされていない、 強調表示(ハイライト)されていない (初期状態) |
| MFS_DISABLED MFS_GRAYED |
項目は無効、 グレーアウトされた状態 |
| MFS_CHECKED | チェックマークが付けられている |
| MFS_HILITE | 強調表示(ハイライト)されている |
| MFS_DEFAULT | デフォルトとして設定されている デフォルトの項目はメニュー内で一つだけ含めることができ、太字で表示される |
wIDメンバはメニュー項目を識別するIDです。
hSubMenuメンバは項目に関連付けられているドロップダウンメニューまたはサブメニューのハンドルです。
これらがない場合はNULLです。
hbmpCheckedメンバは項目が選択状態の時に項目の横に表示されるビットマップのハンドルです。
このメンバがNULLの場合、デフォルトのチェックマークが使用されます。
hbmpUncheckedメンバは項目が非選択状態の時に項目の横に表示されるビットマップのハンドルです。
このメンバがNULLの場合は何も表示されません。
dwItemDataメンバは項目に関連付けられている任意の値です。
この値はプログラマが自由に使用できます。
dwTypeDataメンバは項目の内容です。
fTypeメンバの指定によって文字列のポインタであったりビットマップハンドルだったりします。
ただし上述している通り、ビットマップハンドルはこのメンバではなくMIIM_BITMAPフラグとhbmpItemメンバを使用するのがおすすめです。
cchメンバは、項目の内容が文字列である場合(MFT_STRING)の、文字列のサイズです。
hbmpItemメンバは項目に表示するビットマップのハンドルです。
GetMenu関数
メニュー項目の情報を取得/設定するにはメニューハンドルが必要です。
LoadMenu関数を使用している場合はそれをそのまま使用すれば良いですが、ウィンドウクラスに関連付けて作成されたメニューはGetMenu関数でハンドルを取得できます。
- HMENU GetMenu(
HWND hWnd
); - ウィンドウhWndに割り当てられているメニューのハンドルを返す。
メニューが存在しない場合はNULLを返す。
hWndが子ウィンドウの場合、戻り値は未定義なので使用してはならない。
サンプルコード
メニュー項目の状態を変更するサンプルです。
ビットマップを表示するためにリソースにビットマップを使用しています。
このコードをビルドするには適当なビットマップ画像を用意してください。
(16×16ピクセル推奨。自動で拡大縮小されたりはしない)
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU
BEGIN
POPUP "編集"
BEGIN
MENUITEM "チェック", ID_40001
MENUITEM "無効", ID_40002
MENUITEM "↑の無効を解除", ID_40003
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_BITMAP1 BITMAP "sample.bmp"
#include <windows.h>
#include "resource.h"
//ウィンドウの生成等は省略
//ウィンドウクラスの登録
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); //メニューの登録
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBmp;
static HMENU hMenu;
MENUITEMINFO mii;
switch (message)
{
case WM_CREATE:
//ビットマップリソースの読み込み
hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
//メニューハンドルの取得
hMenu = GetMenu(hWnd);
//項目にビットマップを表示
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = hBmp;
SetMenuItemInfo(hMenu, ID_40003, 0, &mii);
break;
case WM_COMMAND: //コントロールの操作
switch (LOWORD(wParam))
{
case ID_40001: //チェックのオン/オフ
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
GetMenuItemInfo(hMenu, ID_40001, 0, &mii);
mii.fState =
mii.fState == MFS_CHECKED ? MFS_UNCHECKED : MFS_CHECKED;
SetMenuItemInfo(hMenu, ID_40001, 0, &mii);
break;
case ID_40002: //項目を無効化する
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
mii.fState = MFS_DISABLED;
SetMenuItemInfo(hMenu, ID_40002, 0, &mii);
break;
case ID_40003: //↑の無効化を解除
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
mii.fState = MFS_ENABLED;
SetMenuItemInfo(hMenu, ID_40002, 0, &mii);
break;
}
break;
case WM_DESTROY: //ウィンドウの破棄
DeleteObject(hBmp);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
「チェック」項目はクリックするごとにチェック状態が切り替わります。
「無効」項目はクリックするとその項目が無効になり、以降はクリックできなくなります。
「↑の無効を解除」項目は無効化された上の「無効」項目を有効化します。
この項目にはビットマップを表示しています。