7d9afb7c80657eef68727ecdd56920f7098a81c9
[reactos.git] / reactos / lib / cpl / desk / settings.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Display Control Panel
5 * FILE: lib/cpl/desk/settings.c
6 * PURPOSE: Settings property page
7 *
8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
9 * Hervé Poussineau (poussine@freesurf.fr)
10 */
11
12 #include <windows.h>
13 #include <commctrl.h>
14 #include <stdio.h>
15 #include <tchar.h>
16 #include <cpl.h>
17
18 #include "resource.h"
19 #include "desk.h"
20
21 /* As slider control can't contain user data, we have to keep an
22 * array of RESOLUTION_INFO to have our own associated data.
23 */
24 typedef struct _RESOLUTION_INFO
25 {
26 DWORD dmPelsWidth;
27 DWORD dmPelsHeight;
28 } RESOLUTION_INFO, *PRESOLUTION_INFO;
29
30 typedef struct _SETTINGS_ENTRY
31 {
32 struct _SETTINGS_ENTRY *Blink;
33 struct _SETTINGS_ENTRY *Flink;
34 DWORD dmBitsPerPel;
35 DWORD dmPelsWidth;
36 DWORD dmPelsHeight;
37 } SETTINGS_ENTRY, *PSETTINGS_ENTRY;
38
39 typedef struct _DISPLAY_DEVICE_ENTRY
40 {
41 struct _DISPLAY_DEVICE_ENTRY *Flink;
42 LPTSTR DeviceDescription;
43 LPTSTR DeviceName;
44 PSETTINGS_ENTRY Settings; /* sorted by increasing dmPelsHeight, BPP */
45 DWORD SettingsCount;
46 PRESOLUTION_INFO Resolutions;
47 DWORD ResolutionsCount;
48 PSETTINGS_ENTRY CurrentSettings; /* Points into Settings list */
49 SETTINGS_ENTRY InitialSettings;
50 } DISPLAY_DEVICE_ENTRY, *PDISPLAY_DEVICE_ENTRY;
51
52 static PDISPLAY_DEVICE_ENTRY DisplayDeviceList = NULL;
53 static PDISPLAY_DEVICE_ENTRY CurrentDisplayDevice = NULL;
54
55 static VOID
56 UpdateDisplay(IN HWND hwndDlg)
57 {
58 TCHAR Buffer[64];
59 TCHAR Pixel[64];
60 DWORD index;
61
62 LoadString(hApplet, IDS_PIXEL, Pixel, sizeof(Pixel) / sizeof(TCHAR));
63 _stprintf(Buffer, Pixel, CurrentDisplayDevice->CurrentSettings->dmPelsWidth, CurrentDisplayDevice->CurrentSettings->dmPelsHeight, Pixel);
64 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT, WM_SETTEXT, 0, (LPARAM)Buffer);
65
66
67 for (index = 0; index < CurrentDisplayDevice->ResolutionsCount; index++)
68 {
69
70 if (CurrentDisplayDevice->Resolutions[index].dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth &&
71 CurrentDisplayDevice->Resolutions[index].dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight)
72 {
73 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETPOS, TRUE, index);
74 break;
75 }
76 }
77 if (LoadString(hApplet, (2900 + CurrentDisplayDevice->CurrentSettings->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR)))
78 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SELECTSTRING, -1, (LPARAM)Buffer);
79 }
80
81 static PSETTINGS_ENTRY
82 GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTINGS_ENTRY* CurrentSettings)
83 {
84 DEVMODE devmode;
85 DWORD NbSettings = 0;
86 DWORD iMode = 0;
87 DWORD dwFlags = 0;
88 PSETTINGS_ENTRY Settings = NULL;
89 HDC hDC;
90 PSETTINGS_ENTRY Current;
91 DWORD bpp, xres, yres, checkbpp;
92
93 /* Get current settings */
94 *CurrentSettings = NULL;
95 hDC = CreateIC(NULL, DeviceName, NULL, NULL);
96 bpp = GetDeviceCaps(hDC, PLANES);
97 bpp *= GetDeviceCaps(hDC, BITSPIXEL);
98 xres = GetDeviceCaps(hDC, HORZRES);
99 yres = GetDeviceCaps(hDC, VERTRES);
100 DeleteDC(hDC);
101
102 /* List all settings */
103 devmode.dmSize = (WORD)sizeof(DEVMODE);
104 devmode.dmDriverExtra = 0;
105 while (EnumDisplaySettingsEx(DeviceName, iMode, &devmode, dwFlags))
106 {
107
108 if (devmode.dmBitsPerPel==8 || devmode.dmBitsPerPel==16 || devmode.dmBitsPerPel==24 || devmode.dmBitsPerPel==32) checkbpp=1;
109 else checkbpp=0;
110
111 if (devmode.dmPelsWidth < 640 ||
112 devmode.dmPelsHeight < 480 || checkbpp == 0)
113 {
114 iMode++;
115 continue;
116 }
117
118 Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
119 if (Current != NULL)
120 {
121 /* Sort resolutions by increasing height, and BPP */
122 PSETTINGS_ENTRY Previous = NULL;
123 PSETTINGS_ENTRY Next = Settings;
124 Current->dmPelsWidth = devmode.dmPelsWidth;
125 Current->dmPelsHeight = devmode.dmPelsHeight;
126 Current->dmBitsPerPel = devmode.dmBitsPerPel;
127 while (Next != NULL && (
128 Next->dmPelsHeight < Current->dmPelsHeight ||
129 (Next->dmPelsHeight == Current->dmPelsHeight && Next->dmBitsPerPel < Current->dmBitsPerPel)))
130 {
131 Previous = Next;
132 Next = Next->Flink;
133 }
134 Current->Blink = Previous;
135 Current->Flink = Next;
136 if (Previous == NULL)
137 Settings = Current;
138 else
139 Previous->Flink = Current;
140 if (Next != NULL)
141 Next->Blink = Current;
142 if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
143 {
144 *CurrentSettings = Current;
145 }
146 NbSettings++;
147 }
148 iMode++;
149 }
150
151 *pSettingsCount = NbSettings;
152 return Settings;
153 }
154
155 static VOID
156 AddDisplayDevice(IN LPTSTR Description, IN LPTSTR DeviceName)
157 {
158 PDISPLAY_DEVICE_ENTRY newEntry = NULL;
159 LPTSTR description = NULL;
160 LPTSTR name = NULL;
161 DWORD descriptionSize;
162 DWORD nameSize;
163 PSETTINGS_ENTRY Current;
164 DWORD ResolutionsCount = 1;
165 DWORD i;
166
167 newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(DISPLAY_DEVICE_ENTRY));
168 if (!newEntry) goto ByeBye;
169
170 newEntry->Settings = GetPossibleSettings(DeviceName, &newEntry->SettingsCount, &newEntry->CurrentSettings);
171 if (!newEntry->Settings) goto ByeBye;
172
173 newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
174 newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
175 newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
176
177 /* Count different resolutions */
178 for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
179 if (Current->Flink != NULL &&
180 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) || (Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
181 ResolutionsCount++;
182 newEntry->Resolutions = HeapAlloc(GetProcessHeap(), 0, ResolutionsCount * sizeof(RESOLUTION_INFO));
183 if (!newEntry->Resolutions) goto ByeBye;
184 newEntry->ResolutionsCount = ResolutionsCount;
185 /* Fill resolutions infos */
186 for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
187 if (Current->Flink == NULL || (Current->Flink != NULL &&
188 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) || (Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
189 {
190 newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
191 newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
192 i++;
193 }
194
195 descriptionSize = (_tcslen(Description) + 1) * sizeof(TCHAR);
196 description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
197 if (!description) goto ByeBye;
198
199 nameSize = (_tcslen(DeviceName) + 1) * sizeof(TCHAR);
200 name = HeapAlloc(GetProcessHeap(), 0, nameSize);
201 if (!name) goto ByeBye;
202
203 memcpy(description, Description, descriptionSize);
204 memcpy(name, DeviceName, nameSize);
205 newEntry->DeviceDescription = description;
206 newEntry->DeviceName = name;
207 newEntry->Flink = DisplayDeviceList;
208 DisplayDeviceList = newEntry;
209 return;
210
211 ByeBye:
212 if (newEntry != NULL)
213 {
214 if (newEntry->Settings != NULL)
215 {
216 Current = newEntry->Settings;
217 while (Current != NULL)
218 {
219 PSETTINGS_ENTRY Next = Current->Flink;
220 HeapFree(GetProcessHeap(), 0, Current);
221 Current = Next;
222 }
223 }
224 if (newEntry->Resolutions != NULL)
225 HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
226 HeapFree(GetProcessHeap(), 0, newEntry);
227 }
228 if (description != NULL)
229 HeapFree(GetProcessHeap(), 0, description);
230 if (name != NULL)
231 HeapFree(GetProcessHeap(), 0, name);
232 }
233
234 static VOID
235 OnDisplayDeviceChanged(IN HWND hwndDlg, IN PDISPLAY_DEVICE_ENTRY pDeviceEntry)
236 {
237 PSETTINGS_ENTRY Current;
238 DWORD index;
239
240 CurrentDisplayDevice = pDeviceEntry; /* Update global variable */
241
242 /* Fill color depths combo box */
243 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_RESETCONTENT, 0, 0);
244 for (Current = pDeviceEntry->Settings; Current != NULL; Current = Current->Flink)
245 {
246 TCHAR Buffer[64];
247 if (LoadString(hApplet, (2900 + Current->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR)))
248 {
249 index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
250 if (index == (DWORD)CB_ERR)
251 {
252 index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_ADDSTRING, 0, (LPARAM)Buffer);
253 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SETITEMDATA, index, Current->dmBitsPerPel);
254 }
255 }
256 }
257
258 /* Fill resolutions slider */
259 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_CLEARTICS, TRUE, 0);
260 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(0, pDeviceEntry->ResolutionsCount - 1));
261
262 UpdateDisplay(hwndDlg);
263 }
264
265 static VOID
266 OnInitDialog(IN HWND hwndDlg)
267 {
268 DWORD Result = 0;
269 DWORD iDevNum = 0;
270 DISPLAY_DEVICE displayDevice;
271
272 /* Get video cards list */
273 displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
274 while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0))
275 {
276 if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0)
277 {
278 AddDisplayDevice(displayDevice.DeviceString, displayDevice.DeviceName);
279 Result++;
280 }
281 iDevNum++;
282 }
283 if (Result == 0)
284 {
285 /* No adapter found */
286 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_BPP), FALSE);
287 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION), FALSE);
288 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT), FALSE);
289 EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_ADVANCED), FALSE);
290 }
291 else if (Result == 1)
292 {
293 /* Single video adapter */
294 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_DEVICE, WM_SETTEXT, 0, (LPARAM)DisplayDeviceList->DeviceDescription);
295 OnDisplayDeviceChanged(hwndDlg, DisplayDeviceList);
296 }
297 else
298 {
299 /* FIXME: multi video adapter */
300 /* FIXME: choose selected adapter being the primary one */
301 }
302 }
303
304 static VOID
305 OnBPPChanged(IN HWND hwndDlg)
306 {
307 /* if new BPP is not compatible with resolution:
308 * 1) try to find the nearest smaller matching resolution
309 * 2) otherwise, get the nearest bigger resolution
310 */
311 PSETTINGS_ENTRY Current;
312 DWORD dmNewBitsPerPel;
313 DWORD index;
314 TCHAR Buffer[64];
315
316 SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, WM_GETTEXT, (WPARAM)(sizeof(Buffer) / sizeof(TCHAR)), (LPARAM)Buffer);
317 index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
318 dmNewBitsPerPel = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_GETITEMDATA, index, 0);
319
320 /* find if new parameters are valid */
321 Current = CurrentDisplayDevice->CurrentSettings;
322 if (dmNewBitsPerPel == Current->dmBitsPerPel)
323 {
324 /* no change */
325 return;
326 }
327
328 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
329
330 if (dmNewBitsPerPel < Current->dmBitsPerPel)
331 {
332 Current = Current->Blink;
333 while (Current != NULL)
334 {
335 if (Current->dmBitsPerPel == dmNewBitsPerPel
336 && Current->dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight
337 && Current->dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
338 {
339 CurrentDisplayDevice->CurrentSettings = Current;
340 UpdateDisplay(hwndDlg);
341 return;
342 }
343 Current = Current->Blink;
344 }
345 }
346 else
347 {
348 Current = Current->Flink;
349 while (Current != NULL)
350 {
351 if (Current->dmBitsPerPel == dmNewBitsPerPel
352 && Current->dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight
353 && Current->dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
354 {
355 CurrentDisplayDevice->CurrentSettings = Current;
356 UpdateDisplay(hwndDlg);
357 return;
358 }
359 Current = Current->Flink;
360 }
361 }
362
363 /* search smaller resolution compatible with current color depth */
364 Current = CurrentDisplayDevice->CurrentSettings->Blink;
365 while (Current != NULL)
366 {
367 if (Current->dmBitsPerPel == dmNewBitsPerPel)
368 {
369 CurrentDisplayDevice->CurrentSettings = Current;
370 UpdateDisplay(hwndDlg);
371 return;
372 }
373 Current = Current->Blink;
374 }
375
376 /* search bigger resolution compatible with current color depth */
377 Current = CurrentDisplayDevice->CurrentSettings->Flink;
378 while (Current != NULL)
379 {
380 if (Current->dmBitsPerPel == dmNewBitsPerPel)
381 {
382 CurrentDisplayDevice->CurrentSettings = Current;
383 UpdateDisplay(hwndDlg);
384 return;
385 }
386 Current = Current->Flink;
387 }
388
389 /* we shouldn't go there */
390 }
391
392 static VOID
393 OnResolutionChanged(IN HWND hwndDlg, IN DWORD NewPosition)
394 {
395 /* if new resolution is not compatible with color depth:
396 * 1) try to find the nearest bigger matching color depth
397 * 2) otherwise, get the nearest smaller color depth
398 */
399 PSETTINGS_ENTRY Current;
400 DWORD dmNewPelsHeight = CurrentDisplayDevice->Resolutions[NewPosition].dmPelsHeight;
401 DWORD dmNewPelsWidth = CurrentDisplayDevice->Resolutions[NewPosition].dmPelsWidth;
402
403 /* find if new parameters are valid */
404 Current = CurrentDisplayDevice->CurrentSettings;
405 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
406 {
407 /* no change */
408 return;
409 }
410
411 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
412
413 if (dmNewPelsHeight < Current->dmPelsHeight)
414 {
415 Current = Current->Blink;
416 while (Current != NULL)
417 {
418 if (Current->dmPelsHeight == dmNewPelsHeight
419 && Current->dmPelsWidth == dmNewPelsWidth
420 && Current->dmBitsPerPel == CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
421 {
422 CurrentDisplayDevice->CurrentSettings = Current;
423 UpdateDisplay(hwndDlg);
424 return;
425 }
426 Current = Current->Blink;
427 }
428 }
429 else
430 {
431 Current = Current->Flink;
432 while (Current != NULL)
433 {
434 if (Current->dmPelsHeight == dmNewPelsHeight
435 && Current->dmPelsWidth == dmNewPelsWidth
436 && Current->dmBitsPerPel == CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
437 {
438 CurrentDisplayDevice->CurrentSettings = Current;
439 UpdateDisplay(hwndDlg);
440 return;
441 }
442 Current = Current->Flink;
443 }
444 }
445
446 /* search bigger color depth compatible with current resolution */
447 Current = CurrentDisplayDevice->CurrentSettings->Flink;
448 while (Current != NULL)
449 {
450 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
451 {
452 CurrentDisplayDevice->CurrentSettings = Current;
453 UpdateDisplay(hwndDlg);
454 return;
455 }
456 Current = Current->Flink;
457 }
458
459 /* search smaller color depth compatible with current resolution */
460 Current = CurrentDisplayDevice->CurrentSettings->Blink;
461 while (Current != NULL)
462 {
463 if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
464 {
465 CurrentDisplayDevice->CurrentSettings = Current;
466 UpdateDisplay(hwndDlg);
467 return;
468 }
469 Current = Current->Blink;
470 }
471
472 /* we shouldn't go there */
473 }
474
475 static VOID
476 OnAdvancedButton()
477 {
478 MessageBox(NULL, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK);
479 }
480
481 /* Property page dialog callback */
482 INT_PTR CALLBACK
483 SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
484 {
485 switch(uMsg)
486 {
487 case WM_INITDIALOG:
488 OnInitDialog(hwndDlg);
489 break;
490 case WM_COMMAND:
491 {
492 DWORD controlId = LOWORD(wParam);
493 DWORD command = HIWORD(wParam);
494
495 if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
496 OnAdvancedButton();
497 else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
498 OnBPPChanged(hwndDlg);
499 break;
500 }
501 case WM_HSCROLL:
502 {
503 switch (LOWORD(wParam))
504 {
505 case TB_LINEUP:
506 case TB_LINEDOWN:
507 case TB_PAGEUP:
508 case TB_PAGEDOWN:
509 case TB_TOP:
510 case TB_BOTTOM:
511 case TB_ENDTRACK:
512 {
513 DWORD newPosition = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_GETPOS, 0, 0);
514 OnResolutionChanged(hwndDlg, newPosition);
515 }
516 }
517 break;
518 }
519 case WM_NOTIFY:
520 {
521 LPNMHDR lpnm = (LPNMHDR)lParam;
522 if (lpnm->code == (UINT)PSN_APPLY)
523 {
524 if (CurrentDisplayDevice->CurrentSettings->dmPelsWidth != CurrentDisplayDevice->InitialSettings.dmPelsWidth
525 || CurrentDisplayDevice->CurrentSettings->dmPelsHeight != CurrentDisplayDevice->InitialSettings.dmPelsHeight
526 || CurrentDisplayDevice->CurrentSettings->dmBitsPerPel != CurrentDisplayDevice->InitialSettings.dmBitsPerPel)
527 {
528 /* FIXME: Need to test changes */
529 /* Apply new settings */
530 LONG rc;
531 DEVMODE devmode;
532 RtlZeroMemory(&devmode, sizeof(DEVMODE));
533 devmode.dmSize = (WORD)sizeof(DEVMODE);
534 devmode.dmPelsWidth = CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
535 devmode.dmPelsHeight = CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
536 devmode.dmBitsPerPel = CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
537 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
538 rc = ChangeDisplaySettingsEx(
539 CurrentDisplayDevice->DeviceName,
540 &devmode,
541 NULL,
542 CDS_UPDATEREGISTRY,
543 NULL);
544 switch (rc)
545 {
546 case DISP_CHANGE_SUCCESSFUL:
547 CurrentDisplayDevice->InitialSettings.dmPelsWidth = CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
548 CurrentDisplayDevice->InitialSettings.dmPelsHeight = CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
549 CurrentDisplayDevice->InitialSettings.dmBitsPerPel = CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
550 break;
551 case DISP_CHANGE_FAILED:
552 MessageBox(NULL, TEXT("Failed to apply new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
553 break;
554 case DISP_CHANGE_RESTART:
555 MessageBox(NULL, TEXT("You need to restart your computer to apply changes."), TEXT("Display settings"), MB_OK | MB_ICONINFORMATION);
556 break;
557 default:
558 MessageBox(NULL, TEXT("Unknown error when applying new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
559 break;
560 }
561 }
562 }
563 break;
564 }
565 case WM_DESTROY:
566 {
567 PDISPLAY_DEVICE_ENTRY Current = DisplayDeviceList;
568 while (Current != NULL)
569 {
570 PDISPLAY_DEVICE_ENTRY Next = Current->Flink;
571 PSETTINGS_ENTRY CurrentSettings = Current->Settings;
572 while (CurrentSettings != NULL)
573 {
574 PSETTINGS_ENTRY NextSettings = CurrentSettings->Flink;
575 HeapFree(GetProcessHeap(), 0, CurrentSettings);
576 CurrentSettings = NextSettings;
577 }
578 HeapFree(GetProcessHeap(), 0, Current);
579 Current = Next;
580 }
581 }
582 }
583 return FALSE;
584 }