为什么 EnableMenuItem 没有像我预期的那样工作?
Why is EnableMenuItem not working as I expect it to?
我正在尝试创建一个带有简单 File -> Open, Close, Exit
菜单的 window。但是,在用户使用 Open
菜单操作打开文件之前,Close
将被禁用。该菜单作为名为 IDR_MENU1
.
的资源存在
这是我的 wWinMain
函数:
INT APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ INT nShowCmd)
{
HWND hWnd;
MSG Msg;
NONCLIENTMETRICSW ncm;
HFONT hfDefault;
HMENU hMenu;
ZeroMemory(&ncm, sizeof(NONCLIENTMETRICSW));
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, FALSE);
hfDefault = CreateFontIndirectW(&ncm.lfMessageFont);
if (RegisterWCEX(hInstance) == (ATOM)0)
{
MessageBoxW(NULL, L"Window registration failed", L"Error", MB_OK | MB_ICONSTOP);
return -1;
}
hWnd = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, g_wszClassName, L"PTW", WS_SYSMENU | WS_VISIBLE, 100, 100, 600, 450, NULL, NULL, hInstance, NULL);
if (NULL == hWnd)
{
MessageBoxW(NULL, L"Window creation failed", L"Error", MB_OK | MB_ICONSTOP);
return -1;
}
ShowWindow(hWnd, SW_SHOW);
EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&hfDefault);
UpdateWindow(hWnd);
hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
hMenu = GetSubMenu(hMenu, 0);
if (NULL == hMenu)
{
return -1;
}
if (-1 == EnableMenuItem(hMenu, 1, MF_DISABLED | MF_GRAYED | MF_BYPOSITION))
{
return -1;
}
DrawMenuBar(hWnd);
while (GetMessageW(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
return 0;
}
这是我的 WM_CREATE
消息处理程序:
BOOL WINAPI OnCreate(HWND hWnd, LPCREATESTRUCTW lpCreateStruct)
{
HINSTANCE hInstance = lpCreateStruct->hInstance;
INITCOMMONCONTROLSEX iccx;
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_DATE_CLASSES;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
if (!InitCommonControlsEx(&iccx))
{
return FALSE;
}
return TRUE;
}
当我运行这个时,Close
选项仍然启用:
我是不是在调用 LoadMenu
and/or GetSubMenu
时遇到了问题,还是我调用 EnableMenuItem
的方式有问题?
您正在加载菜单资源的第二个实例,与已经分配给您的 window 的任何菜单分开。您正在禁用第二个菜单上的菜单项,并且在任何时候都不会显示将修改后的菜单分配给您的 window.
的代码
摆脱对 LoadMenuW()
的调用,使用 GetMenu()
来获取实际分配给 window 的 HMENU
。
//hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
hMenu = GetMenu(hWnd);
我正在尝试创建一个带有简单 File -> Open, Close, Exit
菜单的 window。但是,在用户使用 Open
菜单操作打开文件之前,Close
将被禁用。该菜单作为名为 IDR_MENU1
.
这是我的 wWinMain
函数:
INT APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ INT nShowCmd)
{
HWND hWnd;
MSG Msg;
NONCLIENTMETRICSW ncm;
HFONT hfDefault;
HMENU hMenu;
ZeroMemory(&ncm, sizeof(NONCLIENTMETRICSW));
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, FALSE);
hfDefault = CreateFontIndirectW(&ncm.lfMessageFont);
if (RegisterWCEX(hInstance) == (ATOM)0)
{
MessageBoxW(NULL, L"Window registration failed", L"Error", MB_OK | MB_ICONSTOP);
return -1;
}
hWnd = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, g_wszClassName, L"PTW", WS_SYSMENU | WS_VISIBLE, 100, 100, 600, 450, NULL, NULL, hInstance, NULL);
if (NULL == hWnd)
{
MessageBoxW(NULL, L"Window creation failed", L"Error", MB_OK | MB_ICONSTOP);
return -1;
}
ShowWindow(hWnd, SW_SHOW);
EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&hfDefault);
UpdateWindow(hWnd);
hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
hMenu = GetSubMenu(hMenu, 0);
if (NULL == hMenu)
{
return -1;
}
if (-1 == EnableMenuItem(hMenu, 1, MF_DISABLED | MF_GRAYED | MF_BYPOSITION))
{
return -1;
}
DrawMenuBar(hWnd);
while (GetMessageW(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
return 0;
}
这是我的 WM_CREATE
消息处理程序:
BOOL WINAPI OnCreate(HWND hWnd, LPCREATESTRUCTW lpCreateStruct)
{
HINSTANCE hInstance = lpCreateStruct->hInstance;
INITCOMMONCONTROLSEX iccx;
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_DATE_CLASSES;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
if (!InitCommonControlsEx(&iccx))
{
return FALSE;
}
return TRUE;
}
当我运行这个时,Close
选项仍然启用:
我是不是在调用 LoadMenu
and/or GetSubMenu
时遇到了问题,还是我调用 EnableMenuItem
的方式有问题?
您正在加载菜单资源的第二个实例,与已经分配给您的 window 的任何菜单分开。您正在禁用第二个菜单上的菜单项,并且在任何时候都不会显示将修改后的菜单分配给您的 window.
的代码摆脱对 LoadMenuW()
的调用,使用 GetMenu()
来获取实际分配给 window 的 HMENU
。
//hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
hMenu = GetMenu(hWnd);