From 350e2960b8d59e41ddb562d01ec6409f5f83ad59 Mon Sep 17 00:00:00 2001 From: Mina Brown Date: Sat, 9 Aug 2025 16:03:40 -0400 Subject: [PATCH] Add functionality for running at startup and disabling the battery warning --- README.md | 2 +- WinPowerDMS/WinPowerDMS.c | 57 +++++++++++++++++++++++++++---------- WinPowerDMS/WinPowerDMS.rc | Bin 5516 -> 6122 bytes WinPowerDMS/resource.h | 6 ++-- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e98f605..26e9ae1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a simple C program written using Visual Studio 2022 that has no external ## TODO - [x] Save preferences to the Windows registry. -- [ ] Add a checkbox to preferences for starting at login. +- [x] Add a checkbox to preferences for starting at login. - [ ] Add an icon. - [ ] Add behavior for when multiple displays are connected. - [x] Warn the user when the system has no battery. diff --git a/WinPowerDMS/WinPowerDMS.c b/WinPowerDMS/WinPowerDMS.c index 7e9961f..e13472b 100644 --- a/WinPowerDMS/WinPowerDMS.c +++ b/WinPowerDMS/WinPowerDMS.c @@ -26,9 +26,8 @@ BOOL DisplayModeEquals(const DISPLAY_MODE* a, const DISPLAY_MODE* b) { #define MODE_SELECTED(mode) (!DisplayModeEquals(&mode, &(DISPLAY_MODE) { 0 })) // I hate parsing the string here, but the alternative requires extra memory management. -static DISPLAY_MODE GetModeFromCB(HWND hDlg, int nIDDlgItem) { +static DISPLAY_MODE GetModeFromCB(HWND hComboBox) { DISPLAY_MODE mode = { 0 }; - HWND hComboBox = GetDlgItem(hDlg, nIDDlgItem); size_t selectedIndex = SendMessage(hComboBox, CB_GETCURSEL, 0, 0); if (selectedIndex != CB_ERR) { LRESULT len = SendMessage(hComboBox, CB_GETLBTEXTLEN, selectedIndex, 0); @@ -125,14 +124,16 @@ static void TestDisplayMode(HWND hDlg, DISPLAY_MODE* mode) { typedef struct { DISPLAY_MODE modeBatt; DISPLAY_MODE modeAC; - DWORD disableBatteryWarning; // not used yet - BOOL runAtStartup; // not used yet + DWORD disableBatteryWarning; + BOOL runAtStartup; } WINPOWERDMS_PREFS; static WINPOWERDMS_PREFS userPrefs = { 0 }; // Save user preferences to registry. static BOOL SavePrefs(void) { + BOOL saved = FALSE; + HKEY regKey; if (!RegCreateKeyEx( HKEY_CURRENT_USER, L"SOFTWARE\\WinPowerDMS", 0, NULL, @@ -145,13 +146,26 @@ static BOOL SavePrefs(void) { RegSetKeyValue(regKey, L"AC Power", L"Height", REG_DWORD, &userPrefs.modeAC.height, sizeof(userPrefs.modeAC.height)); RegSetKeyValue(regKey, L"AC Power", L"Refresh Rate", REG_DWORD, &userPrefs.modeAC.refresh, sizeof(userPrefs.modeAC.refresh)); RegSetValueEx(regKey, L"Disable Battery Warning", 0, REG_DWORD, &userPrefs.disableBatteryWarning, sizeof(userPrefs.disableBatteryWarning)); - return TRUE; + RegCloseKey(regKey); + saved = TRUE; } - else return FALSE; + + // Create the startup entry + if (userPrefs.runAtStartup) { + WCHAR exePath[MAX_PATH]; + DWORD exePathLen = GetModuleFileName(NULL, exePath, sizeof(exePath) / sizeof(exePath[0])) + 1; + RegSetKeyValue(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", L"WinPowerDMS", REG_SZ, exePath, exePathLen); + } + else { // Delete the startup entry + RegDeleteKeyValue(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", L"WinPowerDMS"); + } + return saved; } // Load user preferences from registry. static BOOL LoadPrefs(void) { + BOOL loaded = FALSE; + HKEY regKey; if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\WinPowerDMS", 0, KEY_READ, ®Key)) { DWORD keySize = sizeof(userPrefs.modeBatt.width); @@ -168,9 +182,15 @@ static BOOL LoadPrefs(void) { RegGetValue(regKey, L"AC Power", L"Refresh Rate", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.refresh, &keySize); keySize = sizeof(userPrefs.disableBatteryWarning); RegGetValue(regKey, NULL, L"Disable Battery Warning", RRF_RT_REG_DWORD, NULL, &userPrefs.disableBatteryWarning, &keySize); - return TRUE; + RegCloseKey(regKey); + loaded = TRUE; } - else return FALSE; + + // Figure out if application has a startup entry + if (!RegGetValue(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", L"WinPowerDMS", RRF_RT_ANY, NULL, NULL, NULL)) + userPrefs.runAtStartup = TRUE; + + return loaded; } static DISPLAY_MODE GetCurrentDisplayMode(void) { @@ -184,11 +204,13 @@ static DISPLAY_MODE GetCurrentDisplayMode(void) { } static INT_PTR CALLBACK PrefsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hComboBatt = GetDlgItem(hDlg, IDC_COMBO_BATT); + HWND hComboAC = GetDlgItem(hDlg, IDC_COMBO_AC); + HWND hCheckBattWarning = GetDlgItem(hDlg, IDC_CHECK_BATT_WARNING); + HWND hCheckStartup = GetDlgItem(hCheckBattWarning, IDC_CHECK_STARTUP); + switch (message) { case WM_INITDIALOG: { - HWND hComboBatt = GetDlgItem(hDlg, IDC_COMBO_BATT); - HWND hComboAC = GetDlgItem(hDlg, IDC_COMBO_AC); - // devMode object that will be enumerated DEVMODE devMode; ZeroMemory(&devMode, sizeof(devMode)); @@ -223,6 +245,9 @@ static INT_PTR CALLBACK PrefsDialogProc(HWND hDlg, UINT message, WPARAM wParam, lastMode = currentMode; } } + + SendMessage(hCheckBattWarning, BM_SETCHECK, userPrefs.disableBatteryWarning ? BST_CHECKED : BST_UNCHECKED, 0); + SendMessage(hCheckStartup, BM_SETCHECK, userPrefs.runAtStartup ? BST_CHECKED : BST_UNCHECKED, 0); return TRUE; } @@ -230,8 +255,10 @@ static INT_PTR CALLBACK PrefsDialogProc(HWND hDlg, UINT message, WPARAM wParam, switch (LOWORD(wParam)) { case IDC_BUTTON_APPLY: case IDOK: { - userPrefs.modeBatt = GetModeFromCB(hDlg, IDC_COMBO_BATT); - userPrefs.modeAC = GetModeFromCB(hDlg, IDC_COMBO_AC); + userPrefs.modeBatt = GetModeFromCB(hComboBatt); + userPrefs.modeAC = GetModeFromCB(hComboAC); + userPrefs.disableBatteryWarning = SendMessage(hCheckBattWarning, BM_GETCHECK, 0, 0) == BST_CHECKED; + userPrefs.runAtStartup = SendMessage(hCheckStartup, BM_GETCHECK, 0, 0) == BST_CHECKED; SavePrefs(); if (LOWORD(wParam) == IDC_BUTTON_APPLY) return TRUE; } @@ -240,12 +267,12 @@ static INT_PTR CALLBACK PrefsDialogProc(HWND hDlg, UINT message, WPARAM wParam, return TRUE; } case IDC_BUTTON_TEST_BATT: { - DISPLAY_MODE mode = GetModeFromCB(hDlg, IDC_COMBO_BATT); + DISPLAY_MODE mode = GetModeFromCB(hComboBatt); TestDisplayMode(hDlg, &mode); return TRUE; } case IDC_BUTTON_TEST_AC: { - DISPLAY_MODE mode = GetModeFromCB(hDlg, IDC_COMBO_AC); + DISPLAY_MODE mode = GetModeFromCB(hComboAC); TestDisplayMode(hDlg, &mode); return TRUE; } diff --git a/WinPowerDMS/WinPowerDMS.rc b/WinPowerDMS/WinPowerDMS.rc index 67606d69a225fcc20c9a1cc28e56ca313951a81e..7eb1a13fa611bcb610a601205144e518e06b057d 100644 GIT binary patch delta 626 zcmb7CO-lk%6g{PcjZPThBH9dYA~JHq)MycoN?)d86B-esASJ~psYM`2+XxEYy5Eps zEn4?uf;Rny&U;z3s6{;9d-tBXbI&<<=4SqFvETK$R$z*r=iwlY5_Vx@9~q=!pvbJu zsKhgYJXaB$$RdRtBOMx&3b%>oh#LqJuft(w0~e^_jI}%LVu-czCszz%ai~oTzqU1u zUtA{QBH?R@b1f(yz1PG1b!17*>9;(e_14#WdQ!32DDcjRD{ZP5WdAx^sGy2d@)=~U zkkwHtj#Pe3++kGZlQx%Bb;(@5=U|qIfhMsUb6MG@ix3^9=&sDY!3iX>&Df$_o2yKh z3988Y)Hv2z&S6kcK-_6#-@EU1FIea((gqvLww4-c0()$e`_bHDRuU)P88d_!>mrEr zG!aEu-C;FugHq-CZ4d=ANt@E7K`U)Fh&IvYpN8bemPTyq$&)8YegDu)o-Q|k6VdTb c20oQ9E9Fr-kov=e)rs<`D~`zE-v93Y0Q?_uWdHyG delta 136 zcmaE*-=n>uhJ)Fh!EACp$9h3$21kYfh7bl%27d-W1_cJC$(@{AnN1l?Cp&T_Lutv$ z2e?)-8!;Ge&gGV71TiM(a_3L(;mr_q0%{KdLLCNkAT|bSE9UKIG@Z=MSIiGI1Sn?8 ZU;rcy8B8|M6o_YHHe;~d{9EWf3jn4PA5s7S diff --git a/WinPowerDMS/resource.h b/WinPowerDMS/resource.h index 4a437cb..8fbc1eb 100644 --- a/WinPowerDMS/resource.h +++ b/WinPowerDMS/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by PowerDMS.rc +// Used by WinPowerDMS.rc // #define IDD_PREFSDIALOG 101 #define IDC_COMBO_BATT 1001 @@ -9,6 +9,8 @@ #define IDC_BUTTON_TEST_AC 1004 #define IDC_BUTTON_APPLY 1005 #define IDC_LIST1 1006 +#define IDC_CHECK_BATT_WARNING 1007 +#define IDC_CHECK_STARTUP 1008 // Next default values for new objects // @@ -16,7 +18,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1007 +#define _APS_NEXT_CONTROL_VALUE 1008 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif