C++ 仅消息窗口不接收来自托盘图标的消息
我试图编写一个简单的可重用类来封装基本托盘图标的功能。这是我的第一个C++项目,我有一些问题:<强>为托盘图标创建的消息窗口没有收到任何消息<强>。该图标在任务栏中可见,并具有正确的工具提示,但单击该图标不会向“我的不可见窗口”发送任何消息 为了测试函数C++ 仅消息窗口不接收来自托盘图标的消息,c++,windows,windows-messages,trayicon,C++,Windows,Windows Messages,Trayicon,我试图编写一个简单的可重用类来封装基本托盘图标的功能。这是我的第一个C++项目,我有一些问题:为托盘图标创建的消息窗口没有收到任何消息。该图标在任务栏中可见,并具有正确的工具提示,但单击该图标不会向“我的不可见窗口”发送任何消息 为了测试函数WindowProcedure是否被调用,我添加了一个printf语句,输出结果是函数在创建时被调用了4次,但没有更多,即使我单击了notify图标 为什么我的窗口没有收到来自托盘图标的任何消息? 这就是我所写的: TrayIcon.h: class Tra
WindowProcedure
是否被调用,我添加了一个printf
语句,输出结果是函数在创建时被调用了4次,但没有更多,即使我单击了notify图标
为什么我的窗口没有收到来自托盘图标的任何消息?
这就是我所写的:
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);
/*...*/
};
// 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);
}
TrayIcon.cpp
:
class TrayIcon {
public:
TrayIcon();
~TrayIcon();
void Show();
/*...*/
static void Initialize();
private:
static LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/*...*/
};
// 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;
}
谢谢您的时间。您需要某种形式的消息循环,而不是通过阻塞调用来输入内容。尝试规范消息循环:
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
谢谢,它工作得很好。我打赌我昨天试过了,但没用。我绝对应该在午夜后停止编程!