Skip to content

Commit

Permalink
Improvements:
Browse files Browse the repository at this point in the history
- react to accent color change event
- react to session status change event
- remote timers
  • Loading branch information
HunterZ committed Sep 25, 2017
1 parent 960c2b6 commit 8eeb970
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
*.dll
*.obj
*.tlog
*.user
.vs
Debug/
LFX2.h
LogitechLEDLib.*
Release/
ipch/
UniLight.exe
UniLight.zip
11 changes: 8 additions & 3 deletions UniLight/ColorUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,22 @@ namespace

namespace ColorUtil
{
COLORREF Dword2ColorRef(const DWORD dword)
{
static ColorU color;
color.ci = dword;
return RGB(color.cs.red, color.cs.green, color.cs.blue);
}

bool GetColorizationColor(COLORREF& colorRef)
{
static DWORD dwColor(0);
static BOOL opaque(TRUE);
static bool useResult(false);
static ColorU color;
useResult = SUCCEEDED(DwmGetColorizationColor(&dwColor, &opaque));
if (useResult)
{
color.ci = dwColor;
colorRef = RGB(color.cs.red, color.cs.green, color.cs.blue);
colorRef = Dword2ColorRef(dwColor);
}
return useResult;
}
Expand Down
3 changes: 3 additions & 0 deletions UniLight/ColorUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
// functions for working with Windows accent color API
namespace ColorUtil
{
// convert DwmGetColorizationColor() DWORD color to COLORREF color
COLORREF Dword2ColorRef(const DWORD dword);

// get current Windows accent color into colorRef
// returns true on success, false on failure
bool GetColorizationColor(COLORREF& colorRef);
Expand Down
144 changes: 97 additions & 47 deletions UniLight/Main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
// UniLight by HunterZ

/*
#ifndef _FILE_DEFINED
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif
*/
#include "ColorUtil.h"
#include "LFXUtil.h"
#include "LLEDUtil.h"
Expand All @@ -10,12 +25,15 @@
#include <strsafe.h>
#include <tchar.h>
#include <windows.h>

#include <Wtsapi32.h>
/*
#include <iostream>
#include <io.h>
#include <fcntl.h>
*/
#define ID_TRAY_APP_ICON 1001
#define ID_TRAY_EXIT 1002
#define ID_TRAY_ABOUT 1003
#define IDT_TIMER 1004
#define IDT_TIMER_INIT 1005
#define WM_SYSICON (WM_USER + 1)

namespace
Expand All @@ -29,6 +47,27 @@ namespace
LLEDUtil::LLEDUtilC llledUtil;
COLORREF lastColor(0);
}
/*
// maximum mumber of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;
void RedirectIOToConsole()
{
AllocConsole();
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long)handle_out, _O_TEXT);
FILE* hf_out = _fdopen(hCrt, "w");
setvbuf(hf_out, NULL, _IONBF, 1);
*stdout = *hf_out;
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
hCrt = _open_osfhandle((long)handle_in, _O_TEXT);
FILE* hf_in = _fdopen(hCrt, "r");
setvbuf(hf_in, NULL, _IONBF, 128);
*stdin = *hf_in;
}
*/

void ShowAbout(HWND hwnd)
{
Expand All @@ -40,9 +79,43 @@ void ShowAbout(HWND hwnd)
active = false;
}

void UpdateColor(const COLORREF curColor)
{
// set AlienFX/LightFX color
const bool lfxStatus(lfxUtil.SetLFXColor(GetRValue(curColor), GetGValue(curColor), GetBValue(curColor)));

// set Logitech LED color
const bool lledStatus(llledUtil.SetLLEDColor(GetRValue(curColor), GetGValue(curColor), GetBValue(curColor)));

// set tooltip
std::wstringstream s;
s << "UniLight status:";
s << "\nCurrent color: 0x" << std::setfill(L'0') << std::setw(8) << std::hex << curColor;
s << "\nPrevious color: 0x" << std::setfill(L'0') << std::setw(8) << std::hex << lastColor;
s << "\nLightFX: " << (lfxStatus ? "active" : "inactive");
s << "\nLogiLED: " << (lledStatus ? "active" : "inactive");
StringCchCopy(notifyIconData.szTip, 128, s.str().c_str());
Shell_NotifyIcon(NIM_MODIFY, &notifyIconData);

// update last-seen color to new value
lastColor = curColor;

// std::cout << std::setfill('0') << std::setw(8) << std::hex << curColor << std::endl;
}

void GetAndUpdateColor()
{
static COLORREF curColor(0);
const bool success(ColorUtil::GetColorizationColor(curColor));
if (!success) return;
UpdateColor(curColor);
}

// This function is called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// std::cout << "hwnd=" << hwnd << ", message=" << message << ", wParam=" << wParam << ", lParam=" << lParam << std::endl;

// if explorer restarts, re-add tray icon
// this can't be handled in the switch() below because it is a dynamic value
if (message == WM_TASKBARCREATED)
Expand All @@ -54,7 +127,7 @@ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM
// handle the messages
switch (message)
{
// user-defined WM_SYSICON message
// user-defined WM_SYSICON message indicating interaction with tray icon
case WM_SYSICON:
{
// we could check for wParam == ID_TRAY_APP_ICON here, but why bother when we have only one?
Expand All @@ -79,46 +152,19 @@ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM
}
}
}
break;
return 0;

// color check timers
case WM_TIMER:
// accent color changed
case WM_DWMCOLORIZATIONCOLORCHANGED:
{
COLORREF curColor(0);
const bool success(ColorUtil::GetColorizationColor(curColor));
static bool firstTime(true);
if (success &&
(curColor != lastColor || firstTime))
{
firstTime = false;

// set AlienFX/LightFX color
const bool lfxStatus(lfxUtil.SetLFXColor(GetRValue(curColor), GetGValue(curColor), GetBValue(curColor)));

// set Logitech LED color
const bool lledStatus(llledUtil.SetLLEDColor(GetRValue(curColor), GetGValue(curColor), GetBValue(curColor)));

// set tooltip
std::wstringstream s;
s << "UniLight status:";
s << "\nCurrent color: 0x" << std::setfill(L'0') << std::setw(8) << std::hex << curColor;
s << "\nPrevious color: 0x" << std::setfill(L'0') << std::setw(8) << std::hex << lastColor;
s << "\nLightFX: " << (lfxStatus ? "active" : "inactive");
s << "\nLogiLED: " << (lledStatus ? "active" : "inactive");
StringCchCopy(notifyIconData.szTip, 128, s.str().c_str());
Shell_NotifyIcon(NIM_MODIFY, &notifyIconData);

// update last-seen color to new value
lastColor = curColor;
}
UpdateColor(ColorUtil::Dword2ColorRef(wParam));
}
return 0;

if (wParam == IDT_TIMER_INIT)
{
// this is the initial one-shot timer
// kill it and start the regular timer
KillTimer(hwnd, IDT_TIMER_INIT);
SetTimer(hwnd, IDT_TIMER, 1000, (TIMERPROC)NULL);
}
// session status changed (e.g. lock/unlock)
case WM_WTSSESSION_CHANGE:
{
GetAndUpdateColor();
}
return 0;
}
Expand All @@ -131,6 +177,9 @@ int WINAPI WinMain(HINSTANCE hThisInstance,
LPSTR lpszArgument,
int nCmdShow)
{
// RedirectIOToConsole();
// std::cout << "TEST" << std::endl;

// register for taskbar re-create events so that icon can be restored after an explorer restart
WM_TASKBARCREATED = RegisterWindowMessageA("TaskbarCreated");

Expand Down Expand Up @@ -170,6 +219,8 @@ int WINAPI WinMain(HINSTANCE hThisInstance,
NULL
));

WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_ALL_SESSIONS);

// initialize tray icon data structure
memset(&notifyIconData, 0, sizeof(NOTIFYICONDATA));
notifyIconData.cbSize = sizeof(NOTIFYICONDATA);
Expand All @@ -183,11 +234,8 @@ int WINAPI WinMain(HINSTANCE hThisInstance,
// add the tray icon to the system tray
Shell_NotifyIcon(NIM_ADD, &notifyIconData);

// kick off an immediate one-shot timer to seed color processing
SetTimer(hwnd, // handle to main window
IDT_TIMER_INIT, // timer identifier
0, // interval in milliseconds
(TIMERPROC)NULL); // no timer callback (WindowProcedure() will be invoked)
// perform initial LED color sync
GetAndUpdateColor();

// Run the UI message loop. It will run until GetMessage() returns 0
MSG messages;
Expand All @@ -198,6 +246,8 @@ int WINAPI WinMain(HINSTANCE hThisInstance,
DispatchMessage(&messages); // Send message to WindowProcedure
}

// std::cout << "TEST2" << std::endl;

// we're done - clean up UI elements
Shell_NotifyIcon(NIM_DELETE, &notifyIconData);
DestroyWindow(hwnd);
Expand Down
4 changes: 2 additions & 2 deletions UniLight/UniLight.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dwmapi.lib;LogitechLEDLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dwmapi.lib;Wtsapi32.lib;LogitechLEDLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand Down Expand Up @@ -143,7 +143,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dwmapi.lib;LogitechLEDLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dwmapi.lib;Wtsapi32.lib;LogitechLEDLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand Down

0 comments on commit 8eeb970

Please sign in to comment.