I created a popup menu using c++ win32. The source code is:
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
Now I want to change the title "Turn LockScreen Off" into "Turn LockScreen On" when I clicked it.
The code in .cpp is:
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;
}
But I could not get the hMenu with this method.
The pointer of hMenu is empty. I put a break point there and get (*hMenu).unused:CXX0030:Error: expression cannot be evaluated!
Could somebody explain to me how to do with this error?
The reason your code fails is because you are replacing hMenu
with GetSubMenu
. Your menu should have been loaded at the beginning within the WM_CREATE
case. The menu you are modifying is the recently loaded menu and it is NOT added to the current window so you aren't seeing any changes.. For ModifyMenu, you NEED to specify the MF_STRING flag to change the title!
If the menu is dynamic and created upon Right-Click, then you don't need to use SetMenu
to set the menu and it can be loaded on the fly and changed.. but remember, you do not need GetSubMenu
for this because you are using defined ID's for each menu. If the menu is to be retrieved by indexed position starting at 0, GetSubMenu
would help.
Also, in the below code, I chose to save the menu handle into a variable. You do not need this static variable. You can also use GetMenu
within the case statement that needs a MenuHandle.
Resources.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
Resources.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
main.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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With