Compare commits
11 Commits
5654677a58
...
4eae4af911
| Author | SHA1 | Date | |
|---|---|---|---|
| 4eae4af911 | |||
| 89c76d0a9c | |||
| 081eb00a46 | |||
| 8d070ca5f4 | |||
| cf310dc71c | |||
| 2d6a972e85 | |||
| 35b0d02af5 | |||
| 1d3e58587d | |||
| fdbe1a07bb | |||
| 3977d85fee | |||
| 97727d05d4 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.vs/
|
||||||
|
build/
|
||||||
|
*.aps
|
||||||
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Watchful Eye project CMakeLists.txt
|
||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
|
project(watchful-eye)
|
||||||
|
|
||||||
|
add_subdirectory(WatchfulEye)
|
||||||
49
CMakePresets.json
Normal file
49
CMakePresets.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
17
WatchfulEye/CMakeLists.txt
Normal file
17
WatchfulEye/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# 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")
|
||||||
BIN
WatchfulEye/res/watchful-eye.ico
Normal file
BIN
WatchfulEye/res/watchful-eye.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
151
WatchfulEye/resource.rc
Normal file
151
WatchfulEye/resource.rc
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
253
WatchfulEye/src/Application.cpp
Normal file
253
WatchfulEye/src/Application.cpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
// 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
WatchfulEye/src/Application.h
Normal file
33
WatchfulEye/src/Application.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
26
WatchfulEye/src/main.cpp
Normal file
26
WatchfulEye/src/main.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
||||||
13
WatchfulEye/src/pch.h
Normal file
13
WatchfulEye/src/pch.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// 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>
|
||||||
18
WatchfulEye/src/resource.h
Normal file
18
WatchfulEye/src/resource.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//{{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
|
||||||
2
WatchfulEye/src/version.h.in
Normal file
2
WatchfulEye/src/version.h.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// Version configured header file
|
||||||
|
#define APPVERSION "@APPVERSION@"
|
||||||
Loading…
x
Reference in New Issue
Block a user