Почему не работают всплывающие подсказки Shell_NotifyIcon?

Согласно всему, что я видел, следующая программа на C++ должна отображать всплывающую подсказку из значка в трее, когда я щелкаю левой кнопкой мыши в окне приложения, но она не работает. Может ли кто-нибудь сказать мне, что мне не хватает?

Это на XP с версией 6.0 Shell32.dll (проверено с помощью DllGetVersion).

Спасибо!

    #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;
    }

person Bill Brooks    schedule 22.04.2009    source источник
comment
Кстати, это на XP, а DllGetVersion() возвращает 6.0.   -  person Bill Brooks    schedule 22.04.2009


Ответы (3)


Ба, я понял. По какой-то причине с заголовками у меня...

sizeof(NOTIFYICONDATA) == 508

в то время как...

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

Если я укажу либо V2, либо V3 вместо sizeof(NOTIFYICONDATA), всплывающие подсказки будут отображаться нормально.

person Bill Brooks    schedule 22.04.2009
comment
Дайте этому человеку сигару. Вы, наверное, только что сэкономили мне пару часов. Отметьте свой ответ как правильный, чтобы получить репутацию! - person Jon Bright; 13.06.2009
comment
Для юникода: NOTIFYICONDATAW_V2_SIZE == 936, при использовании sizeof(NOTIFYICONDATAW) возвращается 952. Кстати. в ShellAPI.h есть ошибка, когда вы определяете _WINN32_WINNT в 0x0500 (win2k) и пытаетесь использовать NOTIFYICONDATAW_V2_SIZE (win2k или более поздняя версия), вы получаете сообщение об ошибке: ошибка C2039: 'guidItem': не является членом '_NOTIFYICONDATAW'. Чтобы исправить это, вам нужно закодировать значение NOTIFYICONDATAW_V2_SIZE при настройке cbSize, используйте этот 936. - person Czarek Tomczak; 18.02.2012

Вы проверили в реестре под ...

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

... для EnableBalloonTips? Пользователи очень часто отключают эту функцию.

person JP Alioto    schedule 22.04.2009
comment
Я искал этот ключ, но его нет на моей машине. - person Bill Brooks; 22.04.2009
comment
Подробнее см. на этой странице: howtogeek .com/howto/windows-vista/ - person Greg Fenton; 27.01.2012

Проблема в том, что вы предполагаете, что Windows отправит вам WM_LBUTTONDOWN, когда пользователь щелкнет значок, но это неверно. WM_LBUTTONDOWN отправляется только тогда, когда пользователь щелкает внутри клиентской области hWnd, если вы внимательно прочитаете документацию NOTIFYICONDATA, вы поймете, что когда пользователь щелкает значок, Windows отправит вам сообщение WM_USER+20 (в соответствии с вашим кодом) и в параметре lParam вы получите уведомление WM_LBUTTONDOWN.

person george b    schedule 01.12.2011