如何识别WindowProcedure中的AppendMenu MF_POPUP Menu?
How to identify AppendMenu MF_POPUP Menu in the WindowProcedure?
我有点糊涂了。
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://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)
是的,但是我们现在如何指定Menu的uID并在WindowProcedure中引用它,
如果 uIDNewItem
参数现在是 下拉菜单或子菜单的句柄 。
这是一个简单的代码示例,您可以参考,
#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);
}
}
调试:
EXIT_ID
和SUB_ID
是子菜单的uID。您需要手动定义它们。
#define EXIT_ID 1
#define SUB_ID 2
更新:
您可以使用 WM_MENUSELECT 获取被单击菜单的句柄并比较它们的 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;
...
像这样,
我有点糊涂了。
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://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)
是的,但是我们现在如何指定Menu的uID并在WindowProcedure中引用它,
如果 uIDNewItem
参数现在是 下拉菜单或子菜单的句柄 。
这是一个简单的代码示例,您可以参考,
#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);
}
}
调试:
EXIT_ID
和SUB_ID
是子菜单的uID。您需要手动定义它们。
#define EXIT_ID 1
#define SUB_ID 2
更新:
您可以使用 WM_MENUSELECT 获取被单击菜单的句柄并比较它们的 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;
...
像这样,