xref: /reactos/dll/cpl/powercfg/powershemes.c (revision 7b1049c8)
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 #include <debug.h>
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     iCurSel = (INT)SendDlgItemMessage(hwndDlg,
249                                           IDC_ENERGYLIST,
250                                           CB_GETCURSEL,
251                                           0,
252                                           0);
253     if (iCurSel == CB_ERR)
254         return;
255 
256     EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN),
257                 (iCurSel > 0));
258 
259     if (pScheme == NULL)
260     {
261         pScheme = (PPOWER_SCHEME)SendDlgItemMessage(hwndDlg,
262                                                     IDC_ENERGYLIST,
263                                                     CB_GETITEMDATA,
264                                                     (WPARAM)iCurSel,
265                                                     0);
266         if (pScheme == (PPOWER_SCHEME)CB_ERR)
267             return;
268     }
269 
270     pPageData->pSelectedPowerScheme = pScheme;
271 
272     if (LoadString(hApplet, IDS_CONFIG1, szTemp, MAX_PATH))
273     {
274         _stprintf(szConfig, szTemp, pScheme->pszName);
275         SetWindowText(GetDlgItem(hwndDlg, IDC_GRPDETAIL), szConfig);
276     }
277 
278     pp = &pScheme->PowerPolicy;
279 
280     for (i = 0; i < 16; i++)
281     {
282         hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORACLIST);
283         if (hwndCtrl != NULL && Sec[i] == pp->user.VideoTimeoutAc)
284         {
285             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
286         }
287 
288         hwndCtrl = GetDlgItem(hwndDlg, IDC_MONITORDCLIST);
289         if (hwndCtrl != NULL && Sec[i] == pp->user.VideoTimeoutDc)
290         {
291             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
292         }
293 
294         hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKACLIST);
295         if (hwndCtrl != NULL && Sec[i] == pp->user.SpindownTimeoutAc)
296         {
297             SendMessage(hwndCtrl, CB_SETCURSEL, i - 2, 0);
298         }
299 
300         hwndCtrl = GetDlgItem(hwndDlg, IDC_DISKDCLIST);
301         if (hwndCtrl != NULL && Sec[i] == pp->user.SpindownTimeoutDc)
302         {
303             SendMessage(hwndCtrl, CB_SETCURSEL, i - 2, 0);
304         }
305 
306         hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYACLIST);
307         if (hwndCtrl != NULL && Sec[i] == pp->user.IdleTimeoutAc)
308         {
309             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
310         }
311 
312         hwndCtrl = GetDlgItem(hwndDlg, IDC_STANDBYDCLIST);
313         if (hwndCtrl != NULL && Sec[i] == pp->user.IdleTimeoutDc)
314         {
315             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
316         }
317 
318         hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEACLIST);
319         if (hwndCtrl != NULL && Sec[i] == pp->mach.DozeS4TimeoutAc)
320         {
321             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
322         }
323 
324         hwndCtrl = GetDlgItem(hwndDlg, IDC_HIBERNATEDCLIST);
325         if (hwndCtrl != NULL && Sec[i] == pp->mach.DozeS4TimeoutDc)
326         {
327             SendMessage(hwndCtrl, CB_SETCURSEL, i, 0);
328         }
329     }
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     }
524 }
525 
526 
527 static
528 BOOL
529 DelScheme(
530     HWND hwnd,
531     PPOWER_SCHEMES_PAGE_DATA pPageData)
532 {
533     WCHAR szTitleBuffer[256];
534     WCHAR szRawBuffer[256], szCookedBuffer[512];
535     INT iCurSel;
536     HWND hList;
537     PPOWER_SCHEME pScheme;
538     WCHAR szErrorText[512];
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             LoadStringW(hApplet, IDS_DEL_SCHEME_ERROR, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
561             MessageBoxW(NULL, szErrorText, NULL, MB_OK | MB_ICONERROR);
562             return FALSE;
563         }
564 
565         iCurSel = SendMessage(hList, CB_FINDSTRING, -1, (LPARAM)pScheme->pszName);
566         if (iCurSel != CB_ERR)
567             SendMessage(hList, CB_DELETESTRING, iCurSel, 0);
568 
569         DeletePowerScheme(pScheme);
570 
571         iCurSel = SendMessage(hList, CB_FINDSTRING, -1, (LPARAM)pPageData->pActivePowerScheme->pszName);
572         if (iCurSel != CB_ERR)
573         {
574             SendMessage(hList, CB_SETCURSEL, iCurSel, 0);
575         }
576         else
577         {
578             SendMessage(hList, CB_SETCURSEL, 0, 0);
579         }
580 
581         LoadConfig(hwnd, pPageData, NULL);
582         return TRUE;
583     }
584 
585     return FALSE;
586 }
587 
588 
589 static
590 BOOL
591 SavePowerScheme(
592     HWND hwndDlg,
593     PSAVE_POWER_SCHEME_DATA pSaveSchemeData)
594 {
595     PPOWER_SCHEMES_PAGE_DATA pPageData;
596     PPOWER_SCHEME pScheme;
597     TCHAR szSchemeName[512];
598     BOOL bRet = FALSE;
599 
600     pPageData = pSaveSchemeData->pPageData;
601 
602     GetDlgItemText(hwndDlg, IDC_SCHEMENAME, szSchemeName, ARRAYSIZE(szSchemeName));
603 
604     pScheme = AddPowerScheme(pPageData,
605                              -1,
606                              (_tcslen(szSchemeName) + 1) * sizeof(TCHAR),
607                              szSchemeName,
608                              sizeof(TCHAR),
609                              TEXT(""),
610                              &pPageData->pSelectedPowerScheme->PowerPolicy);
611     if (pScheme != NULL)
612     {
613         if (WritePwrScheme(&pScheme->uId,
614                            pScheme->pszName,
615                            pScheme->pszDescription,
616                            &pScheme->PowerPolicy))
617         {
618             pSaveSchemeData->pNewScheme = pScheme;
619             bRet = TRUE;
620         }
621         else
622         {
623             DeletePowerScheme(pScheme);
624         }
625     }
626 
627     return bRet;
628 }
629 
630 
631 INT_PTR
632 CALLBACK
633 SaveSchemeDlgProc(
634     HWND hwndDlg,
635     UINT uMsg,
636     WPARAM wParam,
637     LPARAM lParam)
638 {
639     PSAVE_POWER_SCHEME_DATA pSaveSchemeData;
640 
641     pSaveSchemeData = (PSAVE_POWER_SCHEME_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
642 
643     switch (uMsg)
644     {
645         case WM_INITDIALOG:
646             pSaveSchemeData = (PSAVE_POWER_SCHEME_DATA)lParam;
647             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSaveSchemeData);
648 
649             SetDlgItemText(hwndDlg,
650                            IDC_SCHEMENAME,
651                            pSaveSchemeData->pPageData->pSelectedPowerScheme->pszName);
652             return TRUE;
653 
654         case WM_COMMAND:
655             switch(LOWORD(wParam))
656             {
657                 case IDOK:
658                     EndDialog(hwndDlg, SavePowerScheme(hwndDlg, pSaveSchemeData));
659                     break;
660 
661                 case IDCANCEL:
662                     EndDialog(hwndDlg, FALSE);
663                     break;
664             }
665             break;
666     }
667 
668     return FALSE;
669 }
670 
671 
672 static
673 VOID
674 SaveScheme(
675     HWND hwndDlg,
676     PPOWER_SCHEMES_PAGE_DATA pPageData)
677 {
678     SAVE_POWER_SCHEME_DATA SaveSchemeData;
679     POWER_POLICY BackupPowerPolicy;
680     HWND hwndList;
681     INT index;
682 
683     SaveSchemeData.pPageData = pPageData;
684     SaveSchemeData.pNewScheme = NULL;
685     SaveSchemeData.hwndPage = hwndDlg;
686 
687     CopyMemory(&BackupPowerPolicy,
688                &pPageData->pSelectedPowerScheme->PowerPolicy,
689                sizeof(POWER_POLICY));
690 
691     Pos_SaveData(hwndDlg, pPageData);
692 
693     if (DialogBoxParam(hApplet,
694                        MAKEINTRESOURCE(IDD_SAVEPOWERSCHEME),
695                        hwndDlg,
696                        SaveSchemeDlgProc,
697                        (LPARAM)&SaveSchemeData))
698     {
699         if (SaveSchemeData.pNewScheme)
700         {
701             hwndList = GetDlgItem(hwndDlg, IDC_ENERGYLIST);
702 
703             index = (INT)SendDlgItemMessage(hwndDlg,
704                                           IDC_ENERGYLIST,
705                                           CB_FINDSTRING,
706                                           -1,
707                                           (LPARAM)SaveSchemeData.pNewScheme->pszName);
708 
709             if (index == CB_ERR)
710             {
711                 index = (INT)SendMessage(hwndList,
712                                          CB_ADDSTRING,
713                                          0,
714                                          (LPARAM)SaveSchemeData.pNewScheme->pszName);
715                 if (index != CB_ERR)
716                 {
717                     SendMessage(hwndList,
718                                 CB_SETITEMDATA,
719                                 index,
720                                 (LPARAM)SaveSchemeData.pNewScheme);
721 
722                     SendMessage(hwndList, CB_SETCURSEL, (WPARAM)index, 0);
723                     EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN), TRUE);
724                 }
725 
726             }
727             LoadConfig(hwndDlg, pPageData, SaveSchemeData.pNewScheme);
728         }
729     }
730 
731     CopyMemory(&pPageData->pSelectedPowerScheme->PowerPolicy,
732                &BackupPowerPolicy,
733                sizeof(POWER_POLICY));
734 }
735 
736 
737 static BOOL
738 CreateEnergyList(
739     HWND hwndDlg,
740     PPOWER_SCHEMES_PAGE_DATA pPageData)
741 {
742     PLIST_ENTRY ListEntry;
743     PPOWER_SCHEME pScheme;
744     INT index;
745     POWER_POLICY pp;
746     SYSTEM_POWER_CAPABILITIES spc;
747     HWND hwndList;
748     UINT aps = 0;
749 
750     hwndList = GetDlgItem(hwndDlg, IDC_ENERGYLIST);
751 
752     if (!GetActivePwrScheme(&aps))
753         return FALSE;
754 
755     if (!ReadGlobalPwrPolicy(&gGPP))
756         return FALSE;
757 
758     if (!ReadPwrScheme(aps, &pp))
759         return FALSE;
760 
761     if (!ValidatePowerPolicies(&gGPP, 0))
762         return FALSE;
763 
764 /*
765     if (!SetActivePwrScheme(aps, &gGPP, &pp))
766         return FALSE;
767 */
768 
769     if (!GetPwrCapabilities(&spc))
770         return FALSE;
771 
772     if (CanUserWritePwrScheme())
773     {
774         // TODO:
775         // Enable write / delete powerscheme button
776     }
777 
778     Pos_InitPage(hwndDlg);
779 
780     if (!GetActivePwrScheme(&aps))
781         return FALSE;
782 
783     ListEntry = pPageData->PowerSchemesList.Flink;
784     while (ListEntry != &pPageData->PowerSchemesList)
785     {
786         pScheme = CONTAINING_RECORD(ListEntry, POWER_SCHEME, ListEntry);
787 
788         index = (int)SendMessage(hwndList,
789                                  CB_ADDSTRING,
790                                  0,
791                                  (LPARAM)pScheme->pszName);
792         if (index == CB_ERR)
793             break;
794 
795         SendMessage(hwndList,
796                     CB_SETITEMDATA,
797                     index,
798                     (LPARAM)pScheme);
799 
800         if (aps == pScheme->uId)
801         {
802             SendMessage(hwndList,
803                         CB_SELECTSTRING,
804                         TRUE,
805                         (LPARAM)pScheme->pszName);
806 
807             pPageData->pActivePowerScheme = pScheme;
808             LoadConfig(hwndDlg, pPageData, pScheme);
809         }
810 
811         ListEntry = ListEntry->Flink;
812     }
813 
814     if (SendMessage(hwndList, CB_GETCOUNT, 0, 0) > 0)
815     {
816         EnableWindow(GetDlgItem(hwndDlg, IDC_SAVEAS_BTN), TRUE);
817     }
818 
819     return TRUE;
820 }
821 
822 
823 /* Property page dialog callback */
824 INT_PTR CALLBACK
825 PowerSchemesDlgProc(
826     HWND hwndDlg,
827     UINT uMsg,
828     WPARAM wParam,
829     LPARAM lParam)
830 {
831     PPOWER_SCHEMES_PAGE_DATA pPageData;
832 
833     pPageData = (PPOWER_SCHEMES_PAGE_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
834 
835     switch (uMsg)
836     {
837         case WM_INITDIALOG:
838             pPageData = (PPOWER_SCHEMES_PAGE_DATA)HeapAlloc(GetProcessHeap(),
839                                                             HEAP_ZERO_MEMORY,
840                                                             sizeof(POWER_SCHEMES_PAGE_DATA));
841             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPageData);
842 
843             BuildSchemesList(pPageData);
844 
845             if (!Pos_InitData(hwndDlg))
846             {
847                 // TODO:
848                 // Initialization failed
849                 // Handle error
850                 MessageBox(hwndDlg,_T("Pos_InitData failed\n"), NULL, MB_OK);
851             }
852 
853             if (!CreateEnergyList(hwndDlg, pPageData))
854             {
855                 // TODO:
856                 // Initialization failed
857                 // Handle error
858                 MessageBox(hwndDlg,_T("CreateEnergyList failed\n"), NULL, MB_OK);
859             }
860             return TRUE;
861 
862         case WM_DESTROY:
863             if (pPageData)
864             {
865                 DestroySchemesList(pPageData);
866                 HeapFree(GetProcessHeap(), 0, pPageData);
867                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
868             }
869             break;
870 
871         case WM_COMMAND:
872             switch(LOWORD(wParam))
873             {
874                 case IDC_ENERGYLIST:
875                     if (HIWORD(wParam) == CBN_SELCHANGE)
876                     {
877                         LoadConfig(hwndDlg, pPageData, NULL);
878                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
879                     }
880                     break;
881 
882                 case IDC_DELETE_BTN:
883                     DelScheme(hwndDlg, pPageData);
884                     break;
885 
886                 case IDC_SAVEAS_BTN:
887                     SaveScheme(hwndDlg, pPageData);
888                     break;
889 
890                 case IDC_MONITORACLIST:
891                 case IDC_MONITORDCLIST:
892                 case IDC_DISKACLIST:
893                 case IDC_DISKDCLIST:
894                 case IDC_STANDBYACLIST:
895                 case IDC_STANDBYDCLIST:
896                 case IDC_HIBERNATEACLIST:
897                 case IDC_HIBERNATEDCLIST:
898                     if (HIWORD(wParam) == CBN_SELCHANGE)
899                     {
900                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
901                     }
902                     break;
903             }
904             break;
905 
906         case WM_NOTIFY:
907             switch (((LPNMHDR)lParam)->code)
908             {
909                 case PSN_APPLY:
910                     Pos_SaveData(hwndDlg, pPageData);
911                     return TRUE;
912 
913                 case PSN_SETACTIVE:
914                     Pos_InitData(hwndDlg);
915                     return TRUE;
916             }
917             break;
918     }
919 
920     return FALSE;
921 }
922