Skip to content
This repository has been archived by the owner on May 30, 2018. It is now read-only.

Use a separate thread for the tray icon #23

Merged
merged 1 commit into from
Dec 31, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 57 additions & 32 deletions src/Managers/TrayManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define WINDOW_CLASSNAME L"TrayIcon"
#define TRAYID 1
#define WM_TRAYICON WM_USER + 1
#define WM_TRAYICON_CLOSE WM_USER + 100

#define MENU_CONFFOLDER_NAME L"Open &configuration folder"
#define MENU_UPDATE_NAME L"&Download new version"
Expand All @@ -51,6 +52,41 @@ namespace lightfx {
return;
}

this->trayIconThread = thread(&TrayManager::AddTrayIconThreaded, this);
}

LFXE_API void TrayManager::RemoveTrayIcon() {
if (!this->isTrayIconAdded) {
return;
}

SendMessage(this->hTrayIconWindow, WM_TRAYICON_CLOSE, 0, 0);
this->trayIconThread.join();

if (!this->isTrayIconAdded) {
LOG(LogLevel::Debug, L"Tray icon removed");
} else {
LOG(LogLevel::Debug, L"Failed to remove tray icon");
}
}


LFXE_API bool TrayManager::HasUpdateNotification() {
return !this->updateVersionString.empty() && !this->updateVersionUrl.empty();
}

LFXE_API void TrayManager::SetUpdateNotification(const wstring& versionString, const wstring& downloadUrl) {
this->updateVersionString = versionString;
this->updateVersionUrl = downloadUrl;

this->trayIconData.dwInfoFlags = NIIF_INFO | 0x80;
StringCchCopyW(this->trayIconData.szInfoTitle, ARRAYSIZE(this->trayIconData.szInfoTitle), TRAY_BALLOON_TITLE);
StringCchCopyW(this->trayIconData.szInfo, ARRAYSIZE(this->trayIconData.szInfo), (L"Version " + versionString + TRAY_BALLOON_UPDATE_TEXT).c_str());
Shell_NotifyIconW(NIM_MODIFY, &this->trayIconData);
}


void TrayManager::AddTrayIconThreaded() {
this->hModuleInstance = GetCurrentModule();
this->trayIconWindowClass.lpfnWndProc = &TrayManager::WndProc;
this->trayIconWindowClass.hInstance = this->hModuleInstance;
Expand Down Expand Up @@ -89,43 +125,23 @@ namespace lightfx {
} else {
LOG(LogLevel::Debug, L"Failed to add tray icon");
}
}

LFXE_API void TrayManager::RemoveTrayIcon() {
if (!this->isTrayIconAdded) {
return;
}

bool result = Shell_NotifyIconW(NIM_DELETE, &this->trayIconData) == TRUE;
DestroyWindow(this->hTrayIconWindow);
this->hTrayIconWindow = NULL;
UnregisterClassW(WINDOW_CLASSNAME, this->hModuleInstance);
this->hModuleInstance = NULL;

this->isTrayIconAdded = !result;
if (!this->isTrayIconAdded) {
LOG(LogLevel::Debug, L"Tray icon removed");
} else {
LOG(LogLevel::Debug, L"Failed to remove tray icon");
// Process the message loop until we remove the icon
MSG msg;
BOOL hasMsg;
while ((hasMsg = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (hasMsg == -1) {
// Error
LOG(LogLevel::Error, L"Error in processing tray icon message loop");
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}


LFXE_API bool TrayManager::HasUpdateNotification() {
return !this->updateVersionString.empty() && !this->updateVersionUrl.empty();
}

LFXE_API void TrayManager::SetUpdateNotification(const wstring& versionString, const wstring& downloadUrl) {
this->updateVersionString = versionString;
this->updateVersionUrl = downloadUrl;

this->trayIconData.dwInfoFlags = NIIF_INFO | 0x80;
StringCchCopyW(this->trayIconData.szInfoTitle, ARRAYSIZE(this->trayIconData.szInfoTitle), TRAY_BALLOON_TITLE);
StringCchCopyW(this->trayIconData.szInfo, ARRAYSIZE(this->trayIconData.szInfo), (L"Version " + versionString + TRAY_BALLOON_UPDATE_TEXT).c_str());
Shell_NotifyIconW(NIM_MODIFY, &this->trayIconData);
}


LRESULT CALLBACK TrayManager::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_NCCREATE) {
// Set extra window space to point to the this object
Expand All @@ -141,6 +157,15 @@ namespace lightfx {
case WM_TRAYICON:
that->TrayIconCallback(wParam, lParam);
break;
case WM_TRAYICON_CLOSE:
bool result = Shell_NotifyIconW(NIM_DELETE, &that->trayIconData) == TRUE;
DestroyWindow(that->hTrayIconWindow);
that->hTrayIconWindow = NULL;
UnregisterClassW(WINDOW_CLASSNAME, that->hModuleInstance);
that->hModuleInstance = NULL;
that->isTrayIconAdded = !result;
PostQuitMessage(0);
break;
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
};
Expand Down
5 changes: 5 additions & 0 deletions src/Managers/TrayManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// Standard includes
#include <string>
#include <thread>
#include <vector>

// Windows includes
Expand Down Expand Up @@ -47,6 +48,10 @@ namespace lightfx {
NOTIFYICONDATAW trayIconData = {};

bool isTrayIconAdded = false;
bool isTrayIconRemoving = false;
std::thread trayIconThread;

void AddTrayIconThreaded();

static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void TrayIconCallback(WPARAM wParam, LPARAM lParam);
Expand Down