Я пытаюсь написать простой многократно используемый класс, чтобы инкапсулировать функциональность для иконки в трее. Это мой первый «проект» с 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;
}
Спасибо за ваше время.
Вам нужна какая-то форма цикла сообщений, а не блокирующий вызов для ввода чего-либо. Попробуйте канонический цикл сообщений:
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}