首页 > 解决方案 > 如何识别WindowProcedure中的AppendMenu MF_POPUP Menu?

问题描述

我越来越糊涂了。

MF_POPUP
0x00000010L

指定菜单项打开一个下拉菜单或子菜单。uIDNewItem参数指定下拉菜单或子菜单的句柄。此标志用于将菜单名称添加到菜单栏,或打开下拉菜单、子菜单或快捷菜单的子菜单的菜单项。

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua

是的,但是如果参数现在是下拉菜单或子菜单的句柄,我们现在如何指定菜单uID并在 WindowProcedure 中引用它。
uIDNewItem

标签: cwinapiwin32gui

解决方案


这是一个简单的代码示例,您可以参考,

#include <Windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#define EXIT_ID 1
#define SUB_ID 2

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message)
    {
    case WM_CREATE:
    {
        HMENU hMenubar = CreateMenu();
        HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
        HMENU hDisplayMenu = CreatePopupMenu(); //display is a popup-menu because it has children.

        AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, "File");
        AppendMenu(hFileMenu, MF_STRING | MF_POPUP, (UINT_PTR)hDisplayMenu, "Display"); 
        AppendMenu(hDisplayMenu, MF_STRING, SUB_ID, "Sub");
        AppendMenu(hFileMenu, MF_STRING, EXIT_ID, "Exit"); 
        SetMenu(hwnd, hMenubar);
    }
    break;
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case SUB_ID:
            MessageBox(hwnd, "You click Sub menu", " ", MB_OK);
            break;
        case EXIT_ID:
            DestroyWindow(hwnd);
            break;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        // TODO: Add any drawing code that uses hdc here...
        EndPaint(hwnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;   
};

HINSTANCE hinst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
    HWND hwnd;

    hinst = GetModuleHandle(NULL);
    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hinst;
    wc.lpszClassName = "win32";

    // register class with operating system:
    RegisterClass(&wc);
    // create and show window:
    hwnd = CreateWindow("win32", "My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
    if (hwnd == NULL) {
        return 0;
    }
    ShowWindow(hwnd, SW_SHOW);
    MSG msg = {};

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

}

调试:

1

EXIT_ID并且SUB_ID是子菜单的 uID。您需要手动定义它们。

#define EXIT_ID 1
#define SUB_ID 2

更新:

您可以使用WM_MENUSELECT获取单击的菜单的句柄并比较它们的 hmenus。

当用户选择菜单项时发送到菜单的所有者窗口。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HMENU hMenubar;
    switch (message)
    {
    case WM_CREATE:
    {
        hMenubar = CreateMenu();
        HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..        
        
        AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
        SetMenu(hWnd, hMenubar);
    }
    break;
    case WM_MENUSELECT:
    {
        HMENU hmenu = (HMENU)lParam;     
        if (hmenu == hMenubar)
        {
            MessageBox(hWnd, L"You click main menu", L" ", MB_OK);
        }
  
    }
    break;
    ...

像这样,

在此处输入图像描述


推荐阅读