views:

227

answers:

3

I'm trying to create a dynamic popup menu within my application, the generation code I use is something like that :

    HMENU   menu;
    POINT   pt;

    menu = CreatePopupMenu();

    SetForegroundWindow( receivingWindow );
    GetCursorPos( &pt );
    int i = 19;
    AppendMenu( menu, MF_STRING, i++, _TEXT("meh meh") );
    AppendMenu( menu, MF_STRING, i++, _TEXT("testo") );
    AppendMenu( menu, MF_STRING, i++, _TEXT("foobar foobar") );
    TrackPopupMenuEx( menu
                    , 0
                    , pt.x, pt.y
                    , receivingWindow
                    , NULL );

    DestroyMenu( menu );

_TEXT is used to ensure text is in Unicode and receivingWindow is a Layered window created before and working well.

When calling TrackPopupMenuEx the menu is displayed with the good size and at the good position, but absolutely no text appear in the popup menu. Did someone got an idea why, and how to fix this problem?

EDIT: more information regarding my environment :

  • Windows 7 x64
  • x86 build in Visual Studio 2008

EDIT2: I've tested the same on Windows XP x86, and it works like a charm, and after further test, the menu is well displayed in Windows 7 x64 with the classic look.

A: 

If your compiler is not set to compile for unicode (i.e #ifndef UNICODE) then winuser.h will map AppendMenu to AppendMenuA which is a non-unicode version and would interpret your strings as multi-byte. Perhaps this explains your issue? You could explicitly call AppendMenuW() (the unicode version) to check if this is your issue.

Elemental
Sadly, UNICODE is already defined and AppendMenuW is well called.
Raoul Supercopter
_TEXT() is also affected by the presenceof, or lack of, UNICODE define. If UNICODE is not defined, AppendMenu() maps to AppendMenuA(), but the text inside _TEXT() also maps to Ansi instead of Unicode. So there is no conflict here.
Remy Lebeau - TeamB
A: 

I believe the problem is that the function TrackPopUpMenuEx doesn't return immediately; thus after it initiates (and presumably chooses it's size and position) but before it first displays you are destroying the menu.

As I understand it you need to destroy the menu after your window has received the command message from a menu selection. Alternately use the TPM_RETURNCMD flag in TrackPopUpMenuEx as this forces trackpopupex to only return after a menu item has been selected (as opposed to immediately).

Elemental
When I put a breakpoint on DestroyMenu, it break only after I've clicked on any blank item in the menu. Again I can see the menu, the text is just invisible :(
Raoul Supercopter
A: 

I found a workaround for this problem. Instead of using my main window (receivingWindow), I'm using a message only window to receive the event. For a reason that I don't understand, the text is displayed normally this way.

Raoul Supercopter