Jump to content
  • Advertisement
Sign in to follow this  
SonicD007

Bug in popup menu (checkmarks) C++ win api

This topic is 3029 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to learn the windows api and so far things have been going pretty well. I've been figuring things out and learning more when I have time. Recently I was trying to use a windows menu to control the score limit of a Pong Clone I'm going to attempt making using c++ and the windows api. Here's what I have for the menu part:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int iSelection = ID_GAMEPOINT_10;
	HMENU hMenu;
    switch(msg)
    {
		case WM_COMMAND:
			hMenu = GetMenu(hwnd);
			switch(LOWORD(wParam))
			{
				case ID_FILE_NEWGAME:
					NewGame();
					break;

				case ID_FILE_PAUSE:
					(g_bPause==true) ? (g_bPause=false) : (g_bPause=true);  //Pause game if unpaused, unpause if paused
					break;

				case ID_FILE_EXIT:
					PostMessage(hwnd, WM_CLOSE, 0, 0);
					break;

				case ID_GAMEPOINT_5:
					{
						CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
						iSelection = LOWORD (wParam);
						CheckMenuItem(hMenu, iSelection, MF_CHECKED);
						if (GetMenuState(hMenu, iSelection, MF_BYCOMMAND) == MF_CHECKED)
							g_iScoreLimit = 5;
					}
					break;

				case ID_GAMEPOINT_10:
					{
						CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
						iSelection = LOWORD (wParam);
						CheckMenuItem(hMenu, iSelection, MF_CHECKED);
						if (GetMenuState(hMenu, iSelection, MF_BYCOMMAND) == MF_CHECKED)
							g_iScoreLimit = 10;
					}
					break;

				case ID_GAMEPOINT_15:
					{
						CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
						iSelection = LOWORD (wParam);
						CheckMenuItem(hMenu, iSelection, MF_CHECKED);
						if (GetMenuState(hMenu, iSelection, MF_BYCOMMAND) == MF_CHECKED)
							g_iScoreLimit = 15;
					}
					break;

				case ID_GAMEPOINT_20:
					{
						CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
						iSelection = LOWORD (wParam);
						CheckMenuItem(hMenu, iSelection, MF_CHECKED);
						if (GetMenuState(hMenu, iSelection, MF_BYCOMMAND) == MF_CHECKED)
							g_iScoreLimit = 20;
					}
					break;

				case ID_HELP_HOWTOPLAY:
					DialogBox(GetModuleHandle(NULL), 
							MAKEINTRESOURCE(IDD_HOWTOPLAY), hwnd, AboutDlgProc);
				break;

				case ID_HELP_ABOUT:
					MessageBox(hwnd,"Pong Game created by ", "About", MB_OK);
				break;
			}
		 break;
		case WM_KEYDOWN:
			switch(wParam)
				{
				case W:
					g_bMoveUp[0] = true;
					break;//this is where the boolean var would go to move up

				case S:
					g_bMoveDown[0] = true;
					break;//this is where the boolean var would go to move down

				case VK_UP:
					g_bMoveUp[1] = true;
					break;//this is where the boolean var would go to move up

				case VK_DOWN:
					g_bMoveDown[1] = true;
					break;//this is where the boolean var would go to move down

				case VK_SPACE:
					g_bBallMove = true;
					break;

				case P:
					(g_bPause==true) ? (g_bPause=false) : (g_bPause=true);
					break;
				}
			break;

		case WM_KEYUP:
			switch(wParam)
				{
				case W:
					g_bMoveUp[0] = false;
					break;//this is where the boolean var would go to move up

				case S:
					g_bMoveDown[0] = false;
					break;//this is where the boolean var would go to move down

				case VK_UP:
					g_bMoveUp[1] = false;
					break;//this is where the boolean var would go to move up

				case VK_DOWN:
					g_bMoveDown[1] = false;
					break;//this is where the boolean var would go to move down
			}
			break;

        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;

        case WM_DESTROY:
            PostQuitMessage(0);
        break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}	//end of wind proc

My code compiles and all, but when I click another menu item like Game->ScoreLimit->15, instead of check marking the menu item with 15 and unchecking the previous checked menu, it will check more than one menu and at times it doesn't do anything. I'm not sure where the bug is and I'm not very keen on using a debugger. Any help would be appreciated. Thanks. If you need any more code I'll post the rest.

Share this post


Link to post
Share on other sites
Advertisement
In CheckMenuItem I believe you must use MF_BYCOMMAND | MF_CHECKED for example, to tell the API you specify menu item by command ID.
Checked the docs and MF_BYCOMMAND is default, so scratch that.

Share this post


Link to post
Share on other sites
Also, I was trying to find out why it wasn't working in the code above and created another project just to test out the menus, and for some reason it works in this code but not in the above.

#include <windows.h>
#include "resource.h"

const char g_szClassName[] = "myWindowClass";

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu;
static int iSelection = ID_SCORELIMIT_10;
switch(msg)
{
case WM_COMMAND:
hMenu = GetMenu(hwnd);
switch (LOWORD(wParam))
{
case ID_SCORELIMIT_5:
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD (wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
if (GetMenuState(hMenu, iSelection, MF_BYCOMMAND) == MF_CHECKED)
MessageBox(hwnd, "test", "Works", MB_OK);
break;
case ID_SCORELIMIT_10:
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD (wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
break;
case ID_SCORELIMIT_15:
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD (wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
break;
case ID_SCORELIMIT_20:
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD (wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}



Any ideas why it works here and not up there?

Share this post


Link to post
Share on other sites
In the project in which it's not working, if you put break points in all the menu command handlers, is the correct handler getting called for a given menu selection?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!