From 0167ae2ea02e7ea4105d15dd7a12993d382ca7bd Mon Sep 17 00:00:00 2001 From: d4koon Date: Tue, 3 Nov 2020 20:00:09 +0100 Subject: [PATCH] Cleanup TrayManager --- WhatsappTray/TrayManager.cpp | 81 +++++++++++------------------------ WhatsappTray/TrayManager.h | 23 +++++----- WhatsappTray/WhatsappTray.cpp | 37 ++++++++-------- 3 files changed, 54 insertions(+), 87 deletions(-) diff --git a/WhatsappTray/TrayManager.cpp b/WhatsappTray/TrayManager.cpp index c07ec9d..0b3230e 100644 --- a/WhatsappTray/TrayManager.cpp +++ b/WhatsappTray/TrayManager.cpp @@ -32,26 +32,17 @@ using namespace Gdiplus; #undef MODULE_NAME #define MODULE_NAME "TrayManager::" -TrayManager::TrayManager(HWND _hwndWhatsappTray) - : _hwndWhatsappTray(_hwndWhatsappTray) +TrayManager::TrayManager(const HWND hwndWhatsappTray) + : _hwndWhatsappTray(hwndWhatsappTray) , _hwndItems { 0 } { Logger::Info(MODULE_NAME "ctor() - Creating TrayManger."); } -void TrayManager::MinimizeWindowToTray(HWND hwnd) +void TrayManager::MinimizeWindowToTray(const HWND hwnd) { Logger::Info(MODULE_NAME "MinimizeWindowToTray(0x%08X)", reinterpret_cast(hwnd)); - // Don't minimize MDI child windows - if ((UINT)GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD) return; - - // If hwnd is a child window, find parent window (e.g. minimize button in - // Office 2007 (ribbon interface) is in a child window) - if ((UINT)GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) { - hwnd = GetAncestor(hwnd, GA_ROOT); - } - // Hide window // NOTE: The SW_MINIMIZE is important for the case when close-to-tray-feature is used: // Without it, a maximized window is not restored as maximized. @@ -64,11 +55,11 @@ void TrayManager::MinimizeWindowToTray(HWND hwnd) /** * If a window is already in the tray nothing will be done. */ -void TrayManager::AddWindowToTray(HWND hwnd) +void TrayManager::RegisterWindow(const HWND hwnd) { // Add icon to tray if it's not already there if (GetIndexFromWindowHandle(hwnd) != -1) { - Logger::Warning(MODULE_NAME "AddWindowToTray() - Trying to send a window to tray that should already be minimized. This should not happen."); + Logger::Warning(MODULE_NAME "RegisterWindow() - Trying to send a window to tray that should already be minimized. This should not happen."); return; } @@ -81,14 +72,14 @@ void TrayManager::AddWindowToTray(HWND hwnd) } if (newIndex == -1) { - Logger::Error(MODULE_NAME "AddWindowToTray() - Tray is full!"); + Logger::Error(MODULE_NAME "RegisterWindow() - Tray is full!"); } _hwndItems[newIndex] = hwnd; CreateTrayIcon(newIndex, hwnd); } -void TrayManager::CreateTrayIcon(int32_t index, HWND hwnd) +void TrayManager::CreateTrayIcon(const int32_t index, const HWND hwnd) { Logger::Info(MODULE_NAME "CreateTrayIcon(%d)", index); @@ -100,13 +91,15 @@ void TrayManager::CreateTrayIcon(int32_t index, HWND hwnd) nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; nid.uCallbackMessage = WM_TRAYCMD; nid.hIcon = Helper::GetWindowIcon(hwnd); + GetWindowText(hwnd, nid.szTip, sizeof(nid.szTip) / sizeof(nid.szTip[0])); + nid.uVersion = NOTIFYICON_VERSION; Shell_NotifyIcon(NIM_ADD, &nid); Shell_NotifyIcon(NIM_SETVERSION, &nid); } -void TrayManager::CloseWindowFromTray(HWND hwnd) +void TrayManager::CloseWindowFromTray(const HWND hwnd) { Logger::Info(MODULE_NAME "CloseWindowFromTray() x%08X", hwnd); @@ -125,14 +118,14 @@ void TrayManager::CloseWindowFromTray(HWND hwnd) } } -void TrayManager::RemoveTrayIcon(HWND hwnd) +void TrayManager::RemoveTrayIcon(const HWND hwnd) { int32_t index = GetIndexFromWindowHandle(hwnd); if (index == -1) { return; } RemoveFromTray(index); } -void TrayManager::RemoveFromTray(int32_t index) +void TrayManager::RemoveFromTray(const int32_t index) { Logger::Info(MODULE_NAME "RemoveFromTray(%d)", index); @@ -141,52 +134,31 @@ void TrayManager::RemoveFromTray(int32_t index) nid.cbSize = NOTIFYICONDATA_V2_SIZE; nid.hWnd = _hwndWhatsappTray; nid.uID = (UINT)index; + Shell_NotifyIcon(NIM_DELETE, &nid); + _hwndItems[index] = NULL; } void TrayManager::RestoreAllWindowsFromTray() { for (int i = 0; i < MAXTRAYITEMS; i++) { - if (_hwndItems[i]) { - RestoreFromTray(i); + HWND itHwnd = _hwndItems[i]; + if (itHwnd) { + RestoreWindowFromTray(itHwnd); } } } -void TrayManager::RestoreFromTray(uintptr_t index) -{ - HWND hwnd = GetHwndFromIndex(index); - RestoreWindowFromTray(hwnd); -} - -void TrayManager::RestoreWindowFromTray(HWND hwnd) -{ - ShowWindow(hwnd, SW_RESTORE); - SetForegroundWindow(hwnd); -} - -void TrayManager::RefreshWindowInTray(HWND hwnd) +void TrayManager::RestoreWindowFromTray(const HWND hwnd) { - int32_t index = GetIndexFromWindowHandle(hwnd); - if (index == -1) { - return; - } - if (!IsWindow(hwnd) || IsWindowVisible(hwnd)) { - RemoveFromTray(index); - } else { - NOTIFYICONDATA nid; - ZeroMemory(&nid, sizeof(nid)); - nid.cbSize = NOTIFYICONDATA_V2_SIZE; - nid.hWnd = _hwndWhatsappTray; - nid.uID = static_cast(index); - nid.uFlags = NIF_TIP; - GetWindowText(hwnd, nid.szTip, sizeof(nid.szTip) / sizeof(nid.szTip[0])); - Shell_NotifyIcon(NIM_MODIFY, &nid); + if (IsWindowVisible(hwnd) == false) { + ShowWindow(hwnd, SW_RESTORE); + SetForegroundWindow(hwnd); } } -void TrayManager::SetIcon(HWND hwnd, LPCSTR text) +void TrayManager::SetIcon(const HWND hwnd, LPCSTR text) { int32_t index = GetIndexFromWindowHandle(hwnd); if (index == -1) { @@ -212,21 +184,18 @@ void TrayManager::SetIcon(HWND hwnd, LPCSTR text) ::DestroyIcon(iconWithText); } -HWND TrayManager::GetHwndFromIndex(uintptr_t index) -{ - return _hwndItems[index]; -} - -int32_t TrayManager::GetIndexFromWindowHandle(HWND hwnd) +int32_t TrayManager::GetIndexFromWindowHandle(const HWND hwnd) { if (hwnd == NULL) { return -1; } + for (int i = 0; i < MAXTRAYITEMS; i++) { if (_hwndItems[i] == hwnd) { return i; } } + return -1; } diff --git a/WhatsappTray/TrayManager.h b/WhatsappTray/TrayManager.h index 726eb8f..8b9df75 100644 --- a/WhatsappTray/TrayManager.h +++ b/WhatsappTray/TrayManager.h @@ -30,19 +30,16 @@ class TrayManager { public: - TrayManager(HWND _hwndWhatsappTray); + TrayManager(const HWND hwndWhatsappTray); ~TrayManager() { } - void MinimizeWindowToTray(HWND hwnd); - void CloseWindowFromTray(HWND hwnd); - void RemoveTrayIcon(HWND hwnd); - void RemoveFromTray(int32_t index); + void MinimizeWindowToTray(const HWND hwnd); + void CloseWindowFromTray(const HWND hwnd); + void RemoveTrayIcon(const HWND hwnd); + void RemoveFromTray(const int32_t index); void RestoreAllWindowsFromTray(); - void RestoreFromTray(uintptr_t index); - void RestoreWindowFromTray(HWND hwnd); - void RefreshWindowInTray(HWND hwnd); - void SetIcon(HWND hwnd, LPCSTR text); - HWND GetHwndFromIndex(uintptr_t index); - void AddWindowToTray(HWND hwnd); + void RestoreWindowFromTray(const HWND hwnd); + void SetIcon(const HWND hwnd, LPCSTR text); + void RegisterWindow(const HWND hwnd); private: static const int MAXTRAYITEMS = 64; @@ -50,8 +47,8 @@ class TrayManager HWND _hwndWhatsappTray; HWND _hwndItems[MAXTRAYITEMS]; - void CreateTrayIcon(int32_t index, HWND hwnd); - int32_t GetIndexFromWindowHandle(HWND hwnd); + void CreateTrayIcon(const int32_t index, const HWND hwnd); + int32_t GetIndexFromWindowHandle(const HWND hwnd); HICON AddTextToIcon(HICON hBackgroundIcon, LPCSTR text); }; diff --git a/WhatsappTray/WhatsappTray.cpp b/WhatsappTray/WhatsappTray.cpp index 7cfcdd7..a25f0f8 100644 --- a/WhatsappTray/WhatsappTray.cpp +++ b/WhatsappTray/WhatsappTray.cpp @@ -50,7 +50,6 @@ constexpr auto CompileConfiguration = "Release"; static HINSTANCE _hInstance = NULL; static HWND _hwndWhatsappTray = NULL; -static HWND _hwndForMenu = NULL; static HWND _hwndWhatsapp = NULL; static HHOOK _hWndProc = NULL; @@ -145,6 +144,20 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara DestroyWindow(_hwndWhatsappTray); } } break; + case WM_CLOSE: { + DestroyWindow(_hwndWhatsappTray); + } break; + case WM_TRAYCMD: { +#pragma WARNING(Move into TrayManager. Problem is executeMenue...) + switch (static_cast(lParam)) { + case NIN_SELECT: { + _trayManager->RestoreWindowFromTray(_hwndWhatsapp); + } break; + case WM_CONTEXTMENU: { + ExecuteMenu(); + } break; + } + } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDM_ABOUT: { @@ -171,10 +184,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } break; case IDM_RESTORE: { Logger::Info(MODULE_NAME "::WndProc() - IDM_RESTORE"); - _trayManager->RestoreWindowFromTray(_hwndForMenu); + _trayManager->RestoreWindowFromTray(_hwndWhatsapp); } break; case IDM_CLOSE: { - _trayManager->CloseWindowFromTray(_hwndForMenu); + _trayManager->CloseWindowFromTray(_hwndWhatsapp); // Running WhatsappTray without Whatsapp makes no sence because if a new instance of Whatsapp is started, WhatsappTray would not hook it. Atleast not in the current implementation... DestroyWindow(_hwndWhatsappTray); @@ -209,18 +222,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara _trayManager->CloseWindowFromTray(_hwndWhatsapp); } } break; - case WM_TRAYCMD: { -#pragma WARNING(Move into TrayManager. Problem is executeMenue...) - switch (static_cast(lParam)) { - case NIN_SELECT: { - _trayManager->RestoreFromTray(wParam); - } break; - case WM_CONTEXTMENU: { - _hwndForMenu = _trayManager->GetHwndFromIndex(wParam); - ExecuteMenu(); - } break; - } - }break; case WM_WHAHTSAPP_CLOSING: { // If Whatsapp is closing we want to close WhatsappTray as well. Logger::Info(MODULE_NAME "::WndProc() - WM_WHAHTSAPP_CLOSING"); @@ -279,7 +280,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara default: { if (msg == s_uTaskbarRestart) { _trayManager = std::make_unique(_hwndWhatsappTray); - _trayManager->AddWindowToTray(_hwndWhatsapp); + _trayManager->RegisterWindow(_hwndWhatsapp); } } break; } @@ -325,7 +326,7 @@ static bool InitWhatsappTray() return false; } - _trayManager->AddWindowToTray(_hwndWhatsapp); + _trayManager->RegisterWindow(_hwndWhatsapp); if (SetHook() == false) { Logger::Error(MODULE_NAME "::WinMain() - Error setting hook."); @@ -572,7 +573,7 @@ static void ExecuteMenu() AppendMenu(hMenu, MF_UNCHECKED, IDM_SETTING_START_MINIMIZED, "Start minimized"); } - // -- Start minimized. + // -- Show unread messages. if (AppData::ShowUnreadMessages.Get()) { AppendMenu(hMenu, MF_CHECKED, IDM_SETTING_SHOW_UNREAD_MESSAGES, "Show Unread Messages (experimental)"); } else {