Display a warning when there is no battery detected

This commit is contained in:
2025-08-09 14:29:12 -04:00
parent 6a586dedb7
commit 036a20df3f
2 changed files with 20 additions and 10 deletions

View File

@ -11,6 +11,6 @@ This is a simple C program written using Visual Studio 2022 that has no external
- [ ] Add a checkbox to preferences for starting at login. - [ ] Add a checkbox to preferences for starting at login.
- [ ] Add an icon. - [ ] Add an icon.
- [ ] Add behavior for when multiple displays are connected. - [ ] Add behavior for when multiple displays are connected.
- [ ] Block program from running when the system has no battery. - [x] Warn the user when the system has no battery.
- [x] Make the default display mode the current one instead of the highest resolution if there are no preferences set. - [x] Make the default display mode the current one instead of the highest resolution if there are no preferences set.
- [ ] Make an actual about dialog. - [ ] Make an actual about dialog.

View File

@ -125,6 +125,8 @@ static void TestDisplayMode(HWND hDlg, DISPLAY_MODE* mode) {
typedef struct { typedef struct {
DISPLAY_MODE modeBatt; DISPLAY_MODE modeBatt;
DISPLAY_MODE modeAC; DISPLAY_MODE modeAC;
DWORD disableBatteryWarning; // not used yet
BOOL runAtStartup; // not used yet
} WINPOWERDMS_PREFS; } WINPOWERDMS_PREFS;
static WINPOWERDMS_PREFS userPrefs = { 0 }; static WINPOWERDMS_PREFS userPrefs = { 0 };
@ -142,6 +144,7 @@ static BOOL SavePrefs(void) {
RegSetKeyValue(regKey, L"AC Power", L"Width", REG_DWORD, &userPrefs.modeAC.width, sizeof(userPrefs.modeAC.width)); RegSetKeyValue(regKey, L"AC Power", L"Width", REG_DWORD, &userPrefs.modeAC.width, sizeof(userPrefs.modeAC.width));
RegSetKeyValue(regKey, L"AC Power", L"Height", REG_DWORD, &userPrefs.modeAC.height, sizeof(userPrefs.modeAC.height)); 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)); 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; return TRUE;
} }
else return FALSE; else return FALSE;
@ -151,18 +154,20 @@ static BOOL SavePrefs(void) {
static BOOL LoadPrefs(void) { static BOOL LoadPrefs(void) {
HKEY regKey; HKEY regKey;
if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\WinPowerDMS", 0, KEY_READ, &regKey)) { if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\WinPowerDMS", 0, KEY_READ, &regKey)) {
DWORD keySize = sizeof(DWORD); DWORD keySize = sizeof(userPrefs.modeBatt.width);
RegGetValue(regKey, L"Battery", L"Width", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.width, &keySize); RegGetValue(regKey, L"Battery", L"Width", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.width, &keySize);
keySize = sizeof(DWORD); keySize = sizeof(userPrefs.modeBatt.height);
RegGetValue(regKey, L"Battery", L"Height", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.height, &keySize); RegGetValue(regKey, L"Battery", L"Height", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.height, &keySize);
keySize = sizeof(DWORD); keySize = sizeof(userPrefs.modeBatt.refresh);
RegGetValue(regKey, L"Battery", L"Refresh Rate", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.refresh, &keySize); RegGetValue(regKey, L"Battery", L"Refresh Rate", RRF_RT_REG_DWORD, NULL, &userPrefs.modeBatt.refresh, &keySize);
keySize = sizeof(DWORD); keySize = sizeof(userPrefs.modeAC.width);
RegGetValue(regKey, L"AC Power", L"Width", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.width, &keySize); RegGetValue(regKey, L"AC Power", L"Width", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.width, &keySize);
keySize = sizeof(DWORD); keySize = sizeof(userPrefs.modeAC.height);
RegGetValue(regKey, L"AC Power", L"Height", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.height, &keySize); RegGetValue(regKey, L"AC Power", L"Height", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.height, &keySize);
keySize = sizeof(DWORD); keySize = sizeof(userPrefs.modeAC.refresh);
RegGetValue(regKey, L"AC Power", L"Refresh Rate", RRF_RT_REG_DWORD, NULL, &userPrefs.modeAC.refresh, &keySize); 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; return TRUE;
} }
else return FALSE; else return FALSE;
@ -278,7 +283,7 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_PREFSDIALOG), hWnd, PrefsDialogProc); DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_PREFSDIALOG), hWnd, PrefsDialogProc);
break; break;
case ID_TRAY_ABOUT: case ID_TRAY_ABOUT:
MessageBoxW(NULL, L"WinPowerDMS\nA utility for switching the resolution of your laptop's display based on the current power state.", L"About", MB_OK | MB_ICONINFORMATION); MessageBoxW(hWnd, L"WinPowerDMS\nA utility for switching the resolution of your laptop's display based on the current power state.", L"About", MB_OK | MB_ICONINFORMATION);
break; break;
case ID_TRAY_EXIT: case ID_TRAY_EXIT:
DestroyWindow(hWnd); DestroyWindow(hWnd);
@ -296,8 +301,8 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
OutputDebugString(L"Power status changed\n"); OutputDebugString(L"Power status changed\n");
DISPLAY_MODE currentMode = GetCurrentDisplayMode(); DISPLAY_MODE currentMode = GetCurrentDisplayMode();
SYSTEM_POWER_STATUS powerStatus; SYSTEM_POWER_STATUS powerStatus;
// Change display mode only if there is a battery present and the current display mode is one of the configured options. // Change display mode only if the current display mode is one of the configured options.
if (GetSystemPowerStatus(&powerStatus) && powerStatus.BatteryFlag != 128 && if (GetSystemPowerStatus(&powerStatus) &&
(DisplayModeEquals(&currentMode, &userPrefs.modeBatt) || DisplayModeEquals(&currentMode, &userPrefs.modeAC))) (DisplayModeEquals(&currentMode, &userPrefs.modeBatt) || DisplayModeEquals(&currentMode, &userPrefs.modeAC)))
{ {
ChangeDisplayMode(powerStatus.ACLineStatus ? &userPrefs.modeAC : &userPrefs.modeBatt, CDS_UPDATEREGISTRY); ChangeDisplayMode(powerStatus.ACLineStatus ? &userPrefs.modeAC : &userPrefs.modeBatt, CDS_UPDATEREGISTRY);
@ -327,6 +332,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
HWND hWnd = CreateWindowEx(0, L"TrayAppClass", NULL, 0, 0, 0, 0, 0, HWND hWnd = CreateWindowEx(0, L"TrayAppClass", NULL, 0, 0, 0, 0, 0,
HWND_MESSAGE, NULL, hInstance, NULL); HWND_MESSAGE, NULL, hInstance, NULL);
RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE); RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE);
// Check if there is a battery in the system and display a warning message if there isn't one.
SYSTEM_POWER_STATUS powerStatus;
if (!userPrefs.disableBatteryWarning && GetSystemPowerStatus(&powerStatus) && powerStatus.BatteryFlag == 128)
MessageBox(hWnd, L"There is no battery present in the system. The program will start and set your display mode to what you have set for AC power, but do nothing else afterwards.", L"WinPowerDMS", MB_OK | MB_ICONWARNING);
// Create context menu // Create context menu
hMenu = CreatePopupMenu(); hMenu = CreatePopupMenu();