Compare commits

..

No commits in common. "4eae4af91149ebf955be415067ff181c17e5044a" and "5654677a580d3c11d13fb10b9fccdd75e719670c" have entirely different histories.

12 changed files with 0 additions and 571 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
.vs/
build/
*.aps

View File

@ -1,6 +0,0 @@
# Watchful Eye project CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(watchful-eye)
add_subdirectory(WatchfulEye)

View File

@ -1,49 +0,0 @@
// Watchful Eye CMake presets
{
"version": 3,
"configurePresets": [
{
"name": "base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
}
},
{
"name": "Debug",
"inherits": "base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "Release",
"inherits": "base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
{
"name": "Debug",
"configurePreset": "Debug"
},
{
"name": "Release",
"configurePreset": "Release"
}
]
}

View File

@ -1,17 +0,0 @@
# Watchful Eye app CMakeLists.txt
add_executable(WatchfulEye WIN32 "src/main.cpp" "src/pch.h" "src/Application.h" "src/Application.cpp" "resource.rc" "src/resource.h")
set_property(TARGET WatchfulEye PROPERTY CXX_STANDARD 20)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /entry:mainCRTStartup")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set_property(TARGET WatchfulEye PROPERTY WIN32_EXECUTABLE FALSE)
endif()
target_precompile_headers(WatchfulEye PUBLIC "src/pch.h")
find_package(Git)
execute_process(COMMAND ${GIT_EXECUTABLE} describe OUTPUT_VARIABLE APPVERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
configure_file(src/version.h.in version.h)
target_include_directories(WatchfulEye PUBLIC "${PROJECT_BINARY_DIR}/WatchfulEye")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

View File

@ -1,151 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "src/resource.h"
#include "version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <winres.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"src/resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include <winres.h>\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOGMAIN DIALOGEX 0, 0, 300, 114
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 "Lower",IDC_STATICLOWER,7,85,286,22,SS_CENTERIMAGE,WS_EX_TRANSPARENT
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOGMAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 293
TOPMARGIN, 7
BOTTOMMARGIN, 107
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_DIALOGMAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x0L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Grayson Riffe"
VALUE "FileDescription", "Watchful Eye"
VALUE "InternalName", "WatchfulEye"
VALUE "LegalCopyright", "Copyright (C) 2026"
VALUE "OriginalFilename", "WatchfulEye.exe"
VALUE "ProductName", "Watchful Eye"
VALUE "ProductVersion", APPVERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICONMAIN ICON "res\\watchful-eye.ico"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -1,253 +0,0 @@
// Application class implementation
#include "pch.h"
#include "Application.h"
#include "resource.h"
#define WM_TRAYICON WM_USER // Tray icon window message
#define IDM_ABOUT 1001 // "About" menu identifier
#define IDM_EXIT 1002 // "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, unsigned int maximumMinutes, const char* driveToDetect)
: m_appName(appName)
, m_appVersion(appVersion)
, m_mainDlg(nullptr)
, m_running(true)
, m_active(false)
, m_overTime(false)
, m_maxMinutes(maximumMinutes)
, m_drive(driveToDetect)
, m_startTime()
{
std::cout << std::format("{} {}\n", m_appName, m_appVersion);
}
void Application::run() {
// Create dialog
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
m_mainDlg = CreateDialogParam(nullptr, MAKEINTRESOURCE(IDD_DIALOGMAIN), nullptr, reinterpret_cast<DLGPROC>(mainDlgProc), reinterpret_cast<LPARAM>(this));
// Create tray icon
createTrayIcon();
// Create drive query thread
std::thread queryThread(&Application::queryThreadFunction, this);
ShowWindow(m_mainDlg, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0))
IsDialogMessage(m_mainDlg, &msg);
m_running = false;
queryThread.join();
}
BOOL CALLBACK Application::mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) {
static Application* app = nullptr;
static UINT taskbarCreatedMessage = 0;
static HFONT timeFont = nullptr;
static HBRUSH greenBackgroundBrush = CreateSolidBrush(RGB(150, 255, 150));
static HBRUSH yellowBackgroundBrush = CreateSolidBrush(RGB(255, 255, 150));
static HBRUSH redBackgroundBrush = CreateSolidBrush(RGB(255, 150, 150));
switch (msg) {
case WM_INITDIALOG: {
app = reinterpret_cast<Application*>(lParam);
SetWindowText(dlg, app->m_appName.c_str());
// Spawn in the lower right corner of the virtual screen (might be problematic in some cases)
int cornerX = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN);
int cornerY = GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN);
SetWindowPos(dlg, nullptr, cornerX - 550, cornerY - 540, NULL, NULL, SWP_NOZORDER | SWP_NOSIZE);
taskbarCreatedMessage = RegisterWindowMessage("TaskbarCreated");
// Set up UI
LOGFONT lFont = {};
strcpy(lFont.lfFaceName, "Consolas");
lFont.lfHeight = 35;
HFONT upperFont = CreateFontIndirect(&lFont);
SendMessage(GetDlgItem(dlg, IDC_STATICLOWER), WM_SETFONT, reinterpret_cast<WPARAM>(upperFont), NULL);
lFont.lfHeight = 180;
lFont.lfWeight = FW_BOLD;
timeFont = CreateFontIndirect(&lFont);
SendMessage(dlg, WM_UPDATE, NULL, NULL);
SetTimer(dlg, IDT_UPDATE, 1000, nullptr);
return TRUE;
}
case WM_TRAYICON: {
if (LOWORD(lParam) == WM_LBUTTONDOWN ||
LOWORD(lParam) == WM_RBUTTONDOWN) {
SetForegroundWindow(dlg);
POINT cursor = {};
GetCursorPos(&cursor);
HMENU popupMenu = CreatePopupMenu();
AppendMenu(popupMenu, MF_STRING, IDM_ABOUT, "About");
AppendMenu(popupMenu, MF_STRING, IDM_EXIT, "Exit");
TrackPopupMenu(popupMenu, NULL, cursor.x, cursor.y, NULL, dlg, nullptr); // Will block here. Might be problematic.
DestroyMenu(popupMenu);
}
return TRUE;
}
case WM_COMMAND: {
if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_ABOUT)
MessageBox(dlg, std::format("{} {}\nCopyright Grayson Riffe 2026\ngraysonriffe.com\n\n"
"\t{} is a simple countdown application\n"
"specifically designed for this electronics testing labratory.\n\n"
"Hopefully, it's working!", app->m_appName, app->m_appVersion,
app->m_appName).c_str(), std::format("About {}", app->m_appName).c_str(), MB_OK);
else if (HIWORD(wParam) == 0 && LOWORD(wParam) == IDM_EXIT)
DestroyWindow(dlg);
return TRUE;
}
case WM_ERASEBKGND: {
HDC hDC = reinterpret_cast<HDC>(wParam);
RECT clientRect = {};
GetClientRect(dlg, &clientRect);
HBRUSH backgroundBrush = nullptr;
if (!app->m_active)
backgroundBrush = greenBackgroundBrush;
else if (app->m_overTime)
backgroundBrush = redBackgroundBrush;
else
backgroundBrush = yellowBackgroundBrush;
FillRect(hDC, &clientRect, backgroundBrush);
return TRUE;
}
case WM_CTLCOLORSTATIC: {
if (GetWindowLongPtr(reinterpret_cast<HWND>(lParam), GWL_EXSTYLE) & WS_EX_TRANSPARENT) {
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 -= 25, timeRect.bottom -= 25;
SetTextColor(hDC, RGB(0, 0, 0));
SetBkMode(hDC, TRANSPARENT);
SelectObject(hDC, timeFont);
Seconds elapsed = Duration(Clock::now() - app->m_startTime).count();
if (!app->m_active)
elapsed = 0;
Seconds remaining = app->m_maxMinutes * 60 - elapsed;
if (app->m_overTime) {
SetDlgItemText(dlg, IDC_STATICLOWER, "Please Eject Your USB");
DrawText(hDC, "STOP", -1, &timeRect, DT_SINGLELINE | DT_NOCLIP | DT_CENTER | DT_VCENTER);
}
else {
SetDlgItemText(dlg, IDC_STATICLOWER, "Time Remaining on Tester");
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);
}
if (remaining <= 0)
app->m_overTime = true;
EndPaint(dlg, &ps);
return TRUE;
}
case WM_CLOSE: {
// Do nothing
return TRUE;
}
case WM_DESTROY: {
PostQuitMessage(0);
return TRUE;
}
}
if (msg == taskbarCreatedMessage)
app->createTrayIcon();
return FALSE;
}
void Application::createTrayIcon() {
NOTIFYICONDATA iconData = {};
iconData.cbSize = sizeof(iconData);
iconData.uVersion = NOTIFYICON_VERSION_4;
iconData.hWnd = m_mainDlg;
iconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
iconData.uCallbackMessage = WM_TRAYICON;
iconData.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICONMAIN));
strcpy(iconData.szTip, m_appName.c_str());
Shell_NotifyIcon(NIM_ADD, &iconData);
}
void Application::queryThreadFunction() {
char buff[100] = {};
while (m_running) {
bool driveDetected = QueryDosDevice(m_drive, buff, 100) > 0;
if (driveDetected && !m_active) {
m_active = true;
m_startTime = Clock::now();
}
else if (!driveDetected && m_active) {
m_active = false;
m_overTime = false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
}

View File

@ -1,33 +0,0 @@
// Application class header
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, unsigned int maximumMinutes, const char* driveToDetect);
void run();
private:
static BOOL CALLBACK mainDlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam);
void createTrayIcon();
void queryThreadFunction();
std::string m_appName, m_appVersion;
HWND m_mainDlg;
bool m_running; // Is the application running?
bool m_active; // Is the timer ticking?
bool m_overTime; // Are we out of time?
unsigned int m_maxMinutes;
const char* m_drive;
TimePoint m_startTime;
};
}

View File

@ -1,26 +0,0 @@
// Watchful Eye main file
#include "pch.h"
#include "version.h"
#include "Application.h"
// Enable visual styles
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define APPNAME "Watchful Eye"
// ======== Configuration ========
#define MAX_MINUTES 15
#define DRIVE_TO_DETECT "D:"
// ===============================
int main(int argc, char* argv[]) {
{
watchfuleye::Application app(APPNAME, APPVERSION, MAX_MINUTES, DRIVE_TO_DETECT);
app.run();
}
return EXIT_SUCCESS;
}

View File

@ -1,13 +0,0 @@
// Watchful Eye precompiled header
// STD
#include <iostream>
#include <string>
#include <format>
#include <chrono>
#include <thread>
// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shellapi.h>

View File

@ -1,18 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by C:\Users\Grayson\Documents\Visual Studio 18\Solutions\watchful-eye\WatchfulEye\resource.rc
//
#define IDD_DIALOGMAIN 101
#define IDI_ICONMAIN 103
#define IDC_STATICLOWER 1000
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,2 +0,0 @@
// Version configured header file
#define APPVERSION "@APPVERSION@"