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