C++/Win32: Context Menus
March 2, 2008
Context menus are the little popup menus that appear when you right-click on certain areas in an application. They’re called context menus because the menu and/or menu options you see depend on the context. If you right-click in an edit box, for example, you might get options to cut, paste, copy, clear, etc. If you right-click on a list view, in the same application, you might be presented with options to sort the list.
We primarily want to add a context menu to our system tray icon, so that when the app is minimized, the user can quickly exit the program without having to restore it from the system tray and then exit it. When we’re done, right-click->Exit will do the trick.
The process is, in general, pretty simple:
HMENU hPopupMenu = CreatePopupMenu(); InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_POPUP_EXIT, "Exit"); SetForegroundWindow(m_hWnd); TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, xpos, ypos, 0, m_hWnd, NULL);
The SetForegroundWindow(m_hWnd); line is there due to a bug explained in http://support.microsoft.com/support/kb/articles/q135/7/88.asp.
We’ll want to put this code inside our message handler, in response to a WM_USER message with lParam == WM_RBUTTONDOWN. If you don’t understand why we’re responding to WM_USER, make sure to read the lesson on minimizing to the system tray.
If you #include
We are specifying the identifier ID_POPUP_EXIT for our Exit menu option, so we can now respond to WM_COMMAND messages with the LOWORD(wParam) == IDPOPUPEXIT by removing the icon from the system tray and calling PostQuitMessage(0) to close the application.
So… try this in your code, and see if it works. It does, but the position of the menu is all wrong! Why is that?
Well, when a right-click message is received, the position returned is relative to the window that is processing the message. That will work fine if we are creating context menus for clicks occurring inside our app window. But that’s not what we want for the system tray. What we want is the cursor position relative to the desktop, which we can get by calling GetCursorPos:
POINT p; GetCursorPos(&p);
Now, p.x and p.y will give the correct screen coordinates which we can use to properly popup out menu, giving the user the option to quit.
That about does it for this project. We’ve got a fully functional Win32 app with some special (and mostly useless) features added in. Hopefully you have learned enough to jump off from here and start coding your own Win32 projects. My real intent all along was to get you far enough along into programming Win32 that you can access MSDN or the Win32 API docs yourself to keep moving along in your development. If you’ve finished this tutorial, that’s exactly where you should be at this point.
Good luck!
Source Code:
win32tut_part19.zip [3.40MB zipped]
Additional Information:
· TheForger’s Win32 API Tutorial - Files target=_blank>CodeProject - ListViews
Further Reading:
· Nitty Gritty Windows Programming with C++ by Henning Hansen.
· Thinking in C++ by Bruce Eckel.




Comments
Got something to say?