windowswinapitaskbarnotification-area

Is my application icon visible in the Windows notification area?


My software has a notification icon. Windows hides inactive icons by default. When a user closes my application, I would like to inform them, that the application is still active in the background and they can reach it through the icon in the hidden notification area.

I would like to show this message only if the icon is indeed not visible.

Using Shell_NotifyIconGetRect doesn’t help much, because even if the icon is hidden, it still succeeds and returns the coordinates of the arrow icon.

Is there any other way to find out if my notification icon is currently visible or not? Alternatively, is there a way to find out the coordinates of the arrow icon – then I could compare them with the coordinates I got looking for my icon. Or is there at least a way to find out if the arrow icon is shown at all (that would help me a little bit with a fallback solution).


Solution

  • Using Shell_NotifyIconGetRect doesn’t help much, because even if the icon is hidden, it still succeeds and returns the coordinates of the arrow icon.

    The result after my test is not like this.

    I created a sample and used the following code:

    static NOTIFYICONDATA nid;
    static NOTIFYICONIDENTIFIER niif;
    case WM_CREATE:
    {
        nid.cbSize = sizeof(NOTIFYICONDATA);
        nid.hWnd = hwnd;
        nid.uID = 1001;
        nid.uCallbackMessage = WM_MYMESSAGE;
        nid.hIcon = LoadIcon(NULL, IDI_QUESTION);
        strcpy(nid.szTip, "Test Tool");
        nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
        nid.dwStateMask = NIS_HIDDEN;
        size_t nidszTipLength = sizeof(nid.szTip) / sizeof(nid.szTip[0]);
        Shell_NotifyIcon(NIM_ADD, &nid);
        niif.cbSize = sizeof NOTIFYICONIDENTIFIER;
        niif.hWnd = nid.hWnd;
        niif.uID = nid.uID;
        niif.guidItem = GUID_NULL;
        return 0;
    }
    

    Then I use Shell_NotifyIconGetRect to get the coordinates of the icon:

    RECT rc;
    HRESULT hr = Shell_NotifyIconGetRect(&niif, &rc);
    

    When the icon is in the hidden area:

    enter image description here

    When I modify its location:

    enter image description here

    It can be seen that even in the hidden area, the coordinates of the icon can be obtained through the Shell_NotifyIconGetRect function.

    Similarly, I tested the situation not in the hidden area:

    enter image description here

    You can find that the size and coordinates of the icon have changed, and you can judge whether the icon is in the hidden area based on them.

    Edit:

    When the hidden area is closed:

    If the icon is displayed in the notification area, the Shell_NotifyIconGetRect function returns S_OK:

    enter image description here

    If the icon is in the hidden area of the notification area, the function returns S_FALSE:

    enter image description here