仅消息窗口不接收来自托盘图标的消息

时间:2014-04-23 22:19:01

标签: c++ windows windows-messages trayicon

我试图编写一个简单的可重用类来封装基本托盘图标的功能。这是我的第一个"项目"使用C ++,我遇到了一些问题:为托盘图标创建的仅限消息的窗口不会收到任何消息。图标在托盘中可见,并且具有正确的工具提示,但点击它不会向我的隐形窗口发送任何消息。

为了测试函数WindowProcedure是否被调用,我添加了一个printf语句,输出是该函数在创建时被调用了4次,但是没有,即使我点击了通知图标。

为什么我的窗口没有从托盘图标收到任何消息?

这是我设法写的:

TrayIcon.h

class TrayIcon {

    public:
        TrayIcon();
        ~TrayIcon();
        void Show();
        /*...*/
        static void Initialize();


    private:
        static LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
        /*...*/    
};

TrayIcon.cpp

// Static initializer
int TrayIcon::_idCounter = 1;
void TrayIcon::Initialize() // This method is called just once
{
    // Registers the class for the tray windows
    WNDCLASSEX wx = {};
    wx.lpfnWndProc = TrayIcon::WindowProcedure;
    wx.lpszClassName = TRAYICON_WINDOW_CLASSNAME;
    wx.cbSize = sizeof(WNDCLASSEX);
    RegisterClassEx(&wx);
}

// Constructor
TrayIcon::TrayIcon()
{
    // Creates an hidden message-only window
    HWND hWnd = CreateWindowEx(0, TRAYICON_WINDOW_CLASSNAME, "trayiconwindow", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)this);

    // Creates the notify icon
    NOTIFYICONDATA icon;
    memset( &icon, 0, sizeof( NOTIFYICONDATA ) ) ;
    icon.cbSize = sizeof(NOTIFYICONDATA);
    icon.hWnd = hWnd;
    icon.uID = TrayIcon::_idCounter++;
    icon.uCallbackMessage = WM_TRAYICON; //Set up our invented Windows Message
    icon.uFlags = NIF_MESSAGE;
    this->_iconData = icon;
}

// Shows the tray icon
void TrayIcon::Show()
{
    // ...
    Shell_NotifyIcon(NIM_ADD, &this->_iconData);
}

// Processes the messages received by the hidden window for each icon
LRESULT CALLBACK TrayIcon::WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TrayIcon* icon = (TrayIcon*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    printf("Window Procedure called.\n\r");
    return DefWindowProc(hwnd, message, wParam, lParam);
}

这就是我使用该类的方式:

int main()
{
    // Creates a new Tray icon
    TrayIcon::Initialize();
    TrayIcon* icon = new TrayIcon();
    icon->SetTooltip("Foo Tooltip");
    icon->SetIcon(...);
    icon->Show();

    // Waits for user input
    void* tmp;
    cin >> tmp;
    return 0;
}

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

您需要某种形式的消息循环,而不是阻止调用输入内容。尝试规范的消息循环:

MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}