为什么 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);