3
votes

The project I'm working on right now is essentially an open source version of Ultramon (the multiple taskbar program). Thus think of the application to be just like the windows taskbar. Buttons for each window, etc. This is coded in C/C++ using WinAPI

I've just started doing it, and have some of the functionality down. However, I'm getting stuck at getting the system menus (eg the menus that you get when you rightclick on a taskbar 'button') showing when and where I want them to.

I'm trying to use:

HMENU menu = GetSystemMenu(item, false); 
SetForegroundWindow(hWnd);
TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, 0, 0, 0, hWnd, NULL);
PostMessage(hWnd, WM_NULL, 0, 0);

item is the HWND I want the menu for, hWnd is the HWND for the button/item I want the menu to show up on. (its showing at 0, 0 for now, the top left corner of my main monitor).

This code works perfectly every time for a system menu which is customized. Eg: its NOT the standard menu of just "Restore", "Maximize" etc etc, it has some added in menu items. Those menus will always display where I want.

However, the default basic system menus (eg the ones with only Maximize, restore, close etc), will ONLY display for the FIRST time I use them. After that they refuse to show up. Unless I restart the computer, run it again, at which point they work perfectly.

Note: SetForegroundWindow(hWnd); and PostMessage(hWnd, WM_NULL, 0, 0); are in there because I read somewhere that the system menu would only work the first time unless I did that trick of bringing it to the foreground, but it still doesn't work correctly.

So does anyone have any idea how to get this working correctly? Or why it works only the first time after I restart the computer?


Just tested something, it will also show the system menu again for a window if I close the window (eg exiting the program) and re-opening it. But once again, it will only show it once then it stops working.

1
link to this project please:)zproxy
Aren't you supposed to check which item the user clicked in TrackPopupMenu, then pass it in WM_SYSCOMMAND, rather than sending WM_NULL?EricLaw
The problem with applications which don't have custom system menus is that GetSystemMenu creates the menu, and as far as I can tell, assigns ownership to your process. When your process exits, the menu is destroyed, but GetSystemMenu continues returning the same (now invalid) menu handle. Alt+Space will still work, presumably because the window manager falls back to its own global copy of the system menu.Lexikos

1 Answers

0
votes

It might be hacky, but have you tried setting the window focus and then issuing an Alt+Space through something like SendInput?