Why aren't Shell_NotifyIcon balloon tips worki

2020-06-23 05:17发布

According to everything I've seen, the following C++ program should be displaying a balloon tool tip from the tray icon when I left-click in the application window, yet it's not working. Can anyone tell me what I'm missing?

This is on XP with version 6.0 of Shell32.dll (verified with DllGetVersion).

Thanks!

    #include "stdafx.h"
    #include "shellapi.h"

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

    int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        MSG msg;

        WNDCLASS wc;
        memset(&wc, 0, sizeof(wc));
        wc.lpfnWndProc = WndProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszClassName = "sysTrayTest";
        RegisterClass(&wc);

        HWND hWnd = CreateWindow("sysTrayTest", "", 
                                WS_OVERLAPPEDWINDOW,
                                CW_USEDEFAULT, 0, 500, 500, 
                                NULL, NULL, hInstance, NULL);
        if (hWnd)
        {
            ShowWindow(hWnd, nCmdShow);
            while (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }

        return 0;
    }

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_DESTROY:
            {
                NOTIFYICONDATA nid;
                memset(&nid, 0, sizeof(NOTIFYICONDATA));
                nid.cbSize = sizeof(NOTIFYICONDATA);
                nid.hWnd = hWnd;
                nid.uID = 1;
                Shell_NotifyIcon(NIM_DELETE, &nid);

                PostQuitMessage(0);
            }
            break;

            case WM_CREATE:
            {
                NOTIFYICONDATA nid;
                memset(&nid, 0, sizeof(NOTIFYICONDATA));
                nid.cbSize = sizeof(NOTIFYICONDATA);
                nid.hWnd = hWnd;
                nid.uID = 1;
                nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
                nid.uCallbackMessage = WM_USER + 200;
                nid.hIcon = LoadIcon(NULL, IDI_INFORMATION);
                lstrcpy (nid.szTip, "Test Tip");
                Shell_NotifyIcon(NIM_ADD, &nid);
            }
            break;

            case WM_LBUTTONDOWN:
            {
                NOTIFYICONDATA nid;
                memset(&nid, 0, sizeof(NOTIFYICONDATA));
                nid.cbSize = sizeof(NOTIFYICONDATA);
                nid.hWnd = hWnd;
                nid.uID = 1;
                nid.uFlags = NIF_INFO;
                lstrcpy(nid.szInfo, "Test balloon tip");
                lstrcpy(nid.szInfoTitle, "Test Title");
                nid.dwInfoFlags = NIIF_INFO;
                nid.uTimeout = 15000;
                Shell_NotifyIcon(NIM_MODIFY, &nid);
            }
            break;

            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }

3条回答
孤傲高冷的网名
2楼-- · 2020-06-23 05:47

Bah, I figured it out. For some reason with the headers I have...

sizeof(NOTIFYICONDATA) == 508

whereas...

NOTIFYICONDATA_V3_SIZE == 504
NOTIFYICONDATA_V2_SIZE == 488
NOTIFYICONDATA_V1_SIZE == 88

If I specify either V2 or V3 instead of sizeof(NOTIFYICONDATA) the balloon tips show up just fine.

查看更多
姐就是有狂的资本
3楼-- · 2020-06-23 06:00

The problem is that you are assuming Windows is going to send you a WM_LBUTTONDOWN when the user click on the icon, but that is not correct. WM_LBUTTONDOWN is sent only when the user clicks inside the hWnd's client area, if you read carefully the documentation of NOTIFYICONDATA you will realize that when the user clicks the icon Windows will send you a WM_USER+20 message (according to your code) and in the lParam paramter you will get the WM_LBUTTONDOWN notification.

查看更多
做个烂人
4楼-- · 2020-06-23 06:05

Have you checked in the registry under ...

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

... for EnableBalloonTips? It's something very common for users to turn off.

查看更多
登录 后发表回答