c++winapidesktop-application

Why does MessageBox block WM_HOTKEY but not WM_TRAYICON in my WindowProc function?


I have a NOTIFYICONDATA structure nid defined on the first instance of a WM_CREATE message. The nid message ID is WM_TRAYICON. I handle the WM_TRAYICON message in WindowProc, which is associated with nid's hWnd. When the WM_TRAYICON is processed I call MessageBox. As I can see now, this looks like a blocking procedure. I cannot processes any WM_HOTKEY messages that were registered with RegisterHotKey, all of which were passed NULL to their hWnd parameter. The modal stops me from interacting with the window referred to by hWnd which is normal. However, WM_TRAYICON messages are still processed. On each click of the tray icon, MessageBox is called, and a new modal appears. I'm wondering if anyone can explain what's going on here. Is the tray icon and the containing status area operating on a different thread than the rest of the program? My understanding of threads is elementary so I might not be using this word properly.

I've included a link to a gist containing all code needed to run the program. The HandleTrayIconMessage is where the problem is. I set up the project using the Windows Desktop Application template from Visual Studio 2022.


Solution

  • I cannot processes any WM_HOTKEY messages that were registered with RegisterHotKey, all of which were passed NULL to their hWnd parameter.

    That is the root cause (and it's the exact same as in your previous question).

    You are not registering your hot keys with your window. As such, WM_HOTKEY messages will arrive in your app as thread messages rather than window messages. Your WindowProc can receive only window messages, so your main message loop will need to process the WM_HOTKEY messages directly.

    However, MessageBox() will block your message loop and run its own secondary message loop, and so it will receive the WM_HOTKEY thread messages and discard them as they have nowhere to go. Raymond Chen describes this in his blog post: Thread messages are eaten by modal loops.

    If you register your hot keys with your window, then MessageBox()'s message loop will be able to dispatch them to your WindowProc, same as your own message loop does.