Click to See Complete Forum and Search --> : rightclick menu not popup again?


GumGumKam
April 27th, 2005, 01:14 PM
I am very new to C++ and win32. What I do is just a dialog window with rightclick menu. I defined all icons, dialog and menu in resources.
It work fine for about 10 click. Suddenly it didn't function anymore!
Could anyone tell me what's wrong there!? Please!

In my WinMain:

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
DialogBox(hThisInstance, MAKEINTRESOURCE(IDD_EMPTY), NULL, DlgProc);
return 0;
}

And DlgProc:

BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
HMENU hMenu = LoadMenu (GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_GMENU) );
HMENU hPopupMenu = GetSubMenu (hMenu, 0);
POINT pt;

switch(Message)
{
case WM_INITDIALOG:
{
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_GSICON) ) );
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_GICON)));
}
break;
case WM_RBUTTONDOWN:
{
GetCursorPos (&pt);
TrackPopupMenu (hPopupMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, NULL);
}
break;
case WM_CLOSE:
EndDialog(hwnd, 0);
break;
default:
return FALSE;
}
return TRUE;
}

Bond
April 27th, 2005, 01:20 PM
Try rewriting your DlgProc like so:

BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenu;
static HMENU hPopupMenu;

switch(Message)
{
case WM_INITDIALOG:
{
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_GSICON) ) );
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_GICON)));
hMenu = LoadMenu (GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_GMENU) );
hPopupMenu = GetSubMenu (hMenu, 0);
}
break;
case WM_RBUTTONDOWN:
{
POINT pt;
GetCursorPos (&pt);
TrackPopupMenu (hPopupMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, NULL);
}
break;
case WM_CLOSE:
EndDialog(hwnd, 0);
break;
default:
return FALSE;
}
return TRUE;
}

The way you did it originally, your menu is constantly being loaded from your application's resources everytime your DlgProc receives a message (which is VERY often). It only needs to be loaded once, say in WM_INITDIALOG as I have done above. The static variables maintain the values (handles) of your menus so that when WM_RBUTTONDOWN comes along and TrackPopupMenu() is called, your variables have the proper handle values.

You could also move the code to load your menu directly into WM_RBUTTONDOWN, if you wish. Then, you wouldn't need to use static variables. To each his own.

GumGumKam
April 27th, 2005, 05:31 PM
Ok, I move the HMENU lines inside WM_RBUTTONDOWN and it works! Thanks.

I wonder why my code didn't work? Because of too often it stop responds!? But the program didn't hang and other messages call work fine!?

I saw something similar posts said that I have to destroy the menus right after
TrackPopupMenu(). Why? And is it a must?

Bond
April 27th, 2005, 05:40 PM
I saw something similar posts said that I have to destroy the menus right after
TrackPopupMenu(). Why? And is it a must?
I'm not sure. I believe what you're referring to is DestroyMenu(). The documentation states that:

"an application must use the DestroyMenu function to destroy a menu not assigned to a window"

However, when you use TrackPopupMenu() you are passing in the handle to the window that owns the shortcut menu as one of the parameters. So, I would think that when the window closes, it would see this as a child window and dispose of it properly.

Just to be safe, though, you may want to call it anyway. Note that DestroyMenu() is recursive so in your situation you can just call it for hMenu and that should take care of both hMenu and hPopupMenu.