Reputation: 529
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
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:
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,
Upvotes: 1