Add countdown and fix flicker

This commit is contained in:
Grayson Riffe 2026-06-04 22:39:08 -05:00
parent cf310dc71c
commit 8d070ca5f4
Signed by: grayson
SSH Key Fingerprint: SHA256:23HJg9tnL2m6u0uUb26QIrOTFymFZ+xgSH/2UPEBB/I
5 changed files with 67 additions and 20 deletions

View File

@ -49,13 +49,12 @@ END
//
IDD_DIALOGMAIN DIALOGEX 0, 0, 300, 114
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOPMOST
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CTEXT "00:00",IDC_STATICTIME,17,35,266,60,SS_CENTERIMAGE,WS_EX_TRANSPARENT
CTEXT "Time left on tester:",IDC_STATICUPPER,7,4,286,22,SS_CENTERIMAGE,WS_EX_TRANSPARENT
CTEXT "Time Remaining on Tester",IDC_STATICUPPER,7,4,286,22,SS_CENTERIMAGE,WS_EX_TRANSPARENT
END

View File

@ -5,19 +5,25 @@
#include "resource.h"
#define WM_TRAYICON WM_USER
#define IDM_EXIT 1001
#define WM_TRAYICON WM_USER // Tray icon window message
#define IDM_EXIT 1001 // "Exit" menu identifier
#define IDT_UPDATE 1 // Update timer identifier
#define WM_UPDATE WM_USER + 1 // Update window message
namespace watchfuleye {
Application::Application(const char* appName, const char* appVersion)
Application::Application(const char* appName, const char* appVersion, unsigned int maximumMinutes)
: m_appName(appName)
, m_appVersion(appVersion)
, m_mainDlg(nullptr)
, m_maxMinutes(maximumMinutes)
, m_startTime()
{
std::cout << std::format("{} {}\n", m_appName, m_appVersion);
}
void Application::run() {
m_startTime = Clock::now();
// Create dialog
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
@ -36,6 +42,8 @@ namespace watchfuleye {
BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) {
static Application* app = nullptr;
static UINT taskbarCreatedMessage = 0;
static HBRUSH backgroundBrush = CreateSolidBrush(RGB(255, 150, 150));
static HFONT timeFont = nullptr;
switch (msg) {
case WM_INITDIALOG: {
@ -54,14 +62,16 @@ namespace watchfuleye {
// Set up UI
LOGFONT lFont = {};
strcpy(lFont.lfFaceName, "Consolas");
lFont.lfHeight = 50;
lFont.lfHeight = 45;
HFONT upperFont = CreateFontIndirect(&lFont);
SendMessage(GetDlgItem(dlg, IDC_STATICUPPER), WM_SETFONT, reinterpret_cast<WPARAM>(upperFont), NULL);
lFont.lfHeight = 200;
HFONT timeFont = CreateFontIndirect(&lFont);
SendMessage(GetDlgItem(dlg, IDC_STATICTIME), WM_SETFONT, reinterpret_cast<WPARAM>(timeFont), NULL);
lFont.lfWeight = FW_BOLD;
timeFont = CreateFontIndirect(&lFont);
SendMessage(dlg, WM_UPDATE, NULL, NULL);
SetTimer(dlg, IDT_UPDATE, 1000, nullptr);
return TRUE;
}
@ -94,28 +104,59 @@ namespace watchfuleye {
case WM_ERASEBKGND: {
HDC hDC = reinterpret_cast<HDC>(wParam);
HBRUSH backgroundBrush = CreateSolidBrush(RGB(255, 150, 150));
RECT clientRect = {};
GetClientRect(dlg, &clientRect);
FillRect(hDC, &clientRect, backgroundBrush);
DeleteObject(backgroundBrush);
return TRUE;
}
case WM_CTLCOLORSTATIC: {
if (GetWindowLongPtr(reinterpret_cast<HWND>(lParam), GWL_EXSTYLE) & WS_EX_TRANSPARENT) {
std::cout << "Test\n";
SetBkMode(reinterpret_cast<HDC>(wParam), TRANSPARENT);
return reinterpret_cast<INT_PTR>(GetStockObject(NULL_BRUSH));
}
return FALSE;
}
case WM_TIMER: {
if (wParam == IDT_UPDATE) {
SendMessage(dlg, WM_UPDATE, NULL, NULL);
return TRUE;
}
return FALSE;
}
case WM_UPDATE: {
InvalidateRect(dlg, nullptr, TRUE);
UpdateWindow(dlg);
return TRUE;
}
case WM_PAINT: {
PAINTSTRUCT ps = {};
HDC hDC = BeginPaint(dlg, &ps);
RECT timeRect = {};
GetClientRect(dlg, &timeRect);
timeRect.top += 15, timeRect.bottom += 15;
SetTextColor(hDC, RGB(0, 0, 0));
SetBkMode(hDC, TRANSPARENT);
SelectObject(hDC, timeFont);
Seconds elapsed = Duration(Clock::now() - app->m_startTime).count();
Seconds remaining = app->m_maxMinutes * 60 - elapsed;
unsigned int minutes = remaining % (3600) / 60, seconds = remaining % 60;
DrawText(hDC, std::format("{:02}:{:02}", minutes, seconds).c_str(), -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
EndPaint(dlg, &ps);
return TRUE;
}
case WM_CLOSE: {
// Do nothing
return TRUE;

View File

@ -2,8 +2,13 @@
namespace watchfuleye {
class Application {
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::time_point<Clock>;
using Duration = std::chrono::duration<double, std::ratio<1, 1>>;
using Seconds = int;
public:
Application(const char* appName, const char* appVersion);
Application(const char* appName, const char* appVersion, unsigned int maximumMinutes);
void run();
@ -15,5 +20,8 @@ namespace watchfuleye {
std::string m_appName, m_appVersion;
HWND m_mainDlg;
unsigned int m_maxMinutes;
TimePoint m_startTime;
};
}

View File

@ -13,7 +13,7 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
int main(int argc, char* argv[]) {
{
watchfuleye::Application app(APPNAME, APPVERSION);
watchfuleye::Application app(APPNAME, APPVERSION, 15);
app.run();
}

View File

@ -3,8 +3,7 @@
// Used by C:\Users\Grayson\Documents\Visual Studio 18\Solutions\watchful-eye\WatchfulEye\resource.rc
//
#define IDD_DIALOGMAIN 101
#define IDC_STATICTIME 1000
#define IDC_STATICUPPER 1001
#define IDC_STATICUPPER 1000
// Next default values for new objects
//