2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: dll/cpl/desk/settings.c
5 * PURPOSE: Settings property page
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Hervé Poussineau (hpoussin@reactos.org)
15 PDISPLAY_DEVICE_ENTRY DisplayDeviceList
;
16 PDISPLAY_DEVICE_ENTRY CurrentDisplayDevice
;
17 HBITMAP hSpectrumBitmaps
[NUM_SPECTRUM_BITMAPS
];
18 int cxSource
[NUM_SPECTRUM_BITMAPS
];
19 int cySource
[NUM_SPECTRUM_BITMAPS
];
24 UpdateDisplay(IN HWND hwndDlg
, PDATA pData
, IN BOOL bUpdateThumb
)
32 LoadString(hApplet
, IDS_PIXEL
, Pixel
, sizeof(Pixel
) / sizeof(TCHAR
));
33 _stprintf(Buffer
, Pixel
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
, Pixel
);
34 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION_TEXT
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
36 for (index
= 0; index
< pData
->CurrentDisplayDevice
->ResolutionsCount
; index
++)
38 if (pData
->CurrentDisplayDevice
->Resolutions
[index
].dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
&&
39 pData
->CurrentDisplayDevice
->Resolutions
[index
].dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
)
42 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_SETPOS
, TRUE
, index
);
46 if (LoadString(hApplet
, (2900 + pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
), Buffer
, sizeof(Buffer
) / sizeof(TCHAR
)))
47 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_SELECTSTRING
, (WPARAM
)-1, (LPARAM
)Buffer
);
49 hwndMonSel
= GetDlgItem(hwndDlg
, IDC_SETTINGS_MONSEL
);
50 index
= (INT
)SendMessage(hwndMonSel
, MSLM_GETCURSEL
, 0, 0);
51 if (index
!= (DWORD
)-1 && SendMessage(hwndMonSel
, MSLM_GETMONITORINFO
, index
, (LPARAM
)&info
))
53 info
.Size
.cx
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
54 info
.Size
.cy
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
55 SendMessage(hwndMonSel
, MSLM_SETMONITORINFO
, index
, (LPARAM
)&info
);
60 CompareSettings(PSETTINGS_ENTRY Entry
, DWORD dmPelsWidth
, DWORD dmPelsHeight
,
61 DWORD dmBitsPerPel
, DWORD dmDisplayFrequency
)
63 if (Entry
->dmPelsWidth
== dmPelsWidth
&&
64 Entry
->dmPelsHeight
== dmPelsHeight
&&
65 Entry
->dmBitsPerPel
== dmBitsPerPel
&&
66 Entry
->dmDisplayFrequency
== dmDisplayFrequency
)
71 if ((Entry
->dmPelsWidth
< dmPelsWidth
) ||
72 (Entry
->dmPelsWidth
== dmPelsWidth
&& Entry
->dmPelsHeight
< dmPelsHeight
) ||
73 (Entry
->dmPelsWidth
== dmPelsWidth
&& Entry
->dmPelsHeight
== dmPelsHeight
&&
74 Entry
->dmBitsPerPel
< dmBitsPerPel
))
81 static PSETTINGS_ENTRY
82 GetPossibleSettings(IN LPCTSTR DeviceName
, OUT DWORD
* pSettingsCount
, OUT PSETTINGS_ENTRY
* CurrentSettings
)
88 PSETTINGS_ENTRY Settings
= NULL
;
90 PSETTINGS_ENTRY Current
;
91 DWORD bpp
, xres
, yres
;
94 /* Get current settings */
95 *CurrentSettings
= NULL
;
96 hDC
= CreateIC(NULL
, DeviceName
, NULL
, NULL
);
97 bpp
= GetDeviceCaps(hDC
, PLANES
);
98 bpp
*= GetDeviceCaps(hDC
, BITSPIXEL
);
99 xres
= GetDeviceCaps(hDC
, HORZRES
);
100 yres
= GetDeviceCaps(hDC
, VERTRES
);
103 /* List all settings */
104 devmode
.dmSize
= (WORD
)sizeof(DEVMODE
);
105 devmode
.dmDriverExtra
= 0;
107 if (!EnumDisplaySettingsEx(DeviceName
, ENUM_CURRENT_SETTINGS
, &devmode
, dwFlags
))
110 curDispFreq
= devmode
.dmDisplayFrequency
;
112 while (EnumDisplaySettingsEx(DeviceName
, iMode
, &devmode
, dwFlags
))
116 if (devmode
.dmPelsWidth
< 640 ||
117 devmode
.dmPelsHeight
< 480 ||
118 devmode
.dmDisplayFrequency
!= curDispFreq
||
119 (devmode
.dmBitsPerPel
!= 4 &&
120 devmode
.dmBitsPerPel
!= 8 &&
121 devmode
.dmBitsPerPel
!= 16 &&
122 devmode
.dmBitsPerPel
!= 24 &&
123 devmode
.dmBitsPerPel
!= 32))
128 Current
= HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY
));
131 /* Sort resolutions by increasing height, and BPP */
132 PSETTINGS_ENTRY Previous
= NULL
;
133 PSETTINGS_ENTRY Next
= Settings
;
134 Current
->dmPelsWidth
= devmode
.dmPelsWidth
;
135 Current
->dmPelsHeight
= devmode
.dmPelsHeight
;
136 Current
->dmBitsPerPel
= devmode
.dmBitsPerPel
;
137 Current
->dmDisplayFrequency
= devmode
.dmDisplayFrequency
;
138 while (Next
!= NULL
&&
139 CompareSettings(Next
, devmode
.dmPelsWidth
,
140 devmode
.dmPelsHeight
, devmode
.dmBitsPerPel
,
141 devmode
.dmDisplayFrequency
) > 0)
146 Current
->Blink
= Previous
;
147 Current
->Flink
= Next
;
148 if (Previous
== NULL
)
151 Previous
->Flink
= Current
;
153 Next
->Blink
= Current
;
154 if (devmode
.dmPelsWidth
== xres
&& devmode
.dmPelsHeight
== yres
&& devmode
.dmBitsPerPel
== bpp
)
156 *CurrentSettings
= Current
;
162 *pSettingsCount
= NbSettings
;
167 AddDisplayDevice(IN PDATA pData
, IN
const DISPLAY_DEVICE
*DisplayDevice
)
169 PDISPLAY_DEVICE_ENTRY newEntry
= NULL
;
170 LPTSTR description
= NULL
;
174 SIZE_T descriptionSize
, nameSize
, keySize
, devidSize
;
175 PSETTINGS_ENTRY Current
;
176 DWORD ResolutionsCount
= 1;
179 newEntry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DISPLAY_DEVICE_ENTRY
));
180 if (!newEntry
) goto ByeBye
;
182 newEntry
->Settings
= GetPossibleSettings(DisplayDevice
->DeviceName
, &newEntry
->SettingsCount
, &newEntry
->CurrentSettings
);
183 if (!newEntry
->Settings
) goto ByeBye
;
185 newEntry
->InitialSettings
.dmPelsWidth
= newEntry
->CurrentSettings
->dmPelsWidth
;
186 newEntry
->InitialSettings
.dmPelsHeight
= newEntry
->CurrentSettings
->dmPelsHeight
;
187 newEntry
->InitialSettings
.dmBitsPerPel
= newEntry
->CurrentSettings
->dmBitsPerPel
;
189 /* Count different resolutions */
190 for (Current
= newEntry
->Settings
; Current
!= NULL
; Current
= Current
->Flink
)
192 if (Current
->Flink
!= NULL
&&
193 ((Current
->dmPelsWidth
!= Current
->Flink
->dmPelsWidth
) ||
194 (Current
->dmPelsHeight
!= Current
->Flink
->dmPelsHeight
)))
200 newEntry
->Resolutions
= HeapAlloc(GetProcessHeap(), 0, ResolutionsCount
* sizeof(RESOLUTION_INFO
));
201 if (!newEntry
->Resolutions
) goto ByeBye
;
203 newEntry
->ResolutionsCount
= ResolutionsCount
;
205 /* Fill resolutions infos */
206 for (Current
= newEntry
->Settings
, i
= 0; Current
!= NULL
; Current
= Current
->Flink
)
208 if (Current
->Flink
== NULL
||
209 (Current
->Flink
!= NULL
&&
210 ((Current
->dmPelsWidth
!= Current
->Flink
->dmPelsWidth
) ||
211 (Current
->dmPelsHeight
!= Current
->Flink
->dmPelsHeight
))))
213 newEntry
->Resolutions
[i
].dmPelsWidth
= Current
->dmPelsWidth
;
214 newEntry
->Resolutions
[i
].dmPelsHeight
= Current
->dmPelsHeight
;
218 descriptionSize
= (_tcslen(DisplayDevice
->DeviceString
) + 1) * sizeof(TCHAR
);
219 description
= HeapAlloc(GetProcessHeap(), 0, descriptionSize
);
220 if (!description
) goto ByeBye
;
222 nameSize
= (_tcslen(DisplayDevice
->DeviceName
) + 1) * sizeof(TCHAR
);
223 name
= HeapAlloc(GetProcessHeap(), 0, nameSize
);
224 if (!name
) goto ByeBye
;
226 keySize
= (_tcslen(DisplayDevice
->DeviceKey
) + 1) * sizeof(TCHAR
);
227 key
= HeapAlloc(GetProcessHeap(), 0, keySize
);
228 if (!key
) goto ByeBye
;
230 devidSize
= (_tcslen(DisplayDevice
->DeviceID
) + 1) * sizeof(TCHAR
);
231 devid
= HeapAlloc(GetProcessHeap(), 0, devidSize
);
232 if (!devid
) goto ByeBye
;
234 memcpy(description
, DisplayDevice
->DeviceString
, descriptionSize
);
235 memcpy(name
, DisplayDevice
->DeviceName
, nameSize
);
236 memcpy(key
, DisplayDevice
->DeviceKey
, keySize
);
237 memcpy(devid
, DisplayDevice
->DeviceID
, devidSize
);
238 newEntry
->DeviceDescription
= description
;
239 newEntry
->DeviceName
= name
;
240 newEntry
->DeviceKey
= key
;
241 newEntry
->DeviceID
= devid
;
242 newEntry
->DeviceStateFlags
= DisplayDevice
->StateFlags
;
243 newEntry
->Flink
= pData
->DisplayDeviceList
;
244 pData
->DisplayDeviceList
= newEntry
;
248 if (newEntry
!= NULL
)
250 if (newEntry
->Settings
!= NULL
)
252 Current
= newEntry
->Settings
;
253 while (Current
!= NULL
)
255 PSETTINGS_ENTRY Next
= Current
->Flink
;
256 HeapFree(GetProcessHeap(), 0, Current
);
260 if (newEntry
->Resolutions
!= NULL
)
261 HeapFree(GetProcessHeap(), 0, newEntry
->Resolutions
);
262 HeapFree(GetProcessHeap(), 0, newEntry
);
264 if (description
!= NULL
)
265 HeapFree(GetProcessHeap(), 0, description
);
267 HeapFree(GetProcessHeap(), 0, name
);
269 HeapFree(GetProcessHeap(), 0, key
);
274 OnDisplayDeviceChanged(IN HWND hwndDlg
, IN PDATA pData
, IN PDISPLAY_DEVICE_ENTRY pDeviceEntry
)
276 PSETTINGS_ENTRY Current
;
279 pData
->CurrentDisplayDevice
= pDeviceEntry
; /* Update variable */
281 /* Fill color depths combo box */
282 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_RESETCONTENT
, 0, 0);
283 for (Current
= pDeviceEntry
->Settings
; Current
!= NULL
; Current
= Current
->Flink
)
286 if (LoadString(hApplet
, (2900 + Current
->dmBitsPerPel
), Buffer
, sizeof(Buffer
) / sizeof(TCHAR
)))
288 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)Buffer
);
289 if (index
== (DWORD
)CB_ERR
)
291 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_ADDSTRING
, 0, (LPARAM
)Buffer
);
292 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_SETITEMDATA
, index
, Current
->dmBitsPerPel
);
297 /* Fill resolutions slider */
298 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_CLEARTICS
, TRUE
, 0);
299 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_SETRANGE
, TRUE
, MAKELONG(0, pDeviceEntry
->ResolutionsCount
- 1));
301 UpdateDisplay(hwndDlg
, pData
, TRUE
);
305 OnInitDialog(IN HWND hwndDlg
)
311 DISPLAY_DEVICE displayDevice
;
314 pData
= HeapAlloc(GetProcessHeap(), 0, sizeof(DATA
));
318 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pData
);
320 /* Get video cards list */
321 pData
->DisplayDeviceList
= NULL
;
322 displayDevice
.cb
= (DWORD
)sizeof(DISPLAY_DEVICE
);
323 while (EnumDisplayDevices(NULL
, iDevNum
, &displayDevice
, 0x1))
325 if ((displayDevice
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
) != 0)
327 if (AddDisplayDevice(pData
, &displayDevice
))
335 /* No adapter found */
336 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_BPP
), FALSE
);
337 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_RESOLUTION
), FALSE
);
338 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_RESOLUTION_TEXT
), FALSE
);
339 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_ADVANCED
), FALSE
);
340 ShowWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_SPECTRUM
), SW_HIDE
);
342 /* Do not initialize the color spectrum bitmaps */
343 memset(pData
->hSpectrumBitmaps
, 0, sizeof(pData
->hSpectrumBitmaps
));
346 else if (Result
== 1)
348 MONSL_MONINFO monitors
;
350 /* Single video adapter */
351 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_DEVICE
, WM_SETTEXT
, 0, (LPARAM
)pData
->DisplayDeviceList
->DeviceDescription
);
352 OnDisplayDeviceChanged(hwndDlg
, pData
, pData
->DisplayDeviceList
);
354 monitors
.Position
.x
= monitors
.Position
.y
= 0;
355 monitors
.Size
.cx
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
356 monitors
.Size
.cy
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
358 SendDlgItemMessage(hwndDlg
,
360 MSLM_SETMONITORSINFO
,
364 else /* FIXME: Incomplete! */
366 PMONSL_MONINFO pMonitors
;
369 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_DEVICE
, WM_SETTEXT
, 0, (LPARAM
)pData
->DisplayDeviceList
->DeviceDescription
);
370 OnDisplayDeviceChanged(hwndDlg
, pData
, pData
->DisplayDeviceList
);
372 pMonitors
= (PMONSL_MONINFO
)HeapAlloc(GetProcessHeap(), 0, sizeof(MONSL_MONINFO
) * Result
);
376 for (i
= 0; i
< Result
; i
++)
378 pMonitors
[i
].Position
.x
= hack
* i
;
379 pMonitors
[i
].Position
.y
= 0;
380 pMonitors
[i
].Size
.cx
= pData
->DisplayDeviceList
->CurrentSettings
->dmPelsWidth
;
381 pMonitors
[i
].Size
.cy
= pData
->DisplayDeviceList
->CurrentSettings
->dmPelsHeight
;
382 pMonitors
[i
].Flags
= 0;
385 SendDlgItemMessage(hwndDlg
,
387 MSLM_SETMONITORSINFO
,
391 HeapFree(GetProcessHeap(), 0, pMonitors
);
395 /* Initialize the color spectrum bitmaps */
396 for(i
= 0; i
< NUM_SPECTRUM_BITMAPS
; i
++)
398 pData
->hSpectrumBitmaps
[i
] = LoadImageW(hApplet
, MAKEINTRESOURCEW(IDB_SPECTRUM_4
+ i
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
400 if (pData
->hSpectrumBitmaps
[i
] != NULL
)
402 if (GetObjectW(pData
->hSpectrumBitmaps
[i
], sizeof(BITMAP
), &bitmap
) != 0)
404 pData
->cxSource
[i
] = bitmap
.bmWidth
;
405 pData
->cySource
[i
] = bitmap
.bmHeight
;
409 pData
->cxSource
[i
] = 0;
410 pData
->cySource
[i
] = 0;
416 /* Get the ID for DATA::hSpectrumBitmaps */
418 ShowColorSpectrum(IN HDC hDC
, IN LPRECT client
, IN DWORD BitsPerPel
, IN PDATA pData
)
423 hdcMem
= CreateCompatibleDC(hDC
);
430 case 4: iBitmap
= 0; break;
431 case 8: iBitmap
= 1; break;
432 default: iBitmap
= 2;
435 if (SelectObject(hdcMem
, pData
->hSpectrumBitmaps
[iBitmap
]))
438 client
->left
, client
->top
,
439 client
->right
- client
->left
,
440 client
->bottom
- client
->top
,
442 pData
->cxSource
[iBitmap
],
443 pData
->cySource
[iBitmap
], SRCCOPY
);
450 OnBPPChanged(IN HWND hwndDlg
, IN PDATA pData
)
452 /* If new BPP is not compatible with resolution:
453 * 1) try to find the nearest smaller matching resolution
454 * 2) otherwise, get the nearest bigger resolution
456 PSETTINGS_ENTRY Current
;
457 DWORD dmNewBitsPerPel
;
460 HWND hSpectrumControl
;
463 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_GETCURSEL
, 0, 0);
464 dmNewBitsPerPel
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_GETITEMDATA
, index
, 0);
466 /* Show a new spectrum bitmap */
467 hSpectrumControl
= GetDlgItem(hwndDlg
, IDC_SETTINGS_SPECTRUM
);
468 hSpectrumDC
= GetDC(hSpectrumControl
);
469 GetClientRect(hSpectrumControl
, &client
);
470 ShowColorSpectrum(hSpectrumDC
, &client
, dmNewBitsPerPel
, pData
);
472 /* Find if new parameters are valid */
473 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
;
474 if (dmNewBitsPerPel
== Current
->dmBitsPerPel
)
480 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
482 if (dmNewBitsPerPel
< Current
->dmBitsPerPel
)
484 Current
= Current
->Blink
;
485 while (Current
!= NULL
)
487 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
488 && Current
->dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
489 && Current
->dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
)
491 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
492 UpdateDisplay(hwndDlg
, pData
, TRUE
);
495 Current
= Current
->Blink
;
500 Current
= Current
->Flink
;
501 while (Current
!= NULL
)
503 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
504 && Current
->dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
505 && Current
->dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
)
507 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
508 UpdateDisplay(hwndDlg
, pData
, TRUE
);
511 Current
= Current
->Flink
;
515 /* Search smaller resolution compatible with current color depth */
516 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Blink
;
517 while (Current
!= NULL
)
519 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
)
521 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
522 UpdateDisplay(hwndDlg
, pData
, TRUE
);
525 Current
= Current
->Blink
;
528 /* Search bigger resolution compatible with current color depth */
529 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Flink
;
530 while (Current
!= NULL
)
532 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
)
534 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
535 UpdateDisplay(hwndDlg
, pData
, TRUE
);
538 Current
= Current
->Flink
;
541 /* We shouldn't go there */
545 OnResolutionChanged(IN HWND hwndDlg
, IN PDATA pData
, IN DWORD NewPosition
,
546 IN BOOL bUpdateThumb
)
548 /* If new resolution is not compatible with color depth:
549 * 1) try to find the nearest bigger matching color depth
550 * 2) otherwise, get the nearest smaller color depth
552 PSETTINGS_ENTRY Current
;
553 DWORD dmNewPelsHeight
= pData
->CurrentDisplayDevice
->Resolutions
[NewPosition
].dmPelsHeight
;
554 DWORD dmNewPelsWidth
= pData
->CurrentDisplayDevice
->Resolutions
[NewPosition
].dmPelsWidth
;
556 DWORD dmDisplayFrequency
;
558 /* Find if new parameters are valid */
559 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
;
560 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
566 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
568 dmBitsPerPel
= Current
->dmBitsPerPel
;
569 dmDisplayFrequency
= Current
->dmDisplayFrequency
;
571 if (CompareSettings(Current
, dmNewPelsWidth
,
572 dmNewPelsHeight
, dmBitsPerPel
,
573 dmDisplayFrequency
) < 0)
575 Current
= Current
->Blink
;
576 while (Current
!= NULL
)
578 if (Current
->dmPelsHeight
== dmNewPelsHeight
579 && Current
->dmPelsWidth
== dmNewPelsWidth
580 && Current
->dmBitsPerPel
== dmBitsPerPel
)
582 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
583 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
586 Current
= Current
->Blink
;
591 Current
= Current
->Flink
;
592 while (Current
!= NULL
)
594 if (Current
->dmPelsHeight
== dmNewPelsHeight
595 && Current
->dmPelsWidth
== dmNewPelsWidth
596 && Current
->dmBitsPerPel
== dmBitsPerPel
)
598 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
599 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
602 Current
= Current
->Flink
;
606 /* Search bigger color depth compatible with current resolution */
607 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Flink
;
608 while (Current
!= NULL
)
610 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
612 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
613 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
616 Current
= Current
->Flink
;
619 /* Search smaller color depth compatible with current resolution */
620 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Blink
;
621 while (Current
!= NULL
)
623 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
625 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
626 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
629 Current
= Current
->Blink
;
632 /* We shouldn't go there */
635 /* Property sheet page callback */
637 SettingsPageCallbackProc(HWND hwnd
, UINT uMsg
, LPPROPSHEETPAGE ppsp
)
644 Ret
= RegisterMonitorSelectionControl(hApplet
);
648 UnregisterMonitorSelectionControl(hApplet
);
655 /* Property page dialog callback */
657 SettingsPageProc(IN HWND hwndDlg
, IN UINT uMsg
, IN WPARAM wParam
, IN LPARAM lParam
)
660 TCHAR Message
[1024], Title
[256];
662 pData
= (PDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
668 OnInitDialog(hwndDlg
);
673 LPDRAWITEMSTRUCT lpDrawItem
;
674 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
676 if (lpDrawItem
->CtlID
== IDC_SETTINGS_SPECTRUM
)
677 ShowColorSpectrum(lpDrawItem
->hDC
, &lpDrawItem
->rcItem
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
, pData
);
682 DWORD controlId
= LOWORD(wParam
);
683 DWORD command
= HIWORD(wParam
);
685 if (controlId
== IDC_SETTINGS_ADVANCED
&& command
== BN_CLICKED
)
686 DisplayAdvancedSettings(hwndDlg
, pData
->CurrentDisplayDevice
);
687 else if (controlId
== IDC_SETTINGS_BPP
&& command
== CBN_SELCHANGE
)
688 OnBPPChanged(hwndDlg
, pData
);
693 switch (LOWORD(wParam
))
703 DWORD newPosition
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_GETPOS
, 0, 0);
704 OnResolutionChanged(hwndDlg
, pData
, newPosition
, TRUE
);
709 OnResolutionChanged(hwndDlg
, pData
, HIWORD(wParam
), FALSE
);
716 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
717 if (lpnm
->code
== (UINT
)PSN_APPLY
)
719 if (pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
720 || pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
721 || pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
)
723 /* FIXME: Need to test changes */
724 /* Apply new settings */
727 RtlZeroMemory(&devmode
, sizeof(DEVMODE
));
728 devmode
.dmSize
= (WORD
)sizeof(DEVMODE
);
729 devmode
.dmPelsWidth
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
730 devmode
.dmPelsHeight
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
731 devmode
.dmBitsPerPel
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
;
732 devmode
.dmDisplayFrequency
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmDisplayFrequency
;
733 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
| DM_BITSPERPEL
| DM_DISPLAYFREQUENCY
;
734 rc
= ChangeDisplaySettingsEx(
735 pData
->CurrentDisplayDevice
->DeviceName
,
742 case DISP_CHANGE_SUCCESSFUL
:
743 pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
744 pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
745 pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
;
747 case DISP_CHANGE_RESTART
:
748 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
749 LoadString(hApplet
, IDS_APPLY_NEEDS_RESTART
, Message
, sizeof(Message
) / sizeof (TCHAR
));
750 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONINFORMATION
);
752 case DISP_CHANGE_FAILED
:
754 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
755 LoadString(hApplet
, IDS_APPLY_FAILED
, Message
, sizeof(Message
) / sizeof (TCHAR
));
756 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONSTOP
);
772 pt
.x
= (SHORT
)LOWORD(lParam
);
773 pt
.y
= (SHORT
)HIWORD(lParam
);
775 hwndMonSel
= GetDlgItem(hwndDlg
,
776 IDC_SETTINGS_MONSEL
);
777 if ((HWND
)wParam
== hwndMonSel
)
779 if (pt
.x
== -1 && pt
.y
== -1)
783 Index
= (INT
)SendMessage(hwndMonSel
,
789 (INT
)SendMessage(hwndMonSel
,
794 pt
.x
= rcMon
.left
+ ((rcMon
.right
- rcMon
.left
) / 2);
795 pt
.y
= rcMon
.top
+ ((rcMon
.bottom
- rcMon
.top
) / 2);
800 MapWindowPoints(hwndMonSel
,
808 MapWindowPoints(NULL
,
813 Index
= (INT
)SendMessage(hwndMonSel
,
821 hPopup
= LoadPopupMenu(hApplet
,
822 MAKEINTRESOURCE(IDM_MONITOR_MENU
));
825 /* FIXME: Enable/Disable menu items */
826 EnableMenuItem(hPopup
,
828 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
829 EnableMenuItem(hPopup
,
831 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
832 EnableMenuItem(hPopup
,
834 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
835 EnableMenuItem(hPopup
,
837 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
839 uiCmd
= (UINT
)TrackPopupMenu(hPopup
,
840 TPM_RETURNCMD
| TPM_RIGHTBUTTON
,
849 case ID_MENU_ATTACHED
:
850 case ID_MENU_PRIMARY
:
851 case ID_MENU_IDENTIFY
:
852 case ID_MENU_PROPERTIES
:
853 /* FIXME: Implement */
867 PDISPLAY_DEVICE_ENTRY Current
= pData
->DisplayDeviceList
;
869 while (Current
!= NULL
)
871 PDISPLAY_DEVICE_ENTRY Next
= Current
->Flink
;
872 PSETTINGS_ENTRY CurrentSettings
= Current
->Settings
;
873 while (CurrentSettings
!= NULL
)
875 PSETTINGS_ENTRY NextSettings
= CurrentSettings
->Flink
;
876 HeapFree(GetProcessHeap(), 0, CurrentSettings
);
877 CurrentSettings
= NextSettings
;
879 HeapFree(GetProcessHeap(), 0, Current
);
883 for (i
= 0; i
< NUM_SPECTRUM_BITMAPS
; i
++)
885 if (pData
->hSpectrumBitmaps
[i
])
886 DeleteObject(pData
->hSpectrumBitmaps
[i
]);
889 HeapFree(GetProcessHeap(), 0, pData
);