Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1013 lines
36 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1996
  4. *
  5. * TITLE: ALARM.C
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 17 Oct, 1996
  12. *
  13. * DESCRIPTION:
  14. * Alarm dialog support.
  15. *
  16. *******************************************************************************/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <mmsystem.h>
  22. #include <commctrl.h>
  23. #include <shlobj.h>
  24. #include <shellapi.h>
  25. #include <shlobjp.h>
  26. #include <help.h>
  27. #include <powercfp.h>
  28. #include <mstask.h>
  29. #include <shfusion.h>
  30. #include <ntpoapi.h>
  31. #include <strsafe.h>
  32. #include "powercfg.h"
  33. #include "pwrresid.h"
  34. #include "PwrMn_cs.h"
  35. // Private functions implemented in ALARM.C
  36. void EditWorkItem(HWND, LPTSTR);
  37. BOOLEAN SetSliderStatusText(HWND, UINT, UINT);
  38. BOOLEAN SetAlarmStatusText(HWND);
  39. #ifdef WINNT
  40. void HideShowRunProgram(HWND hWnd);
  41. #endif
  42. // Alarm dialog property sheet init data structure:
  43. typedef struct _ALARM_POL_DLG_DATA
  44. {
  45. LPTSTR lpszTitleExt;
  46. WPARAM wParam;
  47. } ALARM_POL_DLG_DATA, *PALARM_POL_DLG_DATA;
  48. /*******************************************************************************
  49. *
  50. * G L O B A L D A T A
  51. *
  52. *******************************************************************************/
  53. extern HINSTANCE g_hInstance; // Global instance handle of this DLL.
  54. // This structure is filled in by the Power Policy Manager at CPL_INIT time.
  55. extern SYSTEM_POWER_CAPABILITIES g_SysPwrCapabilities;
  56. extern DWORD g_dwNumSleepStates;
  57. extern DWORD g_dwSleepStatesMaxMin;
  58. extern DWORD g_dwBattryLevelMaxMin;
  59. SYSTEM_POWER_STATE g_spsMaxSleepState = PowerSystemHibernate;
  60. extern UINT g_uiDisableWakesFlag; // Flag mask value.
  61. extern UINT g_uiOverrideAppsFlag; // Flag mask value.
  62. // A systary change requires PowerSchemeDlgProc re-init.
  63. extern BOOL g_bSystrayChange;
  64. // Machine is currently capable of hibernate, managed by code in hibernat.c.
  65. extern UINT g_uiPwrActIDs[];
  66. // Persistant storage of this data is managed by POWRPROF.DLL API's.
  67. extern GLOBAL_POWER_POLICY g_gpp;
  68. // Indices into g_uiPwrActIDs
  69. #define ID_STANDBY 0
  70. #define ID_SHUTDOWN 1
  71. // Local visable/enabled control state variables.
  72. UINT g_uiSoundState;
  73. UINT g_uiTextState;
  74. UINT g_uiProgState;
  75. UINT g_uiLoChangeEnable;
  76. UINT g_uiLoChangeState;
  77. UINT g_uiAlwaysHide = CONTROL_HIDE;
  78. UINT g_uiNotifySoundFlag = POWER_LEVEL_USER_NOTIFY_SOUND;
  79. UINT g_uiNotifyTextFlag = POWER_LEVEL_USER_NOTIFY_TEXT;
  80. #ifdef WINNT
  81. UINT g_uiNotifyProgFlag = POWER_LEVEL_USER_NOTIFY_EXEC;
  82. CONST LPTSTR g_szAlarmTaskName [NUM_DISCHARGE_POLICIES] = {
  83. TEXT("Critical Battery Alarm Program"),
  84. TEXT("Low Battery Alarm Program"),
  85. NULL,
  86. NULL
  87. };
  88. #endif
  89. // Advanced alarm policies dialog controls descriptions:
  90. #ifdef WINNT
  91. #define NUM_ALARM_ACTIONS_CONTROLS 7
  92. #else
  93. #define NUM_ALARM_ACTIONS_CONTROLS 5
  94. #endif
  95. // Handy indicies into our AlarmActions control arrays
  96. #define ID_NOTIFYWITHSOUND 0
  97. #define ID_NOTIFYWITHTEXT 1
  98. #define ID_ENABLELOWSTATE 2
  99. #define ID_ALARMACTIONPOLICY 3
  100. #define ID_ALARMIGNORENONRESP 4
  101. #ifdef WINNT
  102. #define ID_RUNPROGCHECKBOX 5
  103. #define ID_RUNPROGWORKITEM 6
  104. #endif
  105. POWER_CONTROLS g_pcAlarmActions[NUM_ALARM_ACTIONS_CONTROLS] =
  106. {// Control ID Control Type Data Address Data Size Parameter Pointer EnableVisible State Pointer
  107. IDC_NOTIFYWITHSOUND, CHECK_BOX_ENABLE, NULL, sizeof(DWORD), &g_uiNotifySoundFlag, &g_uiSoundState,
  108. IDC_NOTIFYWITHTEXT, CHECK_BOX, NULL, sizeof(DWORD), &g_uiNotifyTextFlag, &g_uiTextState,
  109. IDC_ENABLELOWSTATE, CHECK_BOX_ENABLE, &g_uiLoChangeEnable,sizeof(DWORD), NULL, &g_uiLoChangeState,
  110. IDC_ALARMACTIONPOLICY, COMBO_BOX, NULL, sizeof(DWORD), NULL, &g_uiLoChangeState,
  111. IDC_ALARMIGNORENONRESP, CHECK_BOX, NULL, sizeof(DWORD), &g_uiOverrideAppsFlag, &g_uiLoChangeState,
  112. #ifdef WINNT
  113. IDC_RUNPROGCHECKBOX, CHECK_BOX_ENABLE, NULL, sizeof(DWORD), &g_uiNotifyProgFlag, &g_uiProgState,
  114. IDC_RUNPROGWORKITEM, PUSHBUTTON, NULL, 0, NULL, &g_uiProgState,
  115. #endif
  116. };
  117. // Alarm policies dialog controls descriptions:
  118. #define NUM_ALARM_CONTROLS 6
  119. // Local visable/enabled control state variables.
  120. UINT g_uiLoState;
  121. UINT g_uiCritState;
  122. UINT g_uiBatteryLevelScale;
  123. POWER_CONTROLS g_pcAlarm[NUM_ALARM_CONTROLS] =
  124. {// Control ID Control Type Data Address Data Size Parameter Pointer Enable/Visible State Pointer
  125. IDC_LOBATALARMENABLE, CHECK_BOX_ENABLE, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].Enable), sizeof(ULONG), NULL, &g_uiLoState,
  126. IDC_LOWACTION, PUSHBUTTON, NULL, 0, NULL, &g_uiLoState,
  127. IDC_LOALARMSLIDER, SLIDER, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel), sizeof(ULONG), &g_dwBattryLevelMaxMin, &g_uiLoState,
  128. IDC_CRITBATALARMENABLE, CHECK_BOX_ENABLE, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].Enable), sizeof(ULONG), NULL, &g_uiCritState,
  129. IDC_CRITACTION, PUSHBUTTON, NULL, 0, NULL, &g_uiCritState,
  130. IDC_CRITALARMSLIDER, SLIDER, &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel), sizeof(ULONG), &g_dwBattryLevelMaxMin, &g_uiCritState,
  131. };
  132. // "Alarms" Dialog Box (IDD_ALARMPOLICY == 103) help array:
  133. const DWORD g_AlarmHelpIDs[]=
  134. {
  135. IDC_POWERCFGGROUPBOX3, IDH_103_1110, // Alarms: "Low battery alarm groupbox" (Button)
  136. IDC_LOBATALARMENABLE, IDH_103_1106, // Alarms: "Set off &low battery alarm when power level reaches:" (Button)
  137. IDC_LOWALARMLEVEL, IDH_103_1104, // Alarms: "Low alarm level" (Static)
  138. IDC_LOALARMSLIDER, IDH_103_1102, // Alarms: "Low alarm slider" (msctls_trackbar32)
  139. IDC_LOWACTION, IDH_103_1101, // Alarms: "Alar&m Action..." (Button)
  140. IDC_LOALARMNOTIFICATION, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
  141. IDC_LOALARMPOWERMODE, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
  142. #ifdef WINNT
  143. IDC_LOALARMPROGRAM, IDH_103_1108, // Alarms: "Low alarm status text" (Static)
  144. #endif
  145. IDC_POWERCFGGROUPBOX4, IDH_103_1111, // Alarms: "Critical battery alarm groupbox" (Button)
  146. IDC_CRITBATALARMENABLE, IDH_103_1107, // Alarms: "Set off &critical battery alarm when power level reaches:" (Button)
  147. IDC_CRITALARMLEVEL, IDH_103_1105, // Alarms: "Critical alarm level" (Static)
  148. IDC_CRITALARMSLIDER, IDH_103_1103, // Alarms: "Critical alarm slider" (msctls_trackbar32)
  149. IDC_CRITACTION, IDH_103_1100, // Alarms: "Ala&rm Action..." (Button)
  150. IDC_CRITALARMNOTIFICATION,IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
  151. IDC_CRITALARMPOWERMODE, IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
  152. #ifdef WINNT
  153. IDC_CRITALARMPROGRAM, IDH_103_1109, // Alarms: "Critical alarm status text" (Static)
  154. #endif
  155. IDC_NO_HELP_1, NO_HELP,
  156. IDC_NO_HELP_2, NO_HELP,
  157. IDC_NO_HELP_3, NO_HELP,
  158. IDC_NO_HELP_4, NO_HELP,
  159. 0, 0
  160. };
  161. // "Alarm Actions" Dialog Box (IDD_ALARMACTIONS == 106) help array:
  162. const DWORD g_AlarmActHelpIDs[]=
  163. {
  164. IDC_POWERCFGGROUPBOX5, IDH_106_1608, // Alarm Actions: "Notification groupbox" (Button)
  165. IDC_NOTIFYWITHSOUND, IDH_106_1603, // Alarm Actions: "&Sound alarm" (Button)
  166. IDC_NOTIFYWITHTEXT, IDH_106_1605, // Alarm Actions: "&Display message" (Button)
  167. IDC_POWERCFGGROUPBOX6, IDH_106_1609, // Alarm Actions: "Power level groupbox" (Button)
  168. IDC_POWERCFGGROUPBOX7, IDH_106_1609, // Alarm Actions: "Run program groupbox"
  169. IDC_ENABLELOWSTATE, IDH_106_1600, // Alarm Actions: "When the &alarm goes off, the computer will:" (Button)
  170. IDC_ALARMACTIONPOLICY, IDH_106_1601, // Alarm Actions: "Alarm action dropdown" (ComboBox)
  171. IDC_ALARMIGNORENONRESP, IDH_106_1602, // Alarm Actions: "&Force standby or shutdown even if a program stops responding." (Button)
  172. #ifdef WINNT
  173. IDC_RUNPROGCHECKBOX, IDH_106_1620, // Alarm Actions: "Specifies that you want a program to run..."
  174. IDC_RUNPROGWORKITEM, IDH_106_1621, // Alarm Actions: "Displays a dialog box wher the work item is configured..."
  175. #endif
  176. 0, 0
  177. };
  178. /*******************************************************************************
  179. *
  180. * P U B L I C E N T R Y P O I N T S
  181. *
  182. *******************************************************************************/
  183. /*******************************************************************************
  184. *
  185. * AlarmActionsDlgProc
  186. *
  187. * DESCRIPTION:
  188. *
  189. * PARAMETERS:
  190. *
  191. *******************************************************************************/
  192. INT_PTR CALLBACK AlarmActionsDlgProc(
  193. HWND hWnd,
  194. UINT uMsg,
  195. WPARAM wParam,
  196. LPARAM lParam
  197. )
  198. {
  199. static GLOBAL_POWER_POLICY gpp;
  200. static PALARM_POL_DLG_DATA papdd;
  201. static UINT uiIndex;
  202. static UINT uiEventId;
  203. #ifdef WINNT
  204. static LPTSTR lpszTaskName;
  205. HWND hTaskWnd;
  206. #endif
  207. LPTSTR lpszCaption;
  208. UINT ii;
  209. switch (uMsg) {
  210. case WM_INITDIALOG:
  211. // Save a copy of the global policies to restore on cancel.
  212. memcpy(&gpp, &g_gpp, sizeof(gpp));
  213. // Set the pointers to the data of interest.
  214. papdd = (PALARM_POL_DLG_DATA) lParam;
  215. if (papdd->wParam == IDC_LOWACTION) {
  216. uiIndex = DISCHARGE_POLICY_LOW;
  217. uiEventId = IDS_LOWSOUNDEVENT;
  218. }
  219. else {
  220. uiIndex = DISCHARGE_POLICY_CRITICAL;
  221. uiEventId = IDS_CRITSOUNDEVENT;
  222. }
  223. #ifdef WINNT
  224. lpszTaskName = g_szAlarmTaskName [uiIndex];
  225. #endif
  226. // Set up the data pointers in g_pcAlarmActions.
  227. g_pcAlarmActions[ID_NOTIFYWITHSOUND].lpvData =
  228. &(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
  229. g_pcAlarmActions[ID_NOTIFYWITHTEXT].lpvData =
  230. &(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
  231. #ifdef WINNT
  232. g_pcAlarmActions[ID_RUNPROGCHECKBOX].lpvData =
  233. &(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode);
  234. #endif
  235. g_pcAlarmActions[ID_ALARMACTIONPOLICY].lpdwParam =
  236. (LPDWORD)&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action);
  237. g_pcAlarmActions[ID_ALARMIGNORENONRESP].lpvData =
  238. &(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Flags);
  239. //
  240. // Set the appropriate choices for the Alarms
  241. //
  242. ii=0;
  243. if (g_SysPwrCapabilities.SystemS1 ||
  244. g_SysPwrCapabilities.SystemS2 || g_SysPwrCapabilities.SystemS3) {
  245. g_uiPwrActIDs[ii++] = IDS_STANDBY;
  246. g_uiPwrActIDs[ii++] = PowerActionSleep;
  247. }
  248. if (g_SysPwrCapabilities.HiberFilePresent) {
  249. g_uiPwrActIDs[ii++] = IDS_HIBERNATE;
  250. g_uiPwrActIDs[ii++] = PowerActionHibernate;
  251. }
  252. g_uiPwrActIDs[ii++] = IDS_POWEROFF;
  253. g_uiPwrActIDs[ii++] = PowerActionShutdownOff;
  254. g_uiPwrActIDs[ii++] = 0;
  255. g_uiPwrActIDs[ii++] = 0;
  256. g_pcAlarmActions[ID_ALARMACTIONPOLICY].lpvData = g_uiPwrActIDs;
  257. if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action == PowerActionNone) {
  258. g_uiLoChangeEnable = FALSE;
  259. }
  260. else {
  261. g_uiLoChangeEnable = TRUE;
  262. }
  263. MapPwrAct(&(g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action), FALSE);
  264. // Set the dialog caption.
  265. lpszCaption = LoadDynamicString(IDS_ALARMACTIONS,
  266. papdd->lpszTitleExt);
  267. if (lpszCaption) {
  268. SetWindowText(hWnd, lpszCaption);
  269. LocalFree(lpszCaption);
  270. }
  271. // Initialize the controls.
  272. SetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
  273. #ifdef WINNT
  274. HideShowRunProgram(hWnd);
  275. #endif
  276. return (INT_PTR) TRUE;
  277. case WM_COMMAND:
  278. switch (wParam) {
  279. #ifdef WINNT
  280. case IDC_RUNPROGWORKITEM:
  281. hTaskWnd = FindWindow( NULL, lpszTaskName);
  282. if (hTaskWnd) {
  283. BringWindowToTop(hTaskWnd);
  284. } else {
  285. EditWorkItem(hWnd, lpszTaskName);
  286. }
  287. break;
  288. case IDC_RUNPROGCHECKBOX:
  289. hTaskWnd = FindWindow( NULL, lpszTaskName);
  290. if (hTaskWnd)
  291. {
  292. DestroyWindow(hTaskWnd);
  293. }
  294. // No break: Fall through to update grayed status of controls.
  295. #endif
  296. case IDC_ENABLELOWSTATE:
  297. GetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
  298. SetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
  299. #ifdef WINNT
  300. HideShowRunProgram(hWnd);
  301. #endif
  302. break;
  303. case IDOK:
  304. #ifdef WINNT
  305. hTaskWnd = FindWindow( NULL, lpszTaskName);
  306. if (hTaskWnd) {
  307. BringWindowToTop(hTaskWnd);
  308. } else {
  309. #endif
  310. GetControls(hWnd, NUM_ALARM_ACTIONS_CONTROLS, g_pcAlarmActions);
  311. if (!g_uiLoChangeEnable) {
  312. g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action =
  313. PowerActionNone;
  314. }
  315. g_gpp.user.DischargePolicy[uiIndex].MinSystemState = g_spsMaxSleepState;
  316. EndDialog(hWnd, wParam);
  317. #ifdef WINNT
  318. }
  319. #endif
  320. break;
  321. case IDCANCEL:
  322. #ifdef WINNT
  323. hTaskWnd = FindWindow( NULL, lpszTaskName);
  324. if (hTaskWnd)
  325. {
  326. DestroyWindow(hTaskWnd);
  327. }
  328. #endif
  329. // Restore the original global policies.
  330. memcpy(&g_gpp, &gpp, sizeof(gpp));
  331. EndDialog(hWnd, wParam);
  332. break;
  333. }
  334. break;
  335. case PCWM_NOTIFYPOWER:
  336. // Notification from systray, user has changed a PM UI setting.
  337. g_bSystrayChange = TRUE;
  338. break;
  339. case WM_HELP: // F1
  340. WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_AlarmActHelpIDs);
  341. return TRUE;
  342. case WM_CONTEXTMENU: // right mouse click
  343. WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_AlarmActHelpIDs);
  344. return TRUE;
  345. }
  346. return FALSE;
  347. }
  348. /*******************************************************************************
  349. *
  350. * AlarmDlgProc
  351. *
  352. * DESCRIPTION:
  353. *
  354. * PARAMETERS:
  355. *
  356. *******************************************************************************/
  357. INT_PTR CALLBACK AlarmDlgProc(
  358. HWND hWnd,
  359. UINT uMsg,
  360. WPARAM wParam,
  361. LPARAM lParam
  362. )
  363. {
  364. NMHDR FAR *lpnm;
  365. ALARM_POL_DLG_DATA apdd;
  366. PUINT puiPos, puiPosVar, puiOtherPosVar, puiOtherPos, puiEnableState;
  367. UINT uiEnable, uiSliderStatusId, uiID;
  368. SYSTEM_BATTERY_STATE sbsBatteryState;
  369. BOOL bAdjust;
  370. static HWND hWndLoSlider, hWndCritSlider;
  371. static UINT uiDefaultAlert1, uiLoPos, uiCritPos, uiLoPosSave, uiCritPosSave;
  372. static BOOL bDirty = FALSE;
  373. switch (uMsg) {
  374. case WM_INITDIALOG:
  375. // If we can't read the global power policies hide
  376. // the controls on this page.
  377. if (!GetGlobalPwrPolicy(&g_gpp)) {
  378. HideControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  379. return TRUE;
  380. }
  381. g_uiTextState = g_uiSoundState = CONTROL_ENABLE;
  382. // Set the scale value.
  383. if (!HIWORD(g_dwBattryLevelMaxMin)) {
  384. g_uiBatteryLevelScale = 1;
  385. }
  386. else {
  387. g_uiBatteryLevelScale = 100 / HIWORD(g_dwBattryLevelMaxMin);
  388. }
  389. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel /=
  390. g_uiBatteryLevelScale;
  391. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel /=
  392. g_uiBatteryLevelScale;
  393. // Read DefaultAlert1 from composite battery
  394. NtPowerInformation (SystemBatteryState, NULL, 0, &sbsBatteryState, sizeof(sbsBatteryState));
  395. if (sbsBatteryState.MaxCapacity == 0) {
  396. uiDefaultAlert1 = 0;
  397. } else {
  398. uiDefaultAlert1 = (100 * sbsBatteryState.DefaultAlert1)/sbsBatteryState.MaxCapacity;
  399. }
  400. // Cache the low alarm slider window handle.
  401. hWndLoSlider = GetDlgItem(hWnd, IDC_LOALARMSLIDER);
  402. hWndCritSlider = GetDlgItem(hWnd, IDC_CRITALARMSLIDER);
  403. // Initialize the local enable and position variables.
  404. uiLoPosSave = uiLoPos =
  405. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel;
  406. uiCritPosSave = uiCritPos =
  407. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel;
  408. // Initialize the dialog controls
  409. SendDlgItemMessage(hWnd, IDC_LOALARMSLIDER, TBM_SETTICFREQ, 25, 0);
  410. SendDlgItemMessage(hWnd, IDC_CRITALARMSLIDER, TBM_SETTICFREQ, 25, 0);
  411. SetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  412. SetSliderStatusText(hWnd, IDC_LOWALARMLEVEL, uiLoPos);
  413. SetSliderStatusText(hWnd, IDC_CRITALARMLEVEL, uiCritPos);
  414. SetAlarmStatusText(hWnd);
  415. // If we can't write the global policies disable the controls.
  416. if (!WriteGlobalPwrPolicyReport(hWnd, &g_gpp, FALSE)) {
  417. DisableControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  418. }
  419. return TRUE;
  420. case WM_NOTIFY:
  421. lpnm = (NMHDR FAR *)lParam;
  422. switch(lpnm->code)
  423. {
  424. case PSN_APPLY:
  425. if (bDirty)
  426. {
  427. GetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  428. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel *=
  429. g_uiBatteryLevelScale;
  430. g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel *=
  431. g_uiBatteryLevelScale;
  432. WriteGlobalPwrPolicyReport(hWnd, &g_gpp, TRUE);
  433. GetActivePwrScheme(&uiID);
  434. SetActivePwrSchemeReport(hWnd, uiID, &g_gpp, NULL);
  435. bDirty = FALSE;
  436. }
  437. break;
  438. }
  439. break;
  440. case WM_COMMAND:
  441. switch (wParam) {
  442. case IDC_CRITACTION:
  443. apdd.lpszTitleExt = LoadDynamicString(IDS_CRITBAT);
  444. goto do_config_alarm_act;
  445. case IDC_LOWACTION:
  446. apdd.lpszTitleExt = LoadDynamicString(IDS_LOWBAT);
  447. do_config_alarm_act:
  448. apdd.wParam = wParam;
  449. if (IDOK == DialogBoxParam(g_hInstance,
  450. MAKEINTRESOURCE(IDD_ALARMACTIONS),
  451. hWnd,
  452. AlarmActionsDlgProc,
  453. (LPARAM)&apdd)) {
  454. // Enable the parent dialog Apply button on change.
  455. MarkSheetDirty(hWnd, &bDirty);
  456. }
  457. if (apdd.lpszTitleExt) {
  458. LocalFree(apdd.lpszTitleExt);
  459. }
  460. SetAlarmStatusText(hWnd);
  461. break;
  462. case IDC_LOBATALARMENABLE:
  463. puiPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel);
  464. puiOtherPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel);
  465. uiSliderStatusId = IDC_LOWALARMLEVEL;
  466. goto do_sheet_dirty;
  467. case IDC_CRITBATALARMENABLE:
  468. puiPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_CRITICAL].BatteryLevel);
  469. puiOtherPosVar = &(g_gpp.user.DischargePolicy[DISCHARGE_POLICY_LOW].BatteryLevel);
  470. uiSliderStatusId = IDC_CRITALARMLEVEL;
  471. do_sheet_dirty:
  472. GetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  473. if ((uiEnable = IsDlgButtonChecked(hWnd, (int) wParam)) ==
  474. BST_CHECKED) {
  475. if (uiLoPos < uiCritPos) {
  476. uiLoPos = uiCritPos = *puiPosVar = *puiOtherPosVar;
  477. SetSliderStatusText(hWnd, uiSliderStatusId, uiCritPos);
  478. }
  479. }
  480. SetControls(hWnd, NUM_ALARM_CONTROLS, g_pcAlarm);
  481. SetAlarmStatusText(hWnd);
  482. MarkSheetDirty(hWnd, &bDirty);
  483. break;
  484. }
  485. break;
  486. case WM_HSCROLL:
  487. // Only handle slider controls.
  488. if (((HWND)lParam != hWndLoSlider) &&
  489. ((HWND)lParam != hWndCritSlider)) {
  490. break;
  491. }
  492. // Don't allow the low slider to be set lower than the critical
  493. // slider. Reset position on TB_ENDTRACK for this case.
  494. if (hWndLoSlider == (HWND)lParam) {
  495. puiPos = &uiLoPos;
  496. puiOtherPos = &uiCritPos;
  497. puiEnableState = &g_uiCritState;
  498. uiSliderStatusId = IDC_LOWALARMLEVEL;
  499. }
  500. else {
  501. puiPos = &uiCritPos;
  502. puiOtherPos = &uiLoPos;
  503. puiEnableState = &g_uiLoState;
  504. uiSliderStatusId = IDC_CRITALARMLEVEL;
  505. }
  506. switch (LOWORD(wParam)) {
  507. case TB_ENDTRACK:
  508. bAdjust = FALSE;
  509. if (*puiEnableState & CONTROL_ENABLE) {
  510. if (uiLoPos < uiCritPos) {
  511. *puiPos = *puiOtherPos;
  512. bAdjust = TRUE;
  513. }
  514. }
  515. if (*puiPos < uiDefaultAlert1) {
  516. *puiPos = uiDefaultAlert1;
  517. bAdjust = TRUE;
  518. }
  519. if (bAdjust) {
  520. SendMessage((HWND)lParam, TBM_SETPOS, TRUE,
  521. (LPARAM)*puiPos);
  522. }
  523. break;
  524. case TB_THUMBPOSITION:
  525. case TB_THUMBTRACK:
  526. // New position comes with these messages.
  527. *puiPos = HIWORD(wParam);
  528. break;
  529. default:
  530. // New position must be fetched for the rest.
  531. *puiPos = (UINT) SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
  532. }
  533. // Update the current slider position text.
  534. SetSliderStatusText(hWnd, uiSliderStatusId, *puiPos);
  535. // Enable the parent dialog Apply button on any change.
  536. MarkSheetDirty(hWnd, &bDirty);
  537. break;
  538. case WM_HELP: // F1
  539. WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_AlarmHelpIDs);
  540. return TRUE;
  541. case WM_CONTEXTMENU: // right mouse click
  542. WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_AlarmHelpIDs);
  543. return TRUE;
  544. }
  545. return FALSE;
  546. }
  547. /*******************************************************************************
  548. *
  549. * P R I V A T E F U N C T I O N S
  550. *
  551. *******************************************************************************/
  552. /*******************************************************************************
  553. *
  554. * PathOnly
  555. *
  556. * DESCRIPTION:
  557. *
  558. * PARAMETERS:
  559. *
  560. *******************************************************************************/
  561. BOOL PathOnly(LPTSTR sz)
  562. {
  563. LPTSTR p = sz;
  564. LPTSTR s = NULL;
  565. while ( *p ) {
  566. if ( *p == TEXT('\\') ) {
  567. s = p;
  568. } else if ( *p == TEXT(':') ) {
  569. s = p + 1;
  570. }
  571. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  572. p = AnsiNext(p);
  573. #else
  574. p++;
  575. #endif
  576. }
  577. if ( s ) {
  578. if ( s == sz )
  579. s++;
  580. *s = TEXT('\0');
  581. return TRUE;
  582. }
  583. return FALSE;
  584. }
  585. #ifdef WINNT
  586. /*******************************************************************************
  587. *
  588. * FileNameOnly
  589. *
  590. * DESCRIPTION: Returns a pointer to the first character after the last
  591. * backslash in a string
  592. *
  593. * PARAMETERS:
  594. *
  595. *******************************************************************************/
  596. LPTSTR FileNameOnly(LPTSTR sz)
  597. {
  598. LPTSTR next = sz;
  599. LPTSTR prev;
  600. LPTSTR begin = next;
  601. if (next == NULL) {
  602. return NULL;
  603. }
  604. while ( *next ) {
  605. prev = next;
  606. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  607. next = AnsiNext(next);
  608. #else
  609. next++;
  610. #endif
  611. if ( (*prev == TEXT('\\')) || (*prev == TEXT(':')) ) {
  612. begin = next;
  613. }
  614. }
  615. return begin;
  616. }
  617. /*******************************************************************************
  618. *
  619. * EditWorkItem
  620. *
  621. * DESCRIPTION: Opens the specified task.
  622. *
  623. * PARAMETERS:
  624. *
  625. *******************************************************************************/
  626. void EditWorkItem(HWND hWnd, LPTSTR pszTaskName)
  627. {
  628. ITaskScheduler *pISchedAgent = NULL;
  629. ITask *pITask;
  630. IPersistFile *pIPersistFile;
  631. HRESULT hr;
  632. hr = CoInitialize(NULL);
  633. if (FAILED(hr)) {
  634. MYDBGPRINT(( "EditWorkItem: CoInitialize returned hr = %08x\n", hr));
  635. return;
  636. }
  637. hr = CoCreateInstance( &CLSID_CSchedulingAgent,
  638. NULL,
  639. CLSCTX_INPROC_SERVER,
  640. &IID_ISchedulingAgent,
  641. (LPVOID*)&pISchedAgent);
  642. if (SUCCEEDED(hr)) {
  643. hr = pISchedAgent->lpVtbl->Activate(pISchedAgent,
  644. pszTaskName,
  645. &IID_ITask,
  646. &(IUnknown *)pITask);
  647. if (SUCCEEDED(hr)) {
  648. pITask->lpVtbl->EditWorkItem(pITask, hWnd, 0);
  649. pITask->lpVtbl->Release(pITask);
  650. }
  651. else if (HRESULT_CODE (hr) == ERROR_FILE_NOT_FOUND){
  652. hr = pISchedAgent->lpVtbl->NewWorkItem(
  653. pISchedAgent,
  654. pszTaskName,
  655. &CLSID_CTask,
  656. &IID_ITask,
  657. &(IUnknown *)pITask);
  658. if (SUCCEEDED(hr)) {
  659. hr = pITask->lpVtbl->QueryInterface(pITask, &IID_IPersistFile,
  660. (void **)&pIPersistFile);
  661. if (SUCCEEDED(hr)) {
  662. hr = pIPersistFile->lpVtbl->Save(pIPersistFile, NULL, TRUE);
  663. if (SUCCEEDED(hr)) {
  664. pITask->lpVtbl->EditWorkItem(pITask, hWnd, 0);
  665. }
  666. else {
  667. MYDBGPRINT(( "EditWorkItem: Save filed hr = %08x\n", hr));
  668. }
  669. pIPersistFile->lpVtbl->Release(pIPersistFile);
  670. }
  671. else {
  672. MYDBGPRINT(( "EditWorkItem: QueryInterface for IPersistFile hr = %08x\n", hr));
  673. }
  674. pITask->lpVtbl->Release(pITask);
  675. }
  676. else {
  677. MYDBGPRINT(( "EditWorkItem: Activate returned hr = %08x\n", hr));
  678. }
  679. }
  680. else {
  681. MYDBGPRINT(( "EditWorkItem: NewWorkItem returned hr = %08x\n", hr));
  682. }
  683. pISchedAgent->lpVtbl->Release(pISchedAgent);
  684. }
  685. else {
  686. MYDBGPRINT(( "EditWorkItem: CoCreateInstance returned hr = %08x\n", hr));
  687. }
  688. CoUninitialize();
  689. }
  690. #endif
  691. /*******************************************************************************
  692. *
  693. * SetSliderStatusText
  694. *
  695. * DESCRIPTION:
  696. * Update the current slider position text.
  697. *
  698. * PARAMETERS:
  699. *
  700. *******************************************************************************/
  701. BOOLEAN SetSliderStatusText(HWND hWnd, UINT uiStatusId, UINT uiLevel)
  702. {
  703. LPTSTR pString;
  704. pString = LoadDynamicString(IDS_ALARMLEVELFORMAT,
  705. uiLevel * g_uiBatteryLevelScale);
  706. DisplayFreeStr(hWnd, uiStatusId, pString, FREE_STR);
  707. return TRUE;
  708. }
  709. /*******************************************************************************
  710. *
  711. * SetAlarmStatusText
  712. *
  713. * DESCRIPTION:
  714. *
  715. * PARAMETERS:
  716. *
  717. *******************************************************************************/
  718. BOOLEAN SetAlarmStatusText(HWND hWnd)
  719. {
  720. TCHAR szStatus[MAX_UI_STR_LEN];
  721. LPTSTR lpsz;
  722. UINT uiActionId, uiStatusId, uiIndex, uiAction;
  723. PUINT puiState;
  724. #ifdef WINNT
  725. LPTSTR lpszRunProg;
  726. #endif
  727. puiState = &g_uiCritState;
  728. uiStatusId = IDC_CRITALARMNOTIFICATION;
  729. for (uiIndex = DISCHARGE_POLICY_CRITICAL; uiIndex <= DISCHARGE_POLICY_LOW; uiIndex++) {
  730. // Format the alarm action notification status string.
  731. szStatus[0] = '\0';
  732. if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
  733. POWER_LEVEL_USER_NOTIFY_SOUND) {
  734. if ((lpsz = LoadDynamicString(IDS_ALARMSTATUSSOUND)) != NULL) {
  735. StringCchCat(szStatus, ARRAYSIZE(szStatus), lpsz);
  736. LocalFree(lpsz);
  737. }
  738. }
  739. if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
  740. POWER_LEVEL_USER_NOTIFY_TEXT) {
  741. if (szStatus[0] != '\0') {
  742. StringCchCat(szStatus, ARRAYSIZE(szStatus), TEXT(", "));
  743. }
  744. if ((lpsz = LoadDynamicString(IDS_ALARMSTATUSTEXT)) != NULL) {
  745. StringCchCat(szStatus, ARRAYSIZE(szStatus), lpsz);
  746. LocalFree(lpsz);
  747. }
  748. }
  749. if (szStatus[0] == '\0') {
  750. if ((lpsz = LoadDynamicString(IDS_NOACTION)) != NULL) {
  751. StringCchCat(szStatus, ARRAYSIZE(szStatus), lpsz);
  752. LocalFree(lpsz);
  753. }
  754. }
  755. DisplayFreeStr(hWnd, uiStatusId, szStatus, NO_FREE_STR);
  756. ShowWindow(GetDlgItem(hWnd, uiStatusId),
  757. (*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
  758. uiStatusId++;
  759. // Format the alarm action power mode status string.
  760. uiAction = g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.Action;
  761. switch (uiAction) {
  762. case PowerActionNone:
  763. uiActionId = IDS_NOACTION;
  764. break;
  765. case PowerActionSleep:
  766. uiActionId = IDS_STANDBY;
  767. break;
  768. case PowerActionHibernate:
  769. uiActionId = IDS_HIBERNATE;
  770. break;
  771. case PowerActionShutdown:
  772. case PowerActionShutdownReset:
  773. case PowerActionShutdownOff:
  774. uiActionId = IDS_POWEROFF;
  775. break;
  776. case PowerActionReserved:
  777. default:
  778. MYDBGPRINT(( "SetAlarmStatusText, unable to map power action: %X", uiAction));
  779. uiActionId = IDS_NOACTION;
  780. }
  781. lpsz = LoadDynamicString(uiActionId);
  782. DisplayFreeStr(hWnd, uiStatusId, lpsz, FREE_STR);
  783. ShowWindow(GetDlgItem(hWnd, uiStatusId),
  784. (*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
  785. uiStatusId++;
  786. // Format the alarm action run program status string.
  787. #ifdef WINNT
  788. lpszRunProg = NULL;
  789. if (g_gpp.user.DischargePolicy[uiIndex].PowerPolicy.EventCode &
  790. POWER_LEVEL_USER_NOTIFY_EXEC) {
  791. {
  792. //
  793. // Open up the alarm action task and read the program name.
  794. //
  795. ITaskScheduler *pISchedAgent = NULL;
  796. ITask *pITask;
  797. HRESULT hr;
  798. hr = CoInitialize(NULL);
  799. if (SUCCEEDED(hr)) {
  800. hr = CoCreateInstance( &CLSID_CSchedulingAgent,
  801. NULL,
  802. CLSCTX_INPROC_SERVER,
  803. &IID_ISchedulingAgent,
  804. (LPVOID*)&pISchedAgent);
  805. if (SUCCEEDED(hr)) {
  806. hr = pISchedAgent->lpVtbl->Activate(pISchedAgent,
  807. g_szAlarmTaskName [uiIndex],
  808. &IID_ITask,
  809. &(IUnknown *)pITask);
  810. if (SUCCEEDED(hr)) {
  811. pITask->lpVtbl->GetApplicationName(pITask, &lpszRunProg);
  812. pITask->lpVtbl->Release(pITask);
  813. }
  814. pISchedAgent->lpVtbl->Release(pISchedAgent);
  815. }
  816. else {
  817. MYDBGPRINT(( "SetAlarmStatusText: CoCreateInstance returned hr = %08x\n", hr));
  818. }
  819. CoUninitialize();
  820. }
  821. }
  822. }
  823. if (lpszRunProg != NULL) {
  824. DisplayFreeStr(hWnd, uiStatusId, FileNameOnly(lpszRunProg), NO_FREE_STR);
  825. CoTaskMemFree (lpszRunProg);
  826. lpszRunProg = NULL;
  827. }
  828. else {
  829. lpsz = LoadDynamicString(IDS_NONE);
  830. DisplayFreeStr(hWnd, uiStatusId, lpsz, FREE_STR);
  831. }
  832. ShowWindow(GetDlgItem(hWnd, uiStatusId),
  833. (*puiState & CONTROL_ENABLE) ? SW_SHOW:SW_HIDE);
  834. #endif
  835. uiStatusId++;
  836. puiState = &g_uiLoState;
  837. uiStatusId = IDC_LOALARMNOTIFICATION;
  838. }
  839. return TRUE;
  840. }
  841. #ifdef WINNT
  842. /*******************************************************************************
  843. *
  844. * HideShowRunProgram
  845. *
  846. * DESCRIPTION:
  847. *
  848. * PARAMETERS:
  849. * On WINNT, only power users may set the run program.
  850. * The run program is stored under HKLM.
  851. *
  852. *******************************************************************************/
  853. void HideShowRunProgram(HWND hWnd)
  854. {
  855. if (CanUserWritePwrScheme()) {
  856. ShowWindow(GetDlgItem(hWnd, IDC_POWERCFGGROUPBOX7), SW_SHOW);
  857. ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGCHECKBOX), SW_SHOW);
  858. ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGWORKITEM), SW_SHOW);
  859. }
  860. else {
  861. ShowWindow(GetDlgItem(hWnd, IDC_POWERCFGGROUPBOX7), SW_HIDE);
  862. ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGCHECKBOX), SW_HIDE);
  863. ShowWindow(GetDlgItem(hWnd, IDC_RUNPROGWORKITEM), SW_HIDE);
  864. }
  865. }
  866. #endif