【问题标题】:Why is EnableMenuItem not working as I expect it to?为什么 EnableMenuItem 没有像我预期的那样工作?
【发布时间】:2021-09-07 10:47:03
【问题描述】:

我正在尝试使用简单的File -> Open, Close, Exit 菜单创建一个窗口。但是,在用户使用Open 菜单操作打开文件之前,Close 将被禁用。该菜单作为名为@9​​87654327@ 的资源存在。

这是我的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 和/或GetSubMenu 的方式有什么问题,还是我调用EnableMenuItem 的方式有问题?

【问题讨论】:

  • IDK 如果相关但来自EnableMenuItem MF_GRAYED 在其描述中包含MF_DISABLED 操作,并且它说“返回值指定菜单项的先前状态(它是@987654339 @、MF_ENABLEDMF_GRAYED)。”这意味着应该只设置这三个值中的一个(可能与其他标志进行 ORred),但您使用了两个,MF_DISABLED | MF_GRAYED

标签: c winapi menu


【解决方案1】:

您正在加载菜单资源的第二个实例,与已分配给您的窗口的任何菜单分开。您正在禁用此第二个菜单上的菜单项,并且在任何时候都没有显示将修改后的菜单分配给您的窗口的代码。

摆脱对LoadMenuW()的调用,改用GetMenu()来获取实际分配给窗口的HMENU

//hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
hMenu = GetMenu(hWnd);

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    相关资源
    最近更新 更多