So here I was, happily programming my little stopwatch, I had already created my system tray icon and embedded some version info into. Now I was ready to implement to heart of my application, A popup menu to control the stopwatch. I looked up msdn, searched the net and came up with my code to create the popup menu.

From what I understood, it was a three step process create a handle to a menu, append items to the menu and display the menu using ‘TrackPopupMenu’. To start of with, I decided to implement just two commands under the menu. Just to test out the code and how it works. Following is the code that I implemented.

HMENU hPopup = CreateMenu();
AppendMenu(hPopup, MF_STRING, ID_START, L"Start");
AppendMenu(hPopup, MF_STRING, ID, L"Stop");

POINT pt;
GetCursorPos(&pt);

TrackPopupMenuEx(hPopup, TPM_RIGHTALIGN  | TPM_LEFTBUTTON, pt.x, pt.y, hWnd, NULL);

DestroyMenu(hPopup);

I compiled my code and ran my program. I rightclick on my icon and Bam, A menu as thin as angel hair spagehti, with no strings displayed. Check out the screenshot.

Menu over my system tray icon

Tray Icon Menu

Menu over the application Window

Menu over the application Window

As you can see in the two screen shots, the menu has the required number of rows, i.e. 3 as per my description and it even sends out the appropriate messages when one of them is clicked, It just doesn’t display anything. This little discrepancy took me a while to figure out. From what I found out, this problem is faced by people new to win32. This is one of those little Idiosyncrasy of win32 API. The way to resolve this problem is a bit peculiar.

To get the menu displaying properly, first we need to append our menu to a temporary menu as a POPUP to it, then we have to extract the menu back using GetSubMenu function and use that handle in TrackPopupMenuEx function. The code below would explain it much better.

HMENU hPopup = CreateMenu();
HMENU hTemp = CreateMenu();

AppendMenu(hPopup, MF_STRING, ID_START, L"Start");
AppendMenu(hPopup, MF_STRING, ID_STOP, L"Stop");

AppendMenu(hTemp, MF_POPUP, (UINT_PTR) hPopup, L"Dummy");
hPopup = GetSubMenu(hTemp, 0);

POINT pt;
GetCursorPos(&pt);
TrackPopupMenuEx(hPopup, TPM_RIGHTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, hWnd, NULL);

DestroyMenu(hTemp);
DestroyMenu(hPopup);

And with that, my popup menu gives up its diet and displays perfectly.

Menu after it stopped Dieting

Menu after it stopped Dieting

I hope this helps out people who are just starting out with win32 and ran into this problem, as I had to spend a lot of time trying to figure out this problem.

What if the menu is defined as a resource

Let me define the orginal menu as a resource, remember this will show up as a thin bar.

First the resource.rc file

MENUDEMO MENU DISCARDABLE
BEGIN
    MENUITEM "Start"  ID_START
    MENUITEM "Stop"   ID_STOP
END

To fix this description, we have to add a fake POPUP block to the description as follows.

MENUDEMO MENU DISCARDABLE
BEGIN
     POPUP "Dummy"
     BEGIN
          MENUITEM "Start" ID_START
          MENUITEM "Stop"  ID_STOP
     END
END

Now as before, we would extract the submenu using the GetSubMenu function and then display the submenu using TrackPopupMenuEx function.

I hope this helps out everyone, as it was very frustrating to figure this problem out. Do drop by and let me know if there is a better way of solving this problem, I would love to hear about it.