我使用 c++ win32 创建了一个弹出菜单。 源代码是:
IDR_POPUP_MENU MENU DISCARDABLE
BEGIN
POPUP "POPUP"
BEGIN
MENUITEM "Turn On" IDM_STATUS
POPUP "Preferences"
BEGIN
MENUITEM "Turn Autostart Off" IDM_AUTOSTART
MENUITEM "Turn Lock Screen Off" IDM_LOCKSCREEN
END
MENUITEM "Exit", IDM_EXIT
END
END
现在我想在单击时将标题“关闭锁屏”更改为“打开锁屏”。
.cpp 中的代码是:
case IDM_LOCKSCREEN:
{
if(lockscreen)
{
lockscreen = FALSE;
HMENU hMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUP_MENU));
hMenu = GetSubMenu(hMenu, IDM_LOCKSCREEN);
ModifyMenu(hMenu, IDM_LOCKSCREEN, MF_BYCOMMAND | MF_CHECKED, IDM_LOCKSCREEN, "Turn LockScreen Off");
}
break;
}
但是我无法用这种方法获取hMenu。
hMenu 的指针为空。我在那里放了一个断点并得到 (*hMenu).unused:CXX0030:Error: expression cannot be evaluated!
有人可以向我解释如何处理这个错误吗?
最佳答案
您的代码失败的原因是您将 hMenu
替换为 GetSubMenu
。您的菜单应该在 WM_CREATE
案例的开头加载。您正在修改的菜单是最近加载的菜单,它没有添加到当前窗口,因此您看不到任何更改。对于 ModifyMenu,您需要指定 MF_STRING 标志来更改标题!
如果菜单是动态的并且是在右键单击时创建的,那么您不需要使用 SetMenu
来设置菜单并且它可以即时加载和更改..但是请记住,您不需要为此使用 GetSubMenu
,因为您正在为每个菜单使用定义的 ID。如果要通过从 0 开始的索引位置检索菜单,GetSubMenu
会有所帮助。
此外,在下面的代码中,我选择将菜单句柄保存到一个变量中。您不需要此静态变量。您还可以在需要 MenuHandle 的 case 语句中使用 GetMenu
。
资源.h:
#ifndef RESOURCES_HPP_INCLUDED
#define RESOURCES_H_INCLUDED
#define IDR_POPUP_MENU 1001
#define IDM_STATUS 1002
#define IDM_AUTOSTART 1003
#define IDM_LOCKSCREEN 1004
#define IDM_EXIT 1005
#endif // RESOURCES_H_INCLUDED
资源.rc:
#include "Resources.h"
IDR_POPUP_MENU MENU DISCARDABLE
BEGIN
POPUP "POPUP"
BEGIN
MENUITEM "Turn On", IDM_STATUS
POPUP "Preferences"
BEGIN
MENUITEM "Turn Autostart Off", IDM_AUTOSTART
MENUITEM "Turn Lock Screen Off", IDM_LOCKSCREEN
END
MENUITEM "Exit", IDM_EXIT
END
END
主要.cpp:
#include <windows.h>
#include "Resources.h"
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenu = NULL;
switch(message)
{
case WM_CREATE:
{
hMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUP_MENU));
SetMenu(hwnd, hMenu);
}
break;
case WM_COMMAND:
{
switch(wParam)
{
case IDM_LOCKSCREEN:
{
static bool locked = true;
if (locked)
{
//You can use HMENU = GetMenu(hwnd); if you want.. instead of a static variable..
ModifyMenu(hMenu, IDM_LOCKSCREEN, MF_BYCOMMAND | MF_STRING, IDM_LOCKSCREEN, "Turn LockScreen On");
}
else
{
ModifyMenu(hMenu, IDM_LOCKSCREEN, MF_BYCOMMAND | MF_STRING | MF_CHECKED, IDM_LOCKSCREEN, "Turn LockScreen Off");
}
locked = !locked;
}
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = "CodeBlocksWindowsApp";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wincl))
return 0;
hwnd = CreateWindowEx (0, "CodeBlocksWindowsApp", "Code::Blocks Template Windows App", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow (hwnd, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
关于c++ - C++ Win32程序中,如何修改菜单的标题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28120101/