mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 12:15:34 +08:00
[feat] add configuration to minimize to system tray when clicking the close button, refs #4
This commit is contained in:
112
src/gui/tray/win_tray.cpp
Normal file
112
src/gui/tray/win_tray.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "win_tray.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "localization.h"
|
||||
|
||||
// callback for the message-only window that handles tray icon messages
|
||||
static LRESULT CALLBACK MsgWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
WinTray* tray =
|
||||
reinterpret_cast<WinTray*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
if (!tray) {
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
if (msg == WM_TRAY_CALLBACK) {
|
||||
MSG tmpMsg = {};
|
||||
tmpMsg.message = msg;
|
||||
tmpMsg.wParam = wParam;
|
||||
tmpMsg.lParam = lParam;
|
||||
tray->HandleTrayMessage(&tmpMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
WinTray::WinTray(HWND app_hwnd, HICON icon, const std::wstring& tooltip,
|
||||
int language_index)
|
||||
: app_hwnd_(app_hwnd),
|
||||
icon_(icon),
|
||||
tip_(tooltip),
|
||||
hwnd_message_only_(nullptr),
|
||||
language_index_(language_index) {
|
||||
WNDCLASS wc = {};
|
||||
wc.lpfnWndProc = MsgWndProc;
|
||||
wc.hInstance = GetModuleHandle(nullptr);
|
||||
wc.lpszClassName = L"TrayMessageWindow";
|
||||
RegisterClass(&wc);
|
||||
|
||||
// create a message-only window to receive tray messages
|
||||
hwnd_message_only_ =
|
||||
CreateWindowEx(0, wc.lpszClassName, L"TrayMsg", 0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE, nullptr, wc.hInstance, nullptr);
|
||||
|
||||
// store pointer to this WinTray instance in window data
|
||||
SetWindowLongPtr(hwnd_message_only_, GWLP_USERDATA,
|
||||
reinterpret_cast<LONG_PTR>(this));
|
||||
|
||||
// initialize NOTIFYICONDATA structure
|
||||
ZeroMemory(&nid_, sizeof(nid_));
|
||||
nid_.cbSize = sizeof(nid_);
|
||||
nid_.hWnd = hwnd_message_only_;
|
||||
nid_.uID = 1;
|
||||
nid_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||
nid_.uCallbackMessage = WM_TRAY_CALLBACK;
|
||||
nid_.hIcon = icon_;
|
||||
wcsncpy_s(nid_.szTip, tip_.c_str(), _TRUNCATE);
|
||||
}
|
||||
|
||||
WinTray::~WinTray() {
|
||||
RemoveTrayIcon();
|
||||
if (hwnd_message_only_) DestroyWindow(hwnd_message_only_);
|
||||
}
|
||||
|
||||
void WinTray::MinimizeToTray() {
|
||||
Shell_NotifyIcon(NIM_ADD, &nid_);
|
||||
// hide application window
|
||||
ShowWindow(app_hwnd_, SW_HIDE);
|
||||
}
|
||||
|
||||
void WinTray::RemoveTrayIcon() { Shell_NotifyIcon(NIM_DELETE, &nid_); }
|
||||
|
||||
bool WinTray::HandleTrayMessage(MSG* msg) {
|
||||
if (!msg || msg->message != WM_TRAY_CALLBACK) return false;
|
||||
|
||||
switch (LOWORD(msg->lParam)) {
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_LBUTTONUP: {
|
||||
ShowWindow(app_hwnd_, SW_SHOW);
|
||||
SetForegroundWindow(app_hwnd_);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONUP: {
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
HMENU menu = CreatePopupMenu();
|
||||
AppendMenuW(menu, MF_STRING, 1001,
|
||||
localization::exit_program[language_index_]);
|
||||
|
||||
SetForegroundWindow(hwnd_message_only_);
|
||||
int cmd =
|
||||
TrackPopupMenu(menu, TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTALIGN,
|
||||
pt.x, pt.y, 0, hwnd_message_only_, nullptr);
|
||||
DestroyMenu(menu);
|
||||
|
||||
// handle menu command
|
||||
if (cmd == 1001) {
|
||||
// exit application
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
} else if (cmd == 1002) {
|
||||
ShowWindow(app_hwnd_, SW_SHOW); // show main window
|
||||
SetForegroundWindow(app_hwnd_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user