4

After checking Microsoft's documentation on system tray icons (that I could find):

Shell_NotifyIconA function

NOTIFYICONDATAA structure

I've noticed that a window handle (HWND) is REQUIRED. This is very bad for what I'm trying to accomplish, as I'm looking to create a program that only reacts to the system tray: it doesn't "minimize" the window to the tray, it just uses notifications (clicking/right clicking on the icon) to interact.

How would I go about doing this?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
ZeroZ30o
  • 375
  • 2
  • 18
  • 6
    You can create a window and never show it. – tkausl Jan 23 '19 at 17:23
  • Oh my god, is this seriously how it's meant to work? Am I unable to pass a nullptr or anything? – ZeroZ30o Jan 23 '19 at 17:25
  • The docs actually explain why you need the window: `A handle to the window that receives notifications associated with an icon in the notification area.` Only window's can receive events, so yes, you definitely need to at least create a hidden window. – tkausl Jan 23 '19 at 17:30
  • 1
    @ZeroZ30o the point is that the window you pass is the target of the messages. It's not uncommon in Win32 to use windows just for message passing - there's even the concept of message-only windows (with no actual associated drawing surface or anything). – Matteo Italia Jan 23 '19 at 17:38
  • Indeed. You need a window in order for the system to communicate with you. Just don't show the window. – David Heffernan Jan 23 '19 at 17:43
  • 1
    You can use a [Message-Only window](https://learn.microsoft.com/en-us/windows/desktop/winmsg/window-features#message-only-windows): "*A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.*" – Remy Lebeau Jan 23 '19 at 17:55
  • 1
    @RemyLebeau Unfortunately, [a message-only window doesn't receive `WM_QUERYENDSESSION`](https://stackoverflow.com/q/21141193/7571258) and other broadcast messages. So if you want to gracefully shutdown, instead of being terminated, a regular hidden window would be a better choice. – zett42 Jan 23 '19 at 18:25
  • @zett42 good point – Remy Lebeau Jan 23 '19 at 18:31

1 Answers1

5

The Windows 7 SDK contains an example called NotificationIcon. This example contains a line

ShowWindow(hwnd, nCmdShow);

in its wWinMain function. The effect of this call is that you see a program window.

Just change this line to

ShowWindow(hwnd, SW_HIDE);

to hide the program window and only display the icon in the system tray. As others have pointed out the program needs a program window, even if it is not visible.

Olaf Hess
  • 1,453
  • 11
  • 18
  • 8
    [NotificationIcon sample at GitHub](https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/winui/shell/appshellintegration/NotificationIcon) – zett42 Jan 23 '19 at 22:03