user3789797
user3789797

Reputation: 529

How to identify AppendMenu MF_POPUP Menu in the WindowProcedure?

I'm getting confused.

MF_POPUP
0x00000010L

Specifies that the menu item opens a drop-down menu or submenu. The uIDNewItem parameter specifies a handle to the drop-down menu or submenu. This flag is used to add a menu name to a menu bar, or a menu item that opens a submenu to a drop-down menu, submenu, or shortcut menu.

(https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)

Yes, but how do we now specify the uID of the Menu and refer to it in the WindowProcedure,
if the uIDNewItem parameter is now a handle to the drop-down menu or submenu.

Upvotes: 0

Views: 902

Answers (1)

Strive Sun
Strive Sun

Reputation: 6289

This is a simple code sample you can refer,

#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);
    }

}

Debug:

1

EXIT_ID and SUB_ID are the uID of the submenu. You need to define them manually.

#define EXIT_ID 1
#define SUB_ID 2

Updated:

You can use WM_MENUSELECT to get the handle to the menu that is clicked and compare their hmenus.

Sent to a menu's owner window when the user selects a menu item.

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;
    ...

Like this,

enter image description here

Upvotes: 1

Related Questions