我试图编写一个简单的可重用类来封装基本托盘图标的功能。这是我的第一个"项目"使用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;
}
感谢您的时间。
答案 0 :(得分:2)
您需要某种形式的消息循环,而不是阻止调用输入内容。尝试规范的消息循环:
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}