xref: /reactos/dll/cpl/powercfg/powershemes.c (revision 7eead935)
1 /*
2  * PROJECT:         ReactOS Power Configuration Applet
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            dll/cpl/powercfg/powershemes.c
5  * PURPOSE:         powerschemes tab of applet
6  * PROGRAMMERS:     Alexander Wurzinger (Lohnegrim at gmx dot net)
7  *                  Johannes Anderwald (johannes.anderwald@reactos.org)
8  *                  Martin Rottensteiner
9  *                  Dmitry Chapyshev (lentind@yandex.ru)
10  */
11 
12 #include "powercfg.h"
13 
14 
15 typedef struct _POWER_SCHEME
16 {
17     LIST_ENTRY ListEntry;
18     UINT uId;
19     LPTSTR pszName;
20     LPTSTR pszDescription;
21     POWER_POLICY PowerPolicy;
22 } POWER_SCHEME, *PPOWER_SCHEME;
23 
24 
25 typedef struct _POWER_SCHEMES_PAGE_DATA
26 {
27     LIST_ENTRY PowerSchemesList;
28     PPOWER_SCHEME pActivePowerScheme;
29     PPOWER_SCHEME pSelectedPowerScheme;
30 } POWER_SCHEMES_PAGE_DATA, *PPOWER_SCHEMES_PAGE_DATA;
31 
32 
33 typedef struct _SAVE_POWER_SCHEME_DATA
34 {
35     PPOWER_SCHEMES_PAGE_DATA pPageData;
36     PPOWER_SCHEME pNewScheme;
37     HWND hwndPage;
38 } SAVE_POWER_SCHEME_DATA, *PSAVE_POWER_SCHEME_DATA;
39 
40 
41 UINT Sec[]=
42 {
43     60,
44     120,
45     180,
46     300,
47     600,
48     900,
49     1200,
50     1500,
51     1800,
52     2700,
53     3600,
54     7200,
55     10800,
56     14400,
57     18000,
58     0
59 };
60 
61 
62 static
63 PPOWER_SCHEME
64 AddPowerScheme(
65     PPOWER_SCHEMES_PAGE_DATA pPageData,
66     UINT uId,
67     DWORD dwName,
68     LPTSTR pszName,
69     DWORD dwDescription,
70     LPWSTR pszDescription,
71     PPOWER_POLICY pp)
72 {
73     PPOWER_SCHEME pScheme;
74     BOOL bResult = FALSE;
75 
76     pScheme = HeapAlloc(GetProcessHeap(),
77                         HEAP_ZERO_MEMORY,
78                         sizeof(POWER_SCHEME));
79     if (pScheme == NULL)
80         return NULL;
81 
82     pScheme->uId = uId;
83     CopyMemory(&pScheme->PowerPolicy, pp, sizeof(POWER_POLICY));
84 
85     if (dwName != 0)
86     {
87         pScheme->pszName = HeapAlloc(GetProcessHeap(),
88                                      HEAP_ZERO_MEMORY,
89                                      dwName);
90         if (pScheme->pszName == NULL)
91             goto done;
92 
93         _tcscpy(pScheme->pszName, pszName);
94     }
95 
96     if (dwDescription != 0)
97     {
98         pScheme->pszDescription = HeapAlloc(GetProcessHeap(),
99                                             HEAP_ZERO_MEMORY,
100                                             dwDescription);
101         if (pScheme->pszDescription == NULL)
102             goto done;
103 
104         _tcscpy(pScheme->pszDescription, pszDescription);
105     }
106 
107     InsertTailList(&pPageData->PowerSchemesList, &pScheme->ListEntry);
108     bResult = TRUE;
109 
110 done:
111     if (bResult == FALSE)
112     {
113         if (pScheme->pszName)
114             HeapFree(GetProcessHeap(), 0, pScheme->pszName);
115 
116         if (pScheme->pszDescription)
117             HeapFree(GetProcessHeap(), 0, pScheme->pszDescription);
118 
119         HeapFree(GetProcessHeap(), 0, pScheme);
120         pScheme = NULL;
121     }
122 
123     return pScheme;
124 }
125 
126 
127 static
128 VOID
129 DeletePowerScheme(
130     PPOWER_SCHEME pScheme)
131 {
132     RemoveEntryList(&pScheme->ListEntry);
133 
134     if (pScheme->pszName)
135         HeapFree(GetProcessHeap(), 0, pScheme->pszName);
136 
137     if (pScheme->pszDescription)
138         HeapFree(GetProcessHeap(), 0, pScheme->pszDescription);
139 
140     HeapFree(GetProcessHeap(), 0, pScheme);
141 }
142 
143 
144 static
145 BOOLEAN
146 CALLBACK
147 EnumPowerSchemeCallback(
148     UINT uiIndex,
149     DWORD dwName,
150     LPTSTR pszName,
151     DWORD dwDesc,
152     LPWSTR pszDesc,
153     PPOWER_POLICY pp,
154     LPARAM lParam)
155 {
156     if (ValidatePowerPolicies(0, pp))
157     {
158         AddPowerScheme((PPOWER_SCHEMES_PAGE_DATA)lParam,
159                        uiIndex,
160                        dwName,
161                        pszName,
162                        dwDesc,
163                        pszDesc,
164                        pp);
165     }
166 
167     return TRUE;
168 }
169 
170 static
171 VOID
172 BuildSchemesList(
173     PPOWER_SCHEMES_PAGE_DATA pPageData)
174 {
175     InitializeListHead(&pPageData->PowerSchemesList);
176 
177     EnumPwrSchemes(EnumPowerSchemeCallback, (LPARAM)pPageData);
178 }
179 
180 
181 static
182 VOID
183 DestroySchemesList(
184     PPOWER_SCHEMES_PAGE_DATA pPageData)
185 {
186     PLIST_ENTRY ListEntry;
187     PPOWER_SCHEME pScheme;
188 
189     for (;;)
190     {
191         ListEntry = pPageData->PowerSchemesList.Flink;
192         if (ListEntry == &pPageData->PowerSchemesList)
193             break;
194 
195         pScheme = CONTAINING_RECORD(ListEntry, POWER_SCHEME, ListEntry);
196         DeletePowerScheme(pScheme);
197     }
198 
199     pPageData->pActivePowerScheme = NULL;
200     pPageData->pSelectedPowerScheme = NULL;
201 }
202 
203 
204 BOOLEAN
205 Pos_InitData(
206     HWND hwndDlg)
207 {
208     SYSTEM_POWER_CAPABILITIES spc;
209 
210     if (!GetPwrCapabilities(&spc))
211     {
212         return FALSE;
213     }
214 
215     ShowWindow(GetDlgItem(hwndDlg, IDC_STANDBY),
216                (spc.SystemS1 || spc.SystemS2 || spc.SystemS3) ? SW_SHOW : SW_HIDE);
217     ShowWindow(GetDlgItem(hwndDlg, IDC_STANDBYACLIST),
218                (spc.SystemS1 || spc.SystemS2 || spc.SystemS3) ? SW_SHOW : SW_HIDE);
219     if (spc.SystemBatteriesPresent)
220         ShowWindow(GetDlgItem(hwndDlg, IDC_STANDBYDCLIST),
221                    (spc.SystemS1 || spc.SystemS2 || spc.SystemS3) ? SW_SHOW : SW_HIDE);
222 
223     ShowWindow(GetDlgItem(hwndDlg, IDC_HIBERNATE),
224                (spc.HiberFilePresent) ? SW_SHOW : SW_HIDE);
225     ShowWindow(GetDlgItem(hwndDlg, IDC_HIBERNATEACLIST),
226                (spc.HiberFilePresent) ? SW_SHOW : SW_HIDE);
227     if (spc.SystemBatteriesPresent)
228         ShowWindow(GetDlgItem(hwndDlg, IDC_HIBERNATEDCLIST),
229                    (spc.HiberFilePresent) ? SW_SHOW : SW_HIDE);
230 
231     return TRUE;
232 }
233 
234 
235 static
236 VOID
237 LoadConfig(
238     HWND hwndDlg,
239     PPOWER_SCHEMES_PAGE_DATA pPageData,
240     PPOWER_SCHEME pScheme)
241 {
242     INT i = 0, iCurSel = 0;
243     TCHAR szTemp[MAX_PATH];
244     TCHAR szConfig[MAX_PATH];
245     PPOWER_POLICY pp;
246     HWND hwndCtrl;
247 
248     if (pScheme == NULL)
249     {
250         iCurSel = (INT)SendDlgItemMessage(hwndDlg,
251                                           IDC_ENERGYLIST,
252                                           CB_GETCURSEL,
253                                           0,
254                                           0);
255         if (iCurSel == CB_ERR)
256             return;
257 
258         pScheme = (PPOWER_SCHEME)SendDlgItemMessage(hwndDlg,
259                                                     IDC_ENERGYLIST,
260                                                     CB_GETITEMDATA,
261                                                     (WPARAM)iCurSel,
262                                                     0);
263         if (pScheme == (PPOWER_SCHEME)CB_ERR)
264             return;
265     }
266 
267     pPageData->pSelectedPowerScheme = pScheme;
268 
269     if (LoadString(hApplet, IDS_CONFIG1, szTemp, MAX_PATH))
270     {
271         _stprintf(szConfig, szTemp, pScheme->pszName);
272         SetWindowText(GetDlgItem(hwndDlg, IDC_GRPDETAIL), szConfig);
273     }
274 
275     pp = &pScheme->PowerPolicy;
276 
277     for (i = 0; i < 16; i++)
278     {
279         hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORACLIST);
280         if (hwndCtrl != NULL && Sec[i] == pp->user.VideoTimeoutAc)
281         {
282             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
283         }
284 
285         hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORDCLIST);
286         if (hwndCtrl != NULL && Sec[i] == pp->user.VideoTimeoutDc)
287         {
288             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
289         }
290 
291         hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKACLIST);
292         if (hwndCtrl != NULL && Sec[i] == pp->user.SpindownTimeoutAc)
293         {
294             SendMessage(hwndCtrl, CB_SETCURSEL, i - 2, 0);
295         }
296 
297         hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKDCLIST);
298         if (hwndCtrl != NULL && Sec[i] == pp->user.SpindownTimeoutDc)
299         {
300             SendMessage(hwndCtrl, CB_SETCURSEL, i - 2, 0);
301         }
302 
303         hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYACLIST);
304         if (hwndCtrl != NULL && Sec[i] == pp->user.IdleTimeoutAc)
305         {
306             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
307         }
308 
309         hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYDCLIST);
310         if (hwndCtrl != NULL && Sec[i] == pp->user.IdleTimeoutDc)
311         {
312             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
313         }
314 
315         hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEACLIST);
316         if (hwndCtrl != NULL && Sec[i] == pp->mach.DozeS4TimeoutAc)
317         {
318             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
319         }
320 
321         hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEDCLIST);
322         if (hwndCtrl != NULL && Sec[i] == pp->mach.DozeS4TimeoutDc)
323         {
324             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
325         }
326     }
327 
328     EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN),
329                  (pScheme != pPageData->pActivePowerScheme));
330 }
331 
332 
333 static VOID
334 Pos_InitPage(HWND hwndDlg)
335 {
336     int ifrom = 0, i = 0, imin = 0;
337     HWND hwnd = NULL;
338     TCHAR szName[MAX_PATH];
339     LRESULT index;
340 
341     for (i = 1; i < 9; i++)
342     {
343         switch (i)
344         {
345             case 1:
346                 hwnd = GetDlgItem(hwndDlg, IDC_MONITORACLIST);
347                 imin = IDS_TIMEOUT1;
348                 break;
349 
350             case 2:
351                 hwnd = GetDlgItem(hwndDlg, IDC_STANDBYACLIST);
352                 imin = IDS_TIMEOUT1;
353                 break;
354 
355             case 3:
356                 hwnd = GetDlgItem(hwndDlg, IDC_DISKACLIST);
357                 imin = IDS_TIMEOUT3;
358                 break;
359 
360             case 4:
361                 hwnd = GetDlgItem(hwndDlg, IDC_HIBERNATEACLIST);
362                 imin = IDS_TIMEOUT3;
363                 break;
364 
365             case 5:
366                 hwnd = GetDlgItem(hwndDlg, IDC_MONITORDCLIST);
367                 imin = IDS_TIMEOUT1;
368                 break;
369 
370             case 6:
371                 hwnd = GetDlgItem(hwndDlg, IDC_STANDBYDCLIST);
372                 imin = IDS_TIMEOUT1;
373                 break;
374 
375             case 7:
376                 hwnd = GetDlgItem(hwndDlg, IDC_DISKDCLIST);
377                 imin = IDS_TIMEOUT3;
378                 break;
379 
380             case 8:
381                 hwnd = GetDlgItem(hwndDlg, IDC_HIBERNATEDCLIST);
382                 imin = IDS_TIMEOUT3;
383                 break;
384 
385             default:
386                 hwnd = NULL;
387                 return;
388         }
389 
390         if (hwnd == NULL)
391             continue;
392 
393         for (ifrom = imin; ifrom < (IDS_TIMEOUT15 + 1); ifrom++)
394         {
395             if (LoadString(hApplet, ifrom, szName, MAX_PATH))
396             {
397                 index = SendMessage(hwnd,
398                                      CB_ADDSTRING,
399                                      0,
400                                     (LPARAM)szName);
401                 if (index == CB_ERR)
402                     return;
403 
404                 SendMessage(hwnd,
405                              CB_SETITEMDATA,
406                              index,
407                              (LPARAM)Sec[ifrom - IDS_TIMEOUT16]);
408             }
409         }
410 
411         if (LoadString(hApplet, IDS_TIMEOUT16, szName, MAX_PATH))
412         {
413             index = SendMessage(hwnd,
414                                  CB_ADDSTRING,
415                                  0,
416                                  (LPARAM)szName);
417             if (index == CB_ERR)
418                 return;
419 
420             SendMessage(hwnd,
421                          CB_SETITEMDATA,
422                          index,
423                          (LPARAM)Sec[0]);
424         }
425     }
426 }
427 
428 
429 static VOID
430 Pos_SaveData(
431     HWND hwndDlg,
432     PPOWER_SCHEMES_PAGE_DATA pPageData)
433 {
434     PPOWER_SCHEME pScheme;
435     HWND hwndCtrl;
436     INT tmp;
437 
438     pScheme = pPageData->pSelectedPowerScheme;
439 
440     hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORACLIST);
441     if (hwndCtrl != NULL)
442     {
443         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
444         if (tmp > 0 && tmp < 16)
445         {
446             pScheme->PowerPolicy.user.VideoTimeoutAc = Sec[tmp];
447         }
448     }
449 
450     hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORDCLIST);
451     if (hwndCtrl != NULL)
452     {
453         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
454         if (tmp > 0 && tmp < 16)
455         {
456             pScheme->PowerPolicy.user.VideoTimeoutDc = Sec[tmp];
457         }
458     }
459 
460     hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKACLIST);
461     if (hwndCtrl != NULL)
462     {
463         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
464         if (tmp > 0 && tmp < 16)
465         {
466             pScheme->PowerPolicy.user.SpindownTimeoutAc = Sec[tmp + 2];
467         }
468     }
469 
470     hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKDCLIST);
471     if (hwndCtrl != NULL)
472     {
473         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
474         if (tmp > 0 && tmp < 16)
475         {
476             pScheme->PowerPolicy.user.SpindownTimeoutDc = Sec[tmp + 2];
477         }
478     }
479 
480     hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYACLIST);
481     if (hwndCtrl != NULL)
482     {
483         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
484         if (tmp > 0 && tmp < 16)
485         {
486             pScheme->PowerPolicy.user.IdleTimeoutAc = Sec[tmp];
487         }
488     }
489 
490     hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYDCLIST);
491     if (hwndCtrl != NULL)
492     {
493         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
494         if (tmp > 0 && tmp < 16)
495         {
496             pScheme->PowerPolicy.user.IdleTimeoutDc = Sec[tmp];
497         }
498     }
499 
500     hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEACLIST);
501     if (hwndCtrl != NULL)
502     {
503         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
504         if (tmp > 0 && tmp < 16)
505         {
506             pScheme->PowerPolicy.mach.DozeS4TimeoutAc = Sec[tmp];
507         }
508     }
509 
510     hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEDCLIST);
511     if (hwndCtrl != NULL)
512     {
513         tmp = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0);
514         if (tmp > 0 && tmp < 16)
515         {
516             pScheme->PowerPolicy.mach.DozeS4TimeoutDc = Sec[tmp];
517         }
518     }
519 
520     if (SetActivePwrScheme(pScheme->uId, NULL, &pScheme->PowerPolicy))
521     {
522         pPageData->pActivePowerScheme = pScheme;
523         EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN), FALSE);
524     }
525 }
526 
527 
528 static
529 BOOL
530 DelScheme(
531     HWND hwnd,
532     PPOWER_SCHEMES_PAGE_DATA pPageData)
533 {
534     WCHAR szTitleBuffer[256];
535     WCHAR szRawBuffer[256], szCookedBuffer[512];
536     INT iCurSel;
537     HWND hList;
538     PPOWER_SCHEME pScheme;
539 
540     hList = GetDlgItem(hwnd, IDC_ENERGYLIST);
541 
542     iCurSel = SendMessage(hList, CB_GETCURSEL, 0, 0);
543     if (iCurSel == CB_ERR)
544         return FALSE;
545 
546     SendMessage(hList, CB_SETCURSEL, iCurSel, 0);
547 
548     pScheme = (PPOWER_SCHEME)SendMessage(hList, CB_GETITEMDATA, (WPARAM)iCurSel, 0);
549     if (pScheme == (PPOWER_SCHEME)CB_ERR)
550         return FALSE;
551 
552     LoadStringW(hApplet, IDS_DEL_SCHEME_TITLE, szTitleBuffer, ARRAYSIZE(szTitleBuffer));
553     LoadStringW(hApplet, IDS_DEL_SCHEME, szRawBuffer, ARRAYSIZE(szRawBuffer));
554     StringCchPrintfW(szCookedBuffer, ARRAYSIZE(szCookedBuffer), szRawBuffer, pScheme->pszName);
555 
556     if (MessageBoxW(hwnd, szCookedBuffer, szTitleBuffer, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)
557     {
558         if (!DeletePwrScheme(pScheme->uId))
559         {
560             // FIXME: Show an error message box
561             return FALSE;
562         }
563 
564         iCurSel = SendMessage(hList, CB_FINDSTRING, -1, (LPARAM)pScheme->pszName);
565         if (iCurSel != CB_ERR)
566             SendMessage(hList, CB_DELETESTRING, iCurSel, 0);
567 
568         DeletePowerScheme(pScheme);
569 
570         iCurSel = SendMessage(hList, CB_FINDSTRING, -1, (LPARAM)pPageData->pActivePowerScheme->pszName);
571         if (iCurSel != CB_ERR)
572             SendMessage(hList, CB_SETCURSEL, iCurSel, 0);
573 
574         LoadConfig(hwnd, pPageData, NULL);
575         return TRUE;
576     }
577 
578     return FALSE;
579 }
580 
581 
582 static
583 BOOL
584 SavePowerScheme(
585     HWND hwndDlg,
586     PSAVE_POWER_SCHEME_DATA pSaveSchemeData)
587 {
588     PPOWER_SCHEMES_PAGE_DATA pPageData;
589     PPOWER_SCHEME pScheme;
590     TCHAR szSchemeName[512];
591     BOOL bRet = FALSE;
592 
593     pPageData = pSaveSchemeData->pPageData;
594 
595     GetDlgItemText(hwndDlg, IDC_SCHEMENAME, szSchemeName, ARRAYSIZE(szSchemeName));
596 
597     pScheme = AddPowerScheme(pPageData,
598                              -1,
599                              (_tcslen(szSchemeName) + 1) * sizeof(TCHAR),
600                              szSchemeName,
601                              sizeof(TCHAR),
602                              TEXT(""),
603                              &pPageData->pSelectedPowerScheme->PowerPolicy);
604     if (pScheme != NULL)
605     {
606         if (WritePwrScheme(&pScheme->uId,
607                            pScheme->pszName,
608                            pScheme->pszDescription,
609                            &pScheme->PowerPolicy))
610         {
611             pSaveSchemeData->pNewScheme = pScheme;
612             bRet = TRUE;
613         }
614         else
615         {
616             DeletePowerScheme(pScheme);
617         }
618     }
619 
620     return bRet;
621 }
622 
623 
624 INT_PTR
625 CALLBACK
626 SaveSchemeDlgProc(
627     HWND hwndDlg,
628     UINT uMsg,
629     WPARAM wParam,
630     LPARAM lParam)
631 {
632     PSAVE_POWER_SCHEME_DATA pSaveSchemeData;
633 
634     pSaveSchemeData = (PSAVE_POWER_SCHEME_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
635 
636     switch (uMsg)
637     {
638         case WM_INITDIALOG:
639             pSaveSchemeData = (PSAVE_POWER_SCHEME_DATA)lParam;
640             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSaveSchemeData);
641 
642             SetDlgItemText(hwndDlg,
643                            IDC_SCHEMENAME,
644                            pSaveSchemeData->pPageData->pSelectedPowerScheme->pszName);
645             return TRUE;
646 
647         case WM_COMMAND:
648             switch(LOWORD(wParam))
649             {
650                 case IDOK:
651                     EndDialog(hwndDlg, SavePowerScheme(hwndDlg, pSaveSchemeData));
652                     break;
653 
654                 case IDCANCEL:
655                     EndDialog(hwndDlg, FALSE);
656                     break;
657             }
658             break;
659     }
660 
661     return FALSE;
662 }
663 
664 
665 static
666 VOID
667 SaveScheme(
668     HWND hwndDlg,
669     PPOWER_SCHEMES_PAGE_DATA pPageData)
670 {
671     SAVE_POWER_SCHEME_DATA SaveSchemeData;
672     POWER_POLICY BackupPowerPolicy;
673     HWND hwndList;
674     INT index;
675 
676     SaveSchemeData.pPageData = pPageData;
677     SaveSchemeData.pNewScheme = NULL;
678     SaveSchemeData.hwndPage = hwndDlg;
679 
680     CopyMemory(&BackupPowerPolicy,
681                &pPageData->pSelectedPowerScheme->PowerPolicy,
682                sizeof(POWER_POLICY));
683 
684     Pos_SaveData(hwndDlg, pPageData);
685 
686     if (DialogBoxParam(hApplet,
687                        MAKEINTRESOURCE(IDD_SAVEPOWERSCHEME),
688                        hwndDlg,
689                        SaveSchemeDlgProc,
690                        (LPARAM)&SaveSchemeData))
691     {
692         if (SaveSchemeData.pNewScheme)
693         {
694             hwndList = GetDlgItem(hwndDlg, IDC_ENERGYLIST);
695 
696             index = (INT)SendMessage(hwndList,
697                                      CB_ADDSTRING,
698                                      0,
699                                      (LPARAM)SaveSchemeData.pNewScheme->pszName);
700             if (index != CB_ERR)
701             {
702                 SendMessage(hwndList,
703                             CB_SETITEMDATA,
704                             index,
705                             (LPARAM)SaveSchemeData.pNewScheme);
706 
707                 SendMessage(hwndList, CB_SETCURSEL, (WPARAM)index, 0);
708 
709                 LoadConfig(hwndDlg, pPageData, SaveSchemeData.pNewScheme);
710             }
711         }
712     }
713 
714     CopyMemory(&pPageData->pSelectedPowerScheme->PowerPolicy,
715                &BackupPowerPolicy,
716                sizeof(POWER_POLICY));
717 }
718 
719 
720 static BOOL
721 CreateEnergyList(
722     HWND hwndDlg,
723     PPOWER_SCHEMES_PAGE_DATA pPageData)
724 {
725     PLIST_ENTRY ListEntry;
726     PPOWER_SCHEME pScheme;
727     INT index;
728     POWER_POLICY pp;
729     SYSTEM_POWER_CAPABILITIES spc;
730     HWND hwndList;
731     UINT aps = 0;
732 
733     hwndList = GetDlgItem(hwndDlg, IDC_ENERGYLIST);
734 
735     if (!GetActivePwrScheme(&aps))
736         return FALSE;
737 
738     if (!ReadGlobalPwrPolicy(&gGPP))
739         return FALSE;
740 
741     if (!ReadPwrScheme(aps, &pp))
742         return FALSE;
743 
744     if (!ValidatePowerPolicies(&gGPP, 0))
745         return FALSE;
746 
747 /*
748     if (!SetActivePwrScheme(aps, &gGPP, &pp))
749         return FALSE;
750 */
751 
752     if (!GetPwrCapabilities(&spc))
753         return FALSE;
754 
755     if (CanUserWritePwrScheme())
756     {
757         // TODO:
758         // Enable write / delete powerscheme button
759     }
760 
761     Pos_InitPage(hwndDlg);
762 
763     if (!GetActivePwrScheme(&aps))
764         return FALSE;
765 
766     ListEntry = pPageData->PowerSchemesList.Flink;
767     while (ListEntry != &pPageData->PowerSchemesList)
768     {
769         pScheme = CONTAINING_RECORD(ListEntry, POWER_SCHEME, ListEntry);
770 
771         index = (int)SendMessage(hwndList,
772                                  CB_ADDSTRING,
773                                  0,
774                                  (LPARAM)pScheme->pszName);
775         if (index == CB_ERR)
776             break;
777 
778         SendMessage(hwndList,
779                     CB_SETITEMDATA,
780                     index,
781                     (LPARAM)pScheme);
782 
783         if (aps == pScheme->uId)
784         {
785             SendMessage(hwndList,
786                         CB_SELECTSTRING,
787                         TRUE,
788                         (LPARAM)pScheme->pszName);
789 
790             pPageData->pActivePowerScheme = pScheme;
791             LoadConfig(hwndDlg, pPageData, pScheme);
792         }
793 
794         ListEntry = ListEntry->Flink;
795     }
796 
797     if (SendMessage(hwndList, CB_GETCOUNT, 0, 0) > 0)
798     {
799         EnableWindow(GetDlgItem(hwndDlg, IDC_SAVEAS_BTN), TRUE);
800     }
801 
802     return TRUE;
803 }
804 
805 
806 /* Property page dialog callback */
807 INT_PTR CALLBACK
808 PowerSchemesDlgProc(
809     HWND hwndDlg,
810     UINT uMsg,
811     WPARAM wParam,
812     LPARAM lParam)
813 {
814     PPOWER_SCHEMES_PAGE_DATA pPageData;
815 
816     pPageData = (PPOWER_SCHEMES_PAGE_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
817 
818     switch (uMsg)
819     {
820         case WM_INITDIALOG:
821             pPageData = (PPOWER_SCHEMES_PAGE_DATA)HeapAlloc(GetProcessHeap(),
822                                                             HEAP_ZERO_MEMORY,
823                                                             sizeof(POWER_SCHEMES_PAGE_DATA));
824             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPageData);
825 
826             BuildSchemesList(pPageData);
827 
828             if (!Pos_InitData(hwndDlg))
829             {
830                 // TODO:
831                 // Initialization failed
832                 // Handle error
833                 MessageBox(hwndDlg,_T("Pos_InitData failed\n"), NULL, MB_OK);
834             }
835 
836             if (!CreateEnergyList(hwndDlg, pPageData))
837             {
838                 // TODO:
839                 // Initialization failed
840                 // Handle error
841                 MessageBox(hwndDlg,_T("CreateEnergyList failed\n"), NULL, MB_OK);
842             }
843             return TRUE;
844 
845         case WM_DESTROY:
846             if (pPageData)
847             {
848                 DestroySchemesList(pPageData);
849                 HeapFree(GetProcessHeap(), 0, pPageData);
850                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
851             }
852             break;
853 
854         case WM_COMMAND:
855             switch(LOWORD(wParam))
856             {
857                 case IDC_ENERGYLIST:
858                     if (HIWORD(wParam) == CBN_SELCHANGE)
859                     {
860                         LoadConfig(hwndDlg, pPageData, NULL);
861                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
862                     }
863                     break;
864 
865                 case IDC_DELETE_BTN:
866                     DelScheme(hwndDlg, pPageData);
867                     break;
868 
869                 case IDC_SAVEAS_BTN:
870                     SaveScheme(hwndDlg, pPageData);
871                     break;
872 
873                 case IDC_MONITORACLIST:
874                 case IDC_MONITORDCLIST:
875                 case IDC_DISKACLIST:
876                 case IDC_DISKDCLIST:
877                 case IDC_STANDBYACLIST:
878                 case IDC_STANDBYDCLIST:
879                 case IDC_HIBERNATEACLIST:
880                 case IDC_HIBERNATEDCLIST:
881                     if (HIWORD(wParam) == CBN_SELCHANGE)
882                     {
883                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
884                     }
885                     break;
886             }
887             break;
888 
889         case WM_NOTIFY:
890             switch (((LPNMHDR)lParam)->code)
891             {
892                 case PSN_APPLY:
893                     Pos_SaveData(hwndDlg, pPageData);
894                     return TRUE;
895 
896                 case PSN_SETACTIVE:
897                     Pos_InitData(hwndDlg);
898                     return TRUE;
899             }
900             break;
901     }
902 
903     return FALSE;
904 }
905