1013 lines
35 KiB
C
1013 lines
35 KiB
C
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1996
|
|
*
|
|
* TITLE: ALARM.C
|
|
*
|
|
* VERSION: 2.0
|
|
*
|
|
* AUTHOR: ReedB
|
|
*
|
|
* DATE: 17 Oct, 1996
|
|
*
|
|
* DESCRIPTION:
|
|
* Alarm dialog support.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
#include <mmsystem.h>
|
|
#include <commctrl.h>
|
|
#include <shlobj.h>
|
|
#include <shellapi.h>
|
|
#include <shlobjp.h>
|
|
#include <help.h>
|
|
#include <powercfp.h>
|
|
#include <mstask.h>
|
|
#include <shfusion.h>
|
|
#include <ntpoapi.h>
|
|
|
|
#include "powercfg.h"
|
|
#include "pwrresid.h"
|
|
#include "PwrMn_cs.h"
|
|
|
|
// Private functions implemented in ALARM.C
|
|
void EditWorkItem(HWND, LPTSTR);
|
|
BOOLEAN SetSliderStatusText(HWND, UINT, UINT);
|
|
BOOLEAN SetAlarmStatusText(HWND);
|
|
#ifdef WINNT
|
|
void HideShowRunProgram(HWND hWnd);
|
|
#endif
|
|
|
|
// Alarm dialog property sheet init data structure:
|
|
typedef struct _ALARM_POL_DLG_DATA
|
|
{
|
|
LPTSTR lpszTitleExt;
|
|
WPARAM wParam;
|
|
} ALARM_POL_DLG_DATA, *PALARM_POL_DLG_DATA;
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* G L O B A L D A T A
|
|
*
|
|
*******************************************************************************/
|
|
|
|
extern HINSTANCE g_hInstance; // Global instance handle of this DLL.
|
|
|
|
// This structure is filled in by the Power Policy Manager at CPL_INIT time.
|
|
extern SYSTEM_POWER_CAPABILITIES g_SysPwrCapabilities;
|
|
extern DWORD g_dwNumSleepStates;
|
|
extern DWORD g_dwSleepStatesMaxMin;
|
|
extern DWORD g_dwBattryLevelMaxMin;
|
|
|
|
SYSTEM_POWER_STATE g_spsMaxSleepState = PowerSystemHibernate;
|
|
|
|
extern UINT g_uiDisableWakesFlag; // Flag mask value.
|
|
extern UINT g_uiOverrideAppsFlag; // Flag mask value.
|
|
|
|
// A systary change requires PowerSchemeDlgProc re-init.
|
|
extern BOOL g_bSystrayChange;
|
|
|
|
// Machine is currently capable of hibernate, managed by code in hibernat.c.
|
|
extern UINT g_uiPwrActIDs[];
|
|
|
|
// Persistant storage of this data is managed by POWRPROF.DLL API's.
|
|
extern GLOBAL_POWER_POLICY g_gpp;
|
|
|
|
// Indices into g_uiPwrActIDs
|
|
#define ID_STANDBY 0
|
|
#define ID_SHUTDOWN 1
|
|
|
|
// Local visable/enabled control state variables.
|
|
UINT g_uiSoundState;
|
|
UINT g_uiTextState;
|
|
UINT g_uiProgState;
|
|
UINT g_uiLoChangeEnable;
|
|
UINT g_uiLoChangeState;
|
|
UINT g_uiAlwaysHide = CONTROL_HIDE;
|
|
|
|
UINT g_uiNotifySoundFlag = POWER_LEVEL_USER_NOTIFY_SOUND;
|
|
UINT g_uiNotifyTextFlag = POWER_LEVEL_USER_NOTIFY_TEXT;
|
|
|
|
#ifdef WINNT
|
|
UINT g_uiNotifyProgFlag = POWER_LEVEL_USER_NOTIFY_EXEC;
|
|
|
|
CONST LPTSTR g_szAlarmTaskName [NUM_DISCHARGE_POLICIES] = {
|
|
TEXT("Critical Battery Alarm Program"),
|
|
TEXT("Low Battery Alarm Program"),
|
|
NULL,
|
|
NULL
|
|
};
|
|
#endif
|
|
|
|
// Advanced alarm policies dialog controls descriptions:
|
|
#ifdef WINNT
|
|
#define NUM_ALARM_ACTIONS_CONTROLS 7
|
|
#else
|
|
#define NUM_ALARM_ACTIONS_CONTROLS 5
|
|
#endif
|
|
|
|
// Handy indicies into our AlarmActions control arrays
|
|
#define ID_NOTIFYWITHSOUND 0
|
|
#define ID_NOTIFYWITHTEXT 1
|
|
#define ID_ENABLELOWSTATE 2
|
|
#define ID_ALARMACTIONPOLICY 3
|
|
#define ID_ALARMIGNORENONRESP 4
|
|
#ifdef WINNT
|
|
#define ID_RUNPROGCHECKBOX 5
|
|
#define ID_RUNPROGWORKITEM 6
|
|
#endif
|
|
|
|
POWER_CONTROLS g_pcAlarmActions[NUM_ALARM_ACTIONS_CONTROLS] =
|
|
{// Control ID Control Type Data Address Data Size Parameter Pointer EnableVisible State Pointer
|
|
IDC_NOTIFYWITHSOUND, CHECK_BOX_ENABLE, NULL, sizeof(DWORD), &g_uiNotifySoundFlag, &g_uiSoundState,
|
|
IDC_NOTIFYWITHTEXT, CHECK_BOX, NULL, sizeof(DWORD), &g_uiNotifyTextFlag, &g_uiTextState,
|
|
IDC_ENABLELOWSTATE, CHECK_BOX_ENABLE, &g_uiLoChangeEnable,sizeof(DWORD), NULL, &g_uiLoChangeState,
|
|
IDC_ALARMACTIONPOLICY, COMBO_BOX, NULL, sizeof(DWORD), NULL, &g_uiLoChangeState,
|
|
IDC_ALARMIGNORENONRESP, CHECK_BOX, NULL, sizeof(DWORD), &g_uiOverrideAppsFlag, &g_uiLoChangeState,
|
|
#ifdef WINNT
|
|
IDC_RUNPROGCHECKBOX, CHECK_BOX_ENABLE, NULL, sizeof(DWORD), &g_uiNotifyProgFlag, &g_uiProgState,
|
|
IDC_RUNPROGWORKITEM, PUSHBUTTON, NULL, 0, NULL, &g_uiProgState,
|
|
#endif
|
|
};
|
|
|
|
// Alarm policies dialog controls descriptions:
|
|
#define NUM_ALARM_CONTROLS 6
|
|
|
|
// Local visable/enabled control state variables.
|
|
UINT g_uiLoState;
|
|
UINT g_uiCritState;
|
|
UINT g_uiBatteryLevelScale;
|
|
|
|
POWER_CONTROLS g_pcAlarm[NUM_ALARM_CONTROLS] =
|
|
{// Control ID Control Type Data Address Data Size Parameter Pointer Enable/Visible State Pointer
|
|
IDC_LOBATALARMENABLE, CHECK_BOX_ENABLE, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].Enable), sizeof(ULONG), NULL, &g_uiLoState,
|
|
IDC_LOWACTION, PUSHBUTTON, NULL, 0, NULL, &g_uiLoState,
|
|
IDC_LOALARMSLIDER, SLIDER, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel), sizeof(ULONG), &g_dwBattryLevelMaxMin, &g_uiLoState,
|
|
IDC_CRITBATALARMENABLE, CHECK_BOX_ENABLE, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].Enable), sizeof(ULONG), NULL, &g_uiCritState,
|
|
IDC_CRITACTION, PUSHBUTTON, NULL, 0, NULL, &g_uiCritState,
|
|
IDC_CRITALARMSLIDER, SLIDER, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel), sizeof(ULONG), &g_dwBattryLevelMaxMin, &g_uiCritState,
|
|
};
|
|
|
|
// "Alarms" Dialog Box (IDD_ALARMPOLICY == 103) help array:
|
|
|
|
const DWORD g_AlarmHelpIDs[]=
|
|
{
|
|
IDC_POWERCFGGROUPBOX3, IDH_103_1110, // Alarms: "Low battery alarm groupbox" (Button)
|
|
IDC_LOBATALARMENABLE, IDH_103_1106, // Alarms: "Set off &low battery alarm when power level reaches:" (Button)
|
|
IDC_LOWALARMLEVEL, IDH_103_1104, // Alarms: "Low alarm level" (Static)
|
|
IDC_LOALARMSLIDER, IDH_103_1102, // Alarms: "Low alarm slider" (msctls_trackbar32)
|
|
IDC_LOWACTION, IDH_103_1101, // Alarms: "Alar&m Action..." (Button)
|
|
IDC_LOALARMNOTIFICATION, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
|
|
IDC_LOALARMPOWERMODE, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
|
|
#ifdef WINNT
|
|
IDC_LOALARMPROGRAM, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
|
|
#endif
|
|
IDC_POWERCFGGROUPBOX4, IDH_103_1111, // Alarms: "Critical battery alarm groupbox" (Button)
|
|
IDC_CRITBATALARMENABLE, IDH_103_1107, // Alarms: "Set off &critical battery alarm when power level reaches:" (Button)
|
|
IDC_CRITALARMLEVEL, IDH_103_1105, // Alarms: "Critical alarm level" (Static)
|
|
IDC_CRITALARMSLIDER, IDH_103_1103, // Alarms: "Critical alarm slider" (msctls_trackbar32)
|
|
IDC_CRITACTION, IDH_103_1100, // Alarms: "Ala&rm Action..." (Button)
|
|
IDC_CRITALARMNOTIFICATION,IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
|
|
IDC_CRITALARMPOWERMODE, IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
|
|
#ifdef WINNT
|
|
IDC_CRITALARMPROGRAM, IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
|
|
#endif
|
|
IDC_NO_HELP_1, NO_HELP,
|
|
IDC_NO_HELP_2, NO_HELP,
|
|
IDC_NO_HELP_3, NO_HELP,
|
|
IDC_NO_HELP_4, NO_HELP,
|
|
0, 0
|
|
};
|
|
|
|
// "Alarm Actions" Dialog Box (IDD_ALARMACTIONS == 106) help array:
|
|
|
|
const DWORD g_AlarmActHelpIDs[]=
|
|
{
|
|
IDC_POWERCFGGROUPBOX5, IDH_106_1608, // Alarm Actions: "Notification groupbox" (Button)
|
|
IDC_NOTIFYWITHSOUND, IDH_106_1603, // Alarm Actions: "&Sound alarm" (Button)
|
|
IDC_NOTIFYWITHTEXT, IDH_106_1605, // Alarm Actions: "&Display message" (Button)
|
|
IDC_POWERCFGGROUPBOX6, IDH_106_1609, // Alarm Actions: "Power level groupbox" (Button)
|
|
IDC_POWERCFGGROUPBOX7, IDH_106_1609, // Alarm Actions: "Run program groupbox"
|
|
IDC_ENABLELOWSTATE, IDH_106_1600, // Alarm Actions: "When the &alarm goes off, the computer will:" (Button)
|
|
IDC_ALARMACTIONPOLICY, IDH_106_1601, // Alarm Actions: "Alarm action dropdown" (ComboBox)
|
|
IDC_ALARMIGNORENONRESP, IDH_106_1602, // Alarm Actions: "&Force standby or shutdown even if a program stops responding." (Button)
|
|
#ifdef WINNT
|
|
IDC_RUNPROGCHECKBOX, IDH_106_1620, // Alarm Actions: "Specifies that you want a program to run..."
|
|
IDC_RUNPROGWORKITEM, IDH_106_1621, // Alarm Actions: "Displays a dialog box wher the work item is configured..."
|
|
#endif
|
|
0, 0
|
|
};
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* P U B L I C E N T R Y P O I N T S
|
|
*
|
|
*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* AlarmActionsDlgProc
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
INT_PTR CALLBACK AlarmActionsDlgProc(
|
|
HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
static GLOBAL_POWER_POLICY gpp;
|
|
static PALARM_POL_DLG_DATA papdd;
|
|
|
|
static UINT uiIndex;
|
|
static UINT uiEventId;
|
|
#ifdef WINNT
|
|
static LPTSTR lpszTaskName;
|
|
HWND hTaskWnd;
|
|
#endif
|
|
LPTSTR lpszCaption;
|
|
UINT ii;
|
|
|
|
switch (uMsg) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
// Save a copy of the global policies to restore on cancel.
|
|
memcpy(&gpp, &g_gpp, sizeof(gpp));
|
|
|
|
// Set the pointers to the data of interest.
|
|
papdd = (PALARM_POL_DLG_DATA) lParam;
|
|
if (papdd->wParam == IDC_LOWACTION) {
|
|
uiIndex = DISCHARGE_POLICY_LOW;
|
|
uiEventId = IDS_LOWSOUNDEVENT;
|
|
}
|
|
else {
|
|
uiIndex = DISCHARGE_POLICY_CRITICAL;
|
|
uiEventId = IDS_CRITSOUNDEVENT;
|
|
}
|
|
#ifdef WINNT
|
|
lpszTaskName = g_szAlarmTaskName [uiIndex];
|
|
#endif
|
|
// Set up the data pointers in g_pcAlarmActions.
|
|
g_pcAlarmActions[ID_NOTIFYWITHSOUND].lpvData =
|
|
&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
|
|
g_pcAlarmActions[ID_NOTIFYWITHTEXT].lpvData =
|
|
&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
|
|
#ifdef WINNT
|
|
g_pcAlarmActions[ID_RUNPROGCHECKBOX].lpvData =
|
|
&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
|
|
#endif
|
|
g_pcAlarmActions[ID_ALARMACTIONPOLICY].lpdwParam =
|
|
(LPDWORD)&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action);
|
|
g_pcAlarmActions[ID_ALARMIGNORENONRESP].lpvData =
|
|
&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Flags);
|
|
|
|
//
|
|
// Set the appropriate choices for the Alarms
|
|
//
|
|
ii=0;
|
|
|
|
if (g_SysPwrCapabilities.SystemS1 ||
|
|
g_SysPwrCapabilities.SystemS2 || g_SysPwrCapabilities.SystemS3) {
|
|
g_uiPwrActIDs[ii++] = IDS_STANDBY;
|
|
g_uiPwrActIDs[ii++] = PowerActionSleep;
|
|
}
|
|
|
|
if (g_SysPwrCapabilities.HiberFilePresent) {
|
|
g_uiPwrActIDs[ii++] = IDS_HIBERNATE;
|
|
g_uiPwrActIDs[ii++] = PowerActionHibernate;
|
|
}
|
|
|
|
g_uiPwrActIDs[ii++] = IDS_POWEROFF;
|
|
g_uiPwrActIDs[ii++] = PowerActionShutdownOff;
|
|
g_uiPwrActIDs[ii++] = 0;
|
|
g_uiPwrActIDs[ii++] = 0;
|
|
|
|
g_pcAlarmActions[ID_ALARMACTIONPOLICY].lpvData = g_uiPwrActIDs;
|
|
|
|
if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action == PowerActionNone) {
|
|
g_uiLoChangeEnable = FALSE;
|
|
}
|
|
else {
|
|
g_uiLoChangeEnable = TRUE;
|
|
}
|
|
MapPwrAct(&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action), FALSE);
|
|
|
|
// Set the dialog caption.
|
|
lpszCaption = LoadDynamicString(IDS_ALARMACTIONS,
|
|
papdd->lpszTitleExt);
|
|
if (lpszCaption) {
|
|
SetWindowText(hWnd, lpszCaption);
|
|
LocalFree(lpszCaption);
|
|
}
|
|
|
|
// Initialize the controls.
|
|
SetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
|
|
|
|
#ifdef WINNT
|
|
HideShowRunProgram(hWnd);
|
|
#endif
|
|
return (INT_PTR) TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam) {
|
|
#ifdef WINNT
|
|
case IDC_RUNPROGWORKITEM:
|
|
hTaskWnd = FindWindow( NULL, lpszTaskName);
|
|
if (hTaskWnd) {
|
|
BringWindowToTop(hTaskWnd);
|
|
} else {
|
|
EditWorkItem(hWnd, lpszTaskName);
|
|
}
|
|
break;
|
|
|
|
case IDC_RUNPROGCHECKBOX:
|
|
hTaskWnd = FindWindow( NULL, lpszTaskName);
|
|
if (hTaskWnd)
|
|
{
|
|
DestroyWindow(hTaskWnd);
|
|
}
|
|
// No break: Fall through to update grayed status of controls.
|
|
#endif
|
|
case IDC_ENABLELOWSTATE:
|
|
GetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
|
|
SetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
|
|
#ifdef WINNT
|
|
HideShowRunProgram(hWnd);
|
|
#endif
|
|
break;
|
|
|
|
case IDOK:
|
|
#ifdef WINNT
|
|
hTaskWnd = FindWindow( NULL, lpszTaskName);
|
|
if (hTaskWnd) {
|
|
BringWindowToTop(hTaskWnd);
|
|
} else {
|
|
#endif
|
|
GetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
|
|
if (!g_uiLoChangeEnable) {
|
|
g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action =
|
|
PowerActionNone;
|
|
}
|
|
g_gpp.user.DischargePolicy[uiIndex].MinSystemState = g_spsMaxSleepState;
|
|
EndDialog(hWnd, wParam);
|
|
#ifdef WINNT
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
#ifdef WINNT
|
|
hTaskWnd = FindWindow( NULL, lpszTaskName);
|
|
if (hTaskWnd)
|
|
{
|
|
DestroyWindow(hTaskWnd);
|
|
}
|
|
#endif
|
|
// Restore the original global policies.
|
|
memcpy(&g_gpp, &gpp, sizeof(gpp));
|
|
EndDialog(hWnd, wParam);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PCWM_NOTIFYPOWER:
|
|
// Notification from systray, user has changed a PM UI setting.
|
|
g_bSystrayChange = TRUE;
|
|
break;
|
|
|
|
case WM_HELP: // F1
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_AlarmActHelpIDs);
|
|
return TRUE;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_AlarmActHelpIDs);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* AlarmDlgProc
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
INT_PTR CALLBACK AlarmDlgProc(
|
|
HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
NMHDR FAR *lpnm;
|
|
ALARM_POL_DLG_DATA apdd;
|
|
PUINT puiPos, puiPosVar, puiOtherPosVar, puiOtherPos, puiEnableState;
|
|
UINT uiEnable, uiSliderStatusId, uiID;
|
|
SYSTEM_BATTERY_STATE sbsBatteryState;
|
|
BOOL bAdjust;
|
|
|
|
static HWND hWndLoSlider, hWndCritSlider;
|
|
static UINT uiDefaultAlert1, uiLoPos, uiCritPos, uiLoPosSave, uiCritPosSave;
|
|
static BOOL bDirty = FALSE;
|
|
|
|
switch (uMsg) {
|
|
|
|
case WM_INITDIALOG:
|
|
// If we can't read the global power policies hide
|
|
// the controls on this page.
|
|
if (!GetGlobalPwrPolicy(&g_gpp)) {
|
|
HideControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
return TRUE;
|
|
}
|
|
|
|
g_uiTextState = g_uiSoundState = CONTROL_ENABLE;
|
|
|
|
// Set the scale value.
|
|
if (!HIWORD(g_dwBattryLevelMaxMin)) {
|
|
g_uiBatteryLevelScale = 1;
|
|
}
|
|
else {
|
|
g_uiBatteryLevelScale = 100 / HIWORD(g_dwBattryLevelMaxMin);
|
|
}
|
|
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel /=
|
|
g_uiBatteryLevelScale;
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel /=
|
|
g_uiBatteryLevelScale;
|
|
|
|
// Read DefaultAlert1 from composite battery
|
|
NtPowerInformation (SystemBatteryState, NULL, 0, &sbsBatteryState, sizeof(sbsBatteryState));
|
|
if (sbsBatteryState.MaxCapacity == 0) {
|
|
uiDefaultAlert1 = 0;
|
|
} else {
|
|
uiDefaultAlert1 = (100 * sbsBatteryState.DefaultAlert1)/sbsBatteryState.MaxCapacity;
|
|
}
|
|
|
|
// Cache the low alarm slider window handle.
|
|
hWndLoSlider = GetDlgItem(hWnd, IDC_LOALARMSLIDER);
|
|
hWndCritSlider = GetDlgItem(hWnd, IDC_CRITALARMSLIDER);
|
|
|
|
// Initialize the local enable and position variables.
|
|
uiLoPosSave = uiLoPos =
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel;
|
|
uiCritPosSave = uiCritPos =
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel;
|
|
|
|
// Initialize the dialog controls
|
|
SendDlgItemMessage(hWnd, IDC_LOALARMSLIDER, TBM_SETTICFREQ, 25, 0);
|
|
SendDlgItemMessage(hWnd, IDC_CRITALARMSLIDER, TBM_SETTICFREQ, 25, 0);
|
|
SetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
SetSliderStatusText(hWnd, IDC_LOWALARMLEVEL, uiLoPos);
|
|
SetSliderStatusText(hWnd, IDC_CRITALARMLEVEL, uiCritPos);
|
|
SetAlarmStatusText(hWnd);
|
|
|
|
// If we can't write the global policies disable the controls.
|
|
if (!WriteGlobalPwrPolicyReport(hWnd, &g_gpp, FALSE)) {
|
|
DisableControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_NOTIFY:
|
|
lpnm = (NMHDR FAR *)lParam;
|
|
switch(lpnm->code)
|
|
{
|
|
case PSN_APPLY:
|
|
if (bDirty)
|
|
{
|
|
GetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel *=
|
|
g_uiBatteryLevelScale;
|
|
g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel *=
|
|
g_uiBatteryLevelScale;
|
|
WriteGlobalPwrPolicyReport(hWnd, &g_gpp, TRUE);
|
|
GetActivePwrScheme(&uiID);
|
|
SetActivePwrSchemeReport(hWnd, uiID, &g_gpp, NULL);
|
|
bDirty = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam) {
|
|
case IDC_CRITACTION:
|
|
apdd.lpszTitleExt = LoadDynamicString(IDS_CRITBAT);
|
|
goto do_config_alarm_act;
|
|
|
|
case IDC_LOWACTION:
|
|
apdd.lpszTitleExt = LoadDynamicString(IDS_LOWBAT);
|
|
|
|
do_config_alarm_act:
|
|
apdd.wParam = wParam;
|
|
if (IDOK == DialogBoxParam(g_hInstance,
|
|
MAKEINTRESOURCE(IDD_ALARMACTIONS),
|
|
hWnd,
|
|
AlarmActionsDlgProc,
|
|
(LPARAM)&apdd)) {
|
|
// Enable the parent dialog Apply button on change.
|
|
MarkSheetDirty(hWnd, &bDirty);
|
|
}
|
|
|
|
if (apdd.lpszTitleExt) {
|
|
LocalFree(apdd.lpszTitleExt);
|
|
}
|
|
SetAlarmStatusText(hWnd);
|
|
break;
|
|
|
|
case IDC_LOBATALARMENABLE:
|
|
puiPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel);
|
|
puiOtherPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel);
|
|
uiSliderStatusId = IDC_LOWALARMLEVEL;
|
|
goto do_sheet_dirty;
|
|
|
|
case IDC_CRITBATALARMENABLE:
|
|
puiPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel);
|
|
puiOtherPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel);
|
|
uiSliderStatusId = IDC_CRITALARMLEVEL;
|
|
|
|
do_sheet_dirty:
|
|
GetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
if ((uiEnable = IsDlgButtonChecked(hWnd, (int) wParam)) ==
|
|
BST_CHECKED) {
|
|
if (uiLoPos < uiCritPos) {
|
|
uiLoPos = uiCritPos = *puiPosVar = *puiOtherPosVar;
|
|
SetSliderStatusText(hWnd, uiSliderStatusId, uiCritPos);
|
|
}
|
|
}
|
|
SetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
|
|
SetAlarmStatusText(hWnd);
|
|
MarkSheetDirty(hWnd, &bDirty);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
// Only handle slider controls.
|
|
if (((HWND)lParam != hWndLoSlider) &&
|
|
((HWND)lParam != hWndCritSlider)) {
|
|
break;
|
|
}
|
|
|
|
// Don't allow the low slider to be set lower than the critical
|
|
// slider. Reset position on TB_ENDTRACK for this case.
|
|
if (hWndLoSlider == (HWND)lParam) {
|
|
puiPos = &uiLoPos;
|
|
puiOtherPos = &uiCritPos;
|
|
puiEnableState = &g_uiCritState;
|
|
uiSliderStatusId = IDC_LOWALARMLEVEL;
|
|
}
|
|
else {
|
|
puiPos = &uiCritPos;
|
|
puiOtherPos = &uiLoPos;
|
|
puiEnableState = &g_uiLoState;
|
|
uiSliderStatusId = IDC_CRITALARMLEVEL;
|
|
}
|
|
|
|
switch (LOWORD(wParam)) {
|
|
case TB_ENDTRACK:
|
|
|
|
bAdjust = FALSE;
|
|
|
|
if (*puiEnableState & CONTROL_ENABLE) {
|
|
if (uiLoPos < uiCritPos) {
|
|
*puiPos = *puiOtherPos;
|
|
bAdjust = TRUE;
|
|
}
|
|
}
|
|
|
|
if (*puiPos < uiDefaultAlert1) {
|
|
*puiPos = uiDefaultAlert1;
|
|
bAdjust = TRUE;
|
|
}
|
|
|
|
if (bAdjust) {
|
|
SendMessage((HWND)lParam, TBM_SETPOS, TRUE,
|
|
(LPARAM)*puiPos);
|
|
}
|
|
|
|
break;
|
|
|
|
case TB_THUMBPOSITION:
|
|
case TB_THUMBTRACK:
|
|
// New position comes with these messages.
|
|
*puiPos = HIWORD(wParam);
|
|
break;
|
|
|
|
default:
|
|
// New position must be fetched for the rest.
|
|
*puiPos = (UINT) SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
|
|
}
|
|
|
|
// Update the current slider position text.
|
|
SetSliderStatusText(hWnd, uiSliderStatusId, *puiPos);
|
|
|
|
// Enable the parent dialog Apply button on any change.
|
|
MarkSheetDirty(hWnd, &bDirty);
|
|
break;
|
|
|
|
case WM_HELP: // F1
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_AlarmHelpIDs);
|
|
return TRUE;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_AlarmHelpIDs);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* P R I V A T E F U N C T I O N S
|
|
*
|
|
*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* PathOnly
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
BOOL PathOnly(LPTSTR sz)
|
|
{
|
|
LPTSTR p = sz;
|
|
LPTSTR s = NULL;
|
|
|
|
while ( *p ) {
|
|
if ( *p == TEXT('\\') ) {
|
|
s = p;
|
|
} else if ( *p == TEXT(':') ) {
|
|
s = p + 1;
|
|
}
|
|
#if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
|
|
p = AnsiNext(p);
|
|
#else
|
|
p++;
|
|
#endif
|
|
}
|
|
|
|
if ( s ) {
|
|
if ( s == sz )
|
|
s++;
|
|
|
|
*s = TEXT('\0');
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef WINNT
|
|
/*******************************************************************************
|
|
*
|
|
* FileNameOnly
|
|
*
|
|
* DESCRIPTION: Returns a pointer to the first character after the last
|
|
* backslash in a string
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
LPTSTR FileNameOnly(LPTSTR sz)
|
|
{
|
|
LPTSTR next = sz;
|
|
LPTSTR prev;
|
|
LPTSTR begin = next;
|
|
|
|
if (next == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
while ( *next ) {
|
|
prev = next;
|
|
|
|
#if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
|
|
next = AnsiNext(next);
|
|
#else
|
|
next++;
|
|
#endif
|
|
if ( (*prev == TEXT('\\')) || (*prev == TEXT(':')) ) {
|
|
begin = next;
|
|
}
|
|
}
|
|
|
|
return begin;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* EditWorkItem
|
|
*
|
|
* DESCRIPTION: Opens the specified task.
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
void EditWorkItem(HWND hWnd, LPTSTR pszTaskName)
|
|
{
|
|
ITaskScheduler *pISchedAgent = NULL;
|
|
ITask *pITask;
|
|
IPersistFile *pIPersistFile;
|
|
HRESULT hr;
|
|
|
|
hr = CoInitialize(NULL);
|
|
|
|
if (FAILED(hr)) {
|
|
DebugPrint( "EditWorkItem: CoInitialize returned hr = %08x\n", hr);
|
|
return;
|
|
}
|
|
|
|
hr = CoCreateInstance( &CLSID_CSchedulingAgent,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
&IID_ISchedulingAgent,
|
|
(LPVOID*)&pISchedAgent);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
hr = pISchedAgent->lpVtbl->Activate(pISchedAgent,
|
|
pszTaskName,
|
|
&IID_ITask,
|
|
&(IUnknown *)pITask);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
pITask->lpVtbl->EditWorkItem(pITask, hWnd, 0);
|
|
pITask->lpVtbl->Release(pITask);
|
|
}
|
|
else if (HRESULT_CODE (hr) == ERROR_FILE_NOT_FOUND){
|
|
hr = pISchedAgent->lpVtbl->NewWorkItem(
|
|
pISchedAgent,
|
|
pszTaskName,
|
|
&CLSID_CTask,
|
|
&IID_ITask,
|
|
&(IUnknown *)pITask);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = pITask->lpVtbl->QueryInterface(pITask, &IID_IPersistFile,
|
|
(void **)&pIPersistFile);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = pIPersistFile->lpVtbl->Save(pIPersistFile, NULL, TRUE);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
pITask->lpVtbl->EditWorkItem(pITask, hWnd, 0);
|
|
}
|
|
else {
|
|
DebugPrint( "EditWorkItem: Save filed hr = %08x\n", hr);
|
|
}
|
|
pIPersistFile->lpVtbl->Release(pIPersistFile);
|
|
}
|
|
else {
|
|
DebugPrint( "EditWorkItem: QueryInterface for IPersistFile hr = %08x\n", hr);
|
|
}
|
|
pITask->lpVtbl->Release(pITask);
|
|
|
|
}
|
|
else {
|
|
DebugPrint( "EditWorkItem: Activate returned hr = %08x\n", hr);
|
|
}
|
|
}
|
|
else {
|
|
DebugPrint( "EditWorkItem: NewWorkItem returned hr = %08x\n", hr);
|
|
}
|
|
|
|
pISchedAgent->lpVtbl->Release(pISchedAgent);
|
|
}
|
|
else {
|
|
DebugPrint( "EditWorkItem: CoCreateInstance returned hr = %08x\n", hr);
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
}
|
|
#endif
|
|
/*******************************************************************************
|
|
*
|
|
* SetSliderStatusText
|
|
*
|
|
* DESCRIPTION:
|
|
* Update the current slider position text.
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
BOOLEAN SetSliderStatusText(HWND hWnd, UINT uiStatusId, UINT uiLevel)
|
|
{
|
|
LPTSTR pString;
|
|
|
|
pString = LoadDynamicString(IDS_ALARMLEVELFORMAT,
|
|
uiLevel * g_uiBatteryLevelScale);
|
|
DisplayFreeStr(hWnd, uiStatusId, pString, FREE_STR);
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* SetAlarmStatusText
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
BOOLEAN SetAlarmStatusText(HWND hWnd)
|
|
{
|
|
TCHAR szStatus[MAX_UI_STR_LEN];
|
|
LPTSTR lpsz;
|
|
UINT uiActionId, uiStatusId, uiIndex, uiAction;
|
|
PUINT puiState;
|
|
#ifdef WINNT
|
|
|
|
LPTSTR lpszRunProg;
|
|
|
|
#endif
|
|
|
|
puiState = &g_uiCritState;
|
|
uiStatusId = IDC_CRITALARMNOTIFICATION;
|
|
for (uiIndex = DISCHARGE_POLICY_CRITICAL; uiIndex <= DISCHARGE_POLICY_LOW; uiIndex++) {
|
|
|
|
// Format the alarm action notification status string.
|
|
szStatus[0] = '\0';
|
|
if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
|
|
POWER_LEVEL_USER_NOTIFY_SOUND) {
|
|
if ((lpsz = LoadDynamicString(IDS_ALARMSTATUSSOUND)) != NULL) {
|
|
lstrcat(szStatus, lpsz);
|
|
LocalFree(lpsz);
|
|
}
|
|
}
|
|
|
|
if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
|
|
POWER_LEVEL_USER_NOTIFY_TEXT) {
|
|
if (szStatus[0] != '\0') {
|
|
lstrcat(szStatus, TEXT(", "));
|
|
}
|
|
if ((lpsz = LoadDynamicString(IDS_ALARMSTATUSTEXT)) != NULL) {
|
|
lstrcat(szStatus, lpsz);
|
|
LocalFree(lpsz);
|
|
}
|
|
}
|
|
|
|
if (szStatus[0] == '\0') {
|
|
if ((lpsz = LoadDynamicString(IDS_NOACTION)) != NULL) {
|
|
lstrcat(szStatus, lpsz);
|
|
LocalFree(lpsz);
|
|
}
|
|
}
|
|
DisplayFreeStr(hWnd, uiStatusId, szStatus, NO_FREE_STR);
|
|
ShowWindow(GetDlgItem(hWnd, uiStatusId),
|
|
(*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
|
|
uiStatusId++;
|
|
|
|
// Format the alarm action power mode status string.
|
|
uiAction = g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action;
|
|
switch (uiAction) {
|
|
case PowerActionNone:
|
|
uiActionId = IDS_NOACTION;
|
|
break;
|
|
|
|
case PowerActionSleep:
|
|
uiActionId = IDS_STANDBY;
|
|
break;
|
|
|
|
case PowerActionHibernate:
|
|
uiActionId = IDS_HIBERNATE;
|
|
break;
|
|
|
|
case PowerActionShutdown:
|
|
case PowerActionShutdownReset:
|
|
case PowerActionShutdownOff:
|
|
uiActionId = IDS_POWEROFF;
|
|
break;
|
|
|
|
case PowerActionReserved:
|
|
default:
|
|
DebugPrint( "SetAlarmStatusText, unable to map power action: %X", uiAction);
|
|
uiActionId = IDS_NOACTION;
|
|
}
|
|
lpsz = LoadDynamicString(uiActionId);
|
|
DisplayFreeStr(hWnd, uiStatusId, lpsz, FREE_STR);
|
|
ShowWindow(GetDlgItem(hWnd, uiStatusId),
|
|
(*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
|
|
uiStatusId++;
|
|
|
|
// Format the alarm action run program status string.
|
|
#ifdef WINNT
|
|
lpszRunProg = NULL;
|
|
|
|
if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
|
|
POWER_LEVEL_USER_NOTIFY_EXEC) {
|
|
{
|
|
//
|
|
// Open up the alarm action task and read the program name.
|
|
//
|
|
|
|
ITaskScheduler *pISchedAgent = NULL;
|
|
ITask *pITask;
|
|
|
|
HRESULT hr;
|
|
|
|
hr = CoInitialize(NULL);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
hr = CoCreateInstance( &CLSID_CSchedulingAgent,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
&IID_ISchedulingAgent,
|
|
(LPVOID*)&pISchedAgent);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
hr = pISchedAgent->lpVtbl->Activate(pISchedAgent,
|
|
g_szAlarmTaskName [uiIndex],
|
|
&IID_ITask,
|
|
&(IUnknown *)pITask);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
pITask->lpVtbl->GetApplicationName(pITask, &lpszRunProg);
|
|
pITask->lpVtbl->Release(pITask);
|
|
}
|
|
|
|
pISchedAgent->lpVtbl->Release(pISchedAgent);
|
|
}
|
|
else {
|
|
DebugPrint( "SetAlarmStatusText: CoCreateInstance returned hr = %08x\n", hr);
|
|
}
|
|
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
|
|
}
|
|
if (lpszRunProg != NULL) {
|
|
|
|
DisplayFreeStr(hWnd, uiStatusId, FileNameOnly(lpszRunProg), NO_FREE_STR);
|
|
CoTaskMemFree (lpszRunProg);
|
|
lpszRunProg = NULL;
|
|
}
|
|
else {
|
|
lpsz = LoadDynamicString(IDS_NONE);
|
|
DisplayFreeStr(hWnd, uiStatusId, lpsz, FREE_STR);
|
|
}
|
|
ShowWindow(GetDlgItem(hWnd, uiStatusId),
|
|
(*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
|
|
#endif
|
|
uiStatusId++;
|
|
|
|
puiState = &g_uiLoState;
|
|
uiStatusId = IDC_LOALARMNOTIFICATION;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef WINNT
|
|
/*******************************************************************************
|
|
*
|
|
* HideShowRunProgram
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
* On WINNT, only power users may set the run program.
|
|
* The run program is stored under HKLM.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
void HideShowRunProgram(HWND hWnd)
|
|
{
|
|
if (CanUserWritePwrScheme()) {
|
|
ShowWindow(GetDlgItem(hWnd, IDC_POWERCFGGROUPBOX7), SW_SHOW);
|
|
ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGCHECKBOX), SW_SHOW);
|
|
ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGWORKITEM), SW_SHOW);
|
|
}
|
|
else {
|
|
ShowWindow(GetDlgItem(hWnd, IDC_POWERCFGGROUPBOX7), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGCHECKBOX), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGWORKITEM), SW_HIDE);
|
|
}
|
|
}
|
|
#endif
|
|
|