Skip to content

Commit

Permalink
Cleanup TrayManager
Browse files Browse the repository at this point in the history
  • Loading branch information
d4koon committed Nov 3, 2020
1 parent b75a176 commit 0167ae2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 87 deletions.
81 changes: 25 additions & 56 deletions WhatsappTray/TrayManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uintptr_t>(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.
Expand All @@ -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;
}

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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<UINT>(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) {
Expand All @@ -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;
}

Expand Down
23 changes: 10 additions & 13 deletions WhatsappTray/TrayManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,25 @@
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;

/// The windows that are currently minimized to tray.
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);
};

37 changes: 19 additions & 18 deletions WhatsappTray/WhatsappTray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<UINT>(lParam)) {
case NIN_SELECT: {
_trayManager->RestoreWindowFromTray(_hwndWhatsapp);
} break;
case WM_CONTEXTMENU: {
ExecuteMenu();
} break;
}
} break;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case IDM_ABOUT: {
Expand All @@ -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);
Expand Down Expand Up @@ -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<UINT>(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");
Expand Down Expand Up @@ -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<TrayManager>(_hwndWhatsappTray);
_trayManager->AddWindowToTray(_hwndWhatsapp);
_trayManager->RegisterWindow(_hwndWhatsapp);
}
} break;
}
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 0167ae2

Please sign in to comment.