windows-nt/Source/XPSP1/NT/shell/osshell/cpls/powercfg/alarm.c
2020-09-26 16:20:57 +08:00

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