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)
13 typedef struct _SETTINGS_DATA
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
];
20 } SETTINGS_DATA
, *PSETTINGS_DATA
;
22 typedef struct _TIMEOUTDATA
24 TCHAR szRawBuffer
[256];
25 TCHAR szCookedBuffer
[256];
27 } TIMEOUTDATA
, *PTIMEOUTDATA
;
30 UpdateDisplay(IN HWND hwndDlg
, PSETTINGS_DATA pData
, IN BOOL bUpdateThumb
)
38 LoadString(hApplet
, IDS_PIXEL
, Pixel
, sizeof(Pixel
) / sizeof(TCHAR
));
39 _stprintf(Buffer
, Pixel
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
, Pixel
);
40 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION_TEXT
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
42 for (index
= 0; index
< pData
->CurrentDisplayDevice
->ResolutionsCount
; index
++)
44 if (pData
->CurrentDisplayDevice
->Resolutions
[index
].dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
&&
45 pData
->CurrentDisplayDevice
->Resolutions
[index
].dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
)
48 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_SETPOS
, TRUE
, index
);
52 if (LoadString(hApplet
, (2900 + pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
), Buffer
, sizeof(Buffer
) / sizeof(TCHAR
)))
53 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_SELECTSTRING
, (WPARAM
)-1, (LPARAM
)Buffer
);
55 hwndMonSel
= GetDlgItem(hwndDlg
, IDC_SETTINGS_MONSEL
);
56 index
= (INT
)SendMessage(hwndMonSel
, MSLM_GETCURSEL
, 0, 0);
57 if (index
!= (DWORD
)-1 && SendMessage(hwndMonSel
, MSLM_GETMONITORINFO
, index
, (LPARAM
)&info
))
59 info
.Size
.cx
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
60 info
.Size
.cy
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
61 SendMessage(hwndMonSel
, MSLM_SETMONITORINFO
, index
, (LPARAM
)&info
);
66 CompareSettings(PSETTINGS_ENTRY Entry
, DWORD dmPelsWidth
, DWORD dmPelsHeight
,
67 DWORD dmBitsPerPel
, DWORD dmDisplayFrequency
)
69 if (Entry
->dmPelsWidth
== dmPelsWidth
&&
70 Entry
->dmPelsHeight
== dmPelsHeight
&&
71 Entry
->dmBitsPerPel
== dmBitsPerPel
&&
72 Entry
->dmDisplayFrequency
== dmDisplayFrequency
)
77 if ((Entry
->dmPelsWidth
< dmPelsWidth
) ||
78 (Entry
->dmPelsWidth
== dmPelsWidth
&& Entry
->dmPelsHeight
< dmPelsHeight
) ||
79 (Entry
->dmPelsWidth
== dmPelsWidth
&& Entry
->dmPelsHeight
== dmPelsHeight
&&
80 Entry
->dmBitsPerPel
< dmBitsPerPel
))
87 static PSETTINGS_ENTRY
88 GetPossibleSettings(IN LPCTSTR DeviceName
, OUT DWORD
* pSettingsCount
, OUT PSETTINGS_ENTRY
* CurrentSettings
)
94 PSETTINGS_ENTRY Settings
= NULL
;
96 PSETTINGS_ENTRY Current
;
97 DWORD bpp
, xres
, yres
;
100 /* Get current settings */
101 *CurrentSettings
= NULL
;
102 hDC
= CreateIC(NULL
, DeviceName
, NULL
, NULL
);
103 bpp
= GetDeviceCaps(hDC
, PLANES
);
104 bpp
*= GetDeviceCaps(hDC
, BITSPIXEL
);
105 xres
= GetDeviceCaps(hDC
, HORZRES
);
106 yres
= GetDeviceCaps(hDC
, VERTRES
);
109 /* List all settings */
110 devmode
.dmSize
= (WORD
)sizeof(devmode
);
111 devmode
.dmDriverExtra
= 0;
113 if (!EnumDisplaySettingsEx(DeviceName
, ENUM_CURRENT_SETTINGS
, &devmode
, dwFlags
))
116 curDispFreq
= devmode
.dmDisplayFrequency
;
118 while (EnumDisplaySettingsEx(DeviceName
, iMode
, &devmode
, dwFlags
))
122 if (devmode
.dmPelsWidth
< 640 ||
123 devmode
.dmPelsHeight
< 480 ||
124 devmode
.dmDisplayFrequency
!= curDispFreq
||
125 (devmode
.dmBitsPerPel
!= 4 &&
126 devmode
.dmBitsPerPel
!= 8 &&
127 devmode
.dmBitsPerPel
!= 16 &&
128 devmode
.dmBitsPerPel
!= 24 &&
129 devmode
.dmBitsPerPel
!= 32))
134 Current
= HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY
));
137 /* Sort resolutions by increasing height, and BPP */
138 PSETTINGS_ENTRY Previous
= NULL
;
139 PSETTINGS_ENTRY Next
= Settings
;
140 Current
->dmPelsWidth
= devmode
.dmPelsWidth
;
141 Current
->dmPelsHeight
= devmode
.dmPelsHeight
;
142 Current
->dmBitsPerPel
= devmode
.dmBitsPerPel
;
143 Current
->dmDisplayFrequency
= devmode
.dmDisplayFrequency
;
144 while (Next
!= NULL
&&
145 CompareSettings(Next
, devmode
.dmPelsWidth
,
146 devmode
.dmPelsHeight
, devmode
.dmBitsPerPel
,
147 devmode
.dmDisplayFrequency
) > 0)
152 Current
->Blink
= Previous
;
153 Current
->Flink
= Next
;
154 if (Previous
== NULL
)
157 Previous
->Flink
= Current
;
159 Next
->Blink
= Current
;
160 if (devmode
.dmPelsWidth
== xres
&& devmode
.dmPelsHeight
== yres
&& devmode
.dmBitsPerPel
== bpp
)
162 *CurrentSettings
= Current
;
168 *pSettingsCount
= NbSettings
;
173 AddDisplayDevice(IN PSETTINGS_DATA pData
, IN
const DISPLAY_DEVICE
*DisplayDevice
)
175 PDISPLAY_DEVICE_ENTRY newEntry
= NULL
;
176 LPTSTR description
= NULL
;
180 SIZE_T descriptionSize
, nameSize
, keySize
, devidSize
;
181 PSETTINGS_ENTRY Current
;
182 DWORD ResolutionsCount
= 1;
185 newEntry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DISPLAY_DEVICE_ENTRY
));
186 if (!newEntry
) goto ByeBye
;
188 newEntry
->Settings
= GetPossibleSettings(DisplayDevice
->DeviceName
, &newEntry
->SettingsCount
, &newEntry
->CurrentSettings
);
189 if (!newEntry
->Settings
) goto ByeBye
;
191 newEntry
->InitialSettings
.dmPelsWidth
= newEntry
->CurrentSettings
->dmPelsWidth
;
192 newEntry
->InitialSettings
.dmPelsHeight
= newEntry
->CurrentSettings
->dmPelsHeight
;
193 newEntry
->InitialSettings
.dmBitsPerPel
= newEntry
->CurrentSettings
->dmBitsPerPel
;
195 /* Count different resolutions */
196 for (Current
= newEntry
->Settings
; Current
!= NULL
; Current
= Current
->Flink
)
198 if (Current
->Flink
!= NULL
&&
199 ((Current
->dmPelsWidth
!= Current
->Flink
->dmPelsWidth
) ||
200 (Current
->dmPelsHeight
!= Current
->Flink
->dmPelsHeight
)))
206 newEntry
->Resolutions
= HeapAlloc(GetProcessHeap(), 0, ResolutionsCount
* sizeof(RESOLUTION_INFO
));
207 if (!newEntry
->Resolutions
) goto ByeBye
;
209 newEntry
->ResolutionsCount
= ResolutionsCount
;
211 /* Fill resolutions infos */
212 for (Current
= newEntry
->Settings
, i
= 0; Current
!= NULL
; Current
= Current
->Flink
)
214 if (Current
->Flink
== NULL
||
215 (Current
->Flink
!= NULL
&&
216 ((Current
->dmPelsWidth
!= Current
->Flink
->dmPelsWidth
) ||
217 (Current
->dmPelsHeight
!= Current
->Flink
->dmPelsHeight
))))
219 newEntry
->Resolutions
[i
].dmPelsWidth
= Current
->dmPelsWidth
;
220 newEntry
->Resolutions
[i
].dmPelsHeight
= Current
->dmPelsHeight
;
224 descriptionSize
= (_tcslen(DisplayDevice
->DeviceString
) + 1) * sizeof(TCHAR
);
225 description
= HeapAlloc(GetProcessHeap(), 0, descriptionSize
);
226 if (!description
) goto ByeBye
;
228 nameSize
= (_tcslen(DisplayDevice
->DeviceName
) + 1) * sizeof(TCHAR
);
229 name
= HeapAlloc(GetProcessHeap(), 0, nameSize
);
230 if (!name
) goto ByeBye
;
232 keySize
= (_tcslen(DisplayDevice
->DeviceKey
) + 1) * sizeof(TCHAR
);
233 key
= HeapAlloc(GetProcessHeap(), 0, keySize
);
234 if (!key
) goto ByeBye
;
236 devidSize
= (_tcslen(DisplayDevice
->DeviceID
) + 1) * sizeof(TCHAR
);
237 devid
= HeapAlloc(GetProcessHeap(), 0, devidSize
);
238 if (!devid
) goto ByeBye
;
240 memcpy(description
, DisplayDevice
->DeviceString
, descriptionSize
);
241 memcpy(name
, DisplayDevice
->DeviceName
, nameSize
);
242 memcpy(key
, DisplayDevice
->DeviceKey
, keySize
);
243 memcpy(devid
, DisplayDevice
->DeviceID
, devidSize
);
244 newEntry
->DeviceDescription
= description
;
245 newEntry
->DeviceName
= name
;
246 newEntry
->DeviceKey
= key
;
247 newEntry
->DeviceID
= devid
;
248 newEntry
->DeviceStateFlags
= DisplayDevice
->StateFlags
;
249 newEntry
->Flink
= pData
->DisplayDeviceList
;
250 pData
->DisplayDeviceList
= newEntry
;
254 if (newEntry
!= NULL
)
256 if (newEntry
->Settings
!= NULL
)
258 Current
= newEntry
->Settings
;
259 while (Current
!= NULL
)
261 PSETTINGS_ENTRY Next
= Current
->Flink
;
262 HeapFree(GetProcessHeap(), 0, Current
);
266 if (newEntry
->Resolutions
!= NULL
)
267 HeapFree(GetProcessHeap(), 0, newEntry
->Resolutions
);
268 HeapFree(GetProcessHeap(), 0, newEntry
);
270 if (description
!= NULL
)
271 HeapFree(GetProcessHeap(), 0, description
);
273 HeapFree(GetProcessHeap(), 0, name
);
275 HeapFree(GetProcessHeap(), 0, key
);
280 OnDisplayDeviceChanged(IN HWND hwndDlg
, IN PSETTINGS_DATA pData
, IN PDISPLAY_DEVICE_ENTRY pDeviceEntry
)
282 PSETTINGS_ENTRY Current
;
285 pData
->CurrentDisplayDevice
= pDeviceEntry
; /* Update variable */
287 /* Fill color depths combo box */
288 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_RESETCONTENT
, 0, 0);
289 for (Current
= pDeviceEntry
->Settings
; Current
!= NULL
; Current
= Current
->Flink
)
292 if (LoadString(hApplet
, (2900 + Current
->dmBitsPerPel
), Buffer
, sizeof(Buffer
) / sizeof(TCHAR
)))
294 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)Buffer
);
295 if (index
== (DWORD
)CB_ERR
)
297 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_ADDSTRING
, 0, (LPARAM
)Buffer
);
298 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_SETITEMDATA
, index
, Current
->dmBitsPerPel
);
303 /* Fill resolutions slider */
304 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_CLEARTICS
, TRUE
, 0);
305 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_SETRANGE
, TRUE
, MAKELONG(0, pDeviceEntry
->ResolutionsCount
- 1));
307 UpdateDisplay(hwndDlg
, pData
, TRUE
);
311 SettingsOnInitDialog(IN HWND hwndDlg
)
317 DISPLAY_DEVICE displayDevice
;
318 PSETTINGS_DATA pData
;
320 pData
= HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_DATA
));
324 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pData
);
326 /* Get video cards list */
327 pData
->DisplayDeviceList
= NULL
;
328 displayDevice
.cb
= sizeof(displayDevice
);
329 while (EnumDisplayDevices(NULL
, iDevNum
, &displayDevice
, 0x1))
331 if ((displayDevice
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
) != 0)
333 if (AddDisplayDevice(pData
, &displayDevice
))
341 /* No adapter found */
342 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_BPP
), FALSE
);
343 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_RESOLUTION
), FALSE
);
344 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_RESOLUTION_TEXT
), FALSE
);
345 EnableWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_ADVANCED
), FALSE
);
346 ShowWindow(GetDlgItem(hwndDlg
, IDC_SETTINGS_SPECTRUM
), SW_HIDE
);
348 /* Do not initialize the color spectrum bitmaps */
349 memset(pData
->hSpectrumBitmaps
, 0, sizeof(pData
->hSpectrumBitmaps
));
352 else if (Result
== 1)
354 MONSL_MONINFO monitors
;
356 /* Single video adapter */
357 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_DEVICE
, WM_SETTEXT
, 0, (LPARAM
)pData
->DisplayDeviceList
->DeviceDescription
);
358 OnDisplayDeviceChanged(hwndDlg
, pData
, pData
->DisplayDeviceList
);
360 monitors
.Position
.x
= monitors
.Position
.y
= 0;
361 monitors
.Size
.cx
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
362 monitors
.Size
.cy
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
364 SendDlgItemMessage(hwndDlg
,
366 MSLM_SETMONITORSINFO
,
370 else /* FIXME: Incomplete! */
372 PMONSL_MONINFO pMonitors
;
375 SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_DEVICE
, WM_SETTEXT
, 0, (LPARAM
)pData
->DisplayDeviceList
->DeviceDescription
);
376 OnDisplayDeviceChanged(hwndDlg
, pData
, pData
->DisplayDeviceList
);
378 pMonitors
= (PMONSL_MONINFO
)HeapAlloc(GetProcessHeap(), 0, sizeof(MONSL_MONINFO
) * Result
);
382 for (i
= 0; i
< Result
; i
++)
384 pMonitors
[i
].Position
.x
= hack
* i
;
385 pMonitors
[i
].Position
.y
= 0;
386 pMonitors
[i
].Size
.cx
= pData
->DisplayDeviceList
->CurrentSettings
->dmPelsWidth
;
387 pMonitors
[i
].Size
.cy
= pData
->DisplayDeviceList
->CurrentSettings
->dmPelsHeight
;
388 pMonitors
[i
].Flags
= 0;
391 SendDlgItemMessage(hwndDlg
,
393 MSLM_SETMONITORSINFO
,
397 HeapFree(GetProcessHeap(), 0, pMonitors
);
401 /* Initialize the color spectrum bitmaps */
402 for (i
= 0; i
< NUM_SPECTRUM_BITMAPS
; i
++)
404 pData
->hSpectrumBitmaps
[i
] = LoadImageW(hApplet
, MAKEINTRESOURCEW(IDB_SPECTRUM_4
+ i
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
406 if (pData
->hSpectrumBitmaps
[i
] != NULL
)
408 if (GetObjectW(pData
->hSpectrumBitmaps
[i
], sizeof(BITMAP
), &bitmap
) != 0)
410 pData
->cxSource
[i
] = bitmap
.bmWidth
;
411 pData
->cySource
[i
] = bitmap
.bmHeight
;
415 pData
->cxSource
[i
] = 0;
416 pData
->cySource
[i
] = 0;
422 /* Get the ID for SETTINGS_DATA::hSpectrumBitmaps */
424 ShowColorSpectrum(IN HDC hDC
, IN LPRECT client
, IN DWORD BitsPerPel
, IN PSETTINGS_DATA pData
)
429 hdcMem
= CreateCompatibleDC(hDC
);
436 case 4: iBitmap
= 0; break;
437 case 8: iBitmap
= 1; break;
438 default: iBitmap
= 2;
441 if (SelectObject(hdcMem
, pData
->hSpectrumBitmaps
[iBitmap
]))
444 client
->left
, client
->top
,
445 client
->right
- client
->left
,
446 client
->bottom
- client
->top
,
448 pData
->cxSource
[iBitmap
],
449 pData
->cySource
[iBitmap
], SRCCOPY
);
456 OnBPPChanged(IN HWND hwndDlg
, IN PSETTINGS_DATA pData
)
458 /* If new BPP is not compatible with resolution:
459 * 1) try to find the nearest smaller matching resolution
460 * 2) otherwise, get the nearest bigger resolution
462 PSETTINGS_ENTRY Current
;
463 DWORD dmNewBitsPerPel
;
466 HWND hSpectrumControl
;
469 index
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_GETCURSEL
, 0, 0);
470 dmNewBitsPerPel
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_BPP
, CB_GETITEMDATA
, index
, 0);
472 /* Show a new spectrum bitmap */
473 hSpectrumControl
= GetDlgItem(hwndDlg
, IDC_SETTINGS_SPECTRUM
);
474 hSpectrumDC
= GetDC(hSpectrumControl
);
475 GetClientRect(hSpectrumControl
, &client
);
476 ShowColorSpectrum(hSpectrumDC
, &client
, dmNewBitsPerPel
, pData
);
478 /* Find if new parameters are valid */
479 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
;
480 if (dmNewBitsPerPel
== Current
->dmBitsPerPel
)
486 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
488 if (dmNewBitsPerPel
< Current
->dmBitsPerPel
)
490 Current
= Current
->Blink
;
491 while (Current
!= NULL
)
493 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
494 && Current
->dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
495 && Current
->dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
)
497 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
498 UpdateDisplay(hwndDlg
, pData
, TRUE
);
501 Current
= Current
->Blink
;
506 Current
= Current
->Flink
;
507 while (Current
!= NULL
)
509 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
510 && Current
->dmPelsHeight
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
511 && Current
->dmPelsWidth
== pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
)
513 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
514 UpdateDisplay(hwndDlg
, pData
, TRUE
);
517 Current
= Current
->Flink
;
521 /* Search smaller resolution compatible with current color depth */
522 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Blink
;
523 while (Current
!= NULL
)
525 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
)
527 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
528 UpdateDisplay(hwndDlg
, pData
, TRUE
);
531 Current
= Current
->Blink
;
534 /* Search bigger resolution compatible with current color depth */
535 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Flink
;
536 while (Current
!= NULL
)
538 if (Current
->dmBitsPerPel
== dmNewBitsPerPel
)
540 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
541 UpdateDisplay(hwndDlg
, pData
, TRUE
);
544 Current
= Current
->Flink
;
547 /* We shouldn't go there */
551 OnResolutionChanged(IN HWND hwndDlg
, IN PSETTINGS_DATA pData
, IN DWORD NewPosition
,
552 IN BOOL bUpdateThumb
)
554 /* If new resolution is not compatible with color depth:
555 * 1) try to find the nearest bigger matching color depth
556 * 2) otherwise, get the nearest smaller color depth
558 PSETTINGS_ENTRY Current
;
559 DWORD dmNewPelsHeight
= pData
->CurrentDisplayDevice
->Resolutions
[NewPosition
].dmPelsHeight
;
560 DWORD dmNewPelsWidth
= pData
->CurrentDisplayDevice
->Resolutions
[NewPosition
].dmPelsWidth
;
562 DWORD dmDisplayFrequency
;
564 /* Find if new parameters are valid */
565 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
;
566 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
572 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
574 dmBitsPerPel
= Current
->dmBitsPerPel
;
575 dmDisplayFrequency
= Current
->dmDisplayFrequency
;
577 if (CompareSettings(Current
, dmNewPelsWidth
,
578 dmNewPelsHeight
, dmBitsPerPel
,
579 dmDisplayFrequency
) < 0)
581 Current
= Current
->Blink
;
582 while (Current
!= NULL
)
584 if (Current
->dmPelsHeight
== dmNewPelsHeight
585 && Current
->dmPelsWidth
== dmNewPelsWidth
586 && Current
->dmBitsPerPel
== dmBitsPerPel
)
588 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
589 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
592 Current
= Current
->Blink
;
597 Current
= Current
->Flink
;
598 while (Current
!= NULL
)
600 if (Current
->dmPelsHeight
== dmNewPelsHeight
601 && Current
->dmPelsWidth
== dmNewPelsWidth
602 && Current
->dmBitsPerPel
== dmBitsPerPel
)
604 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
605 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
608 Current
= Current
->Flink
;
612 /* Search bigger color depth compatible with current resolution */
613 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Flink
;
614 while (Current
!= NULL
)
616 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
618 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
619 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
622 Current
= Current
->Flink
;
625 /* Search smaller color depth compatible with current resolution */
626 Current
= pData
->CurrentDisplayDevice
->CurrentSettings
->Blink
;
627 while (Current
!= NULL
)
629 if (dmNewPelsHeight
== Current
->dmPelsHeight
&& dmNewPelsWidth
== Current
->dmPelsWidth
)
631 pData
->CurrentDisplayDevice
->CurrentSettings
= Current
;
632 UpdateDisplay(hwndDlg
, pData
, bUpdateThumb
);
635 Current
= Current
->Blink
;
638 /* We shouldn't go there */
641 /* Property sheet page callback */
643 SettingsPageCallbackProc(HWND hwnd
, UINT uMsg
, LPPROPSHEETPAGE ppsp
)
650 Ret
= RegisterMonitorSelectionControl(hApplet
);
654 UnregisterMonitorSelectionControl(hApplet
);
661 static INT_PTR CALLBACK
662 ConfirmDlgProc(IN HWND hwndDlg
, IN UINT uMsg
, IN WPARAM wParam
, IN LPARAM lParam
)
666 pData
= (PTIMEOUTDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
671 /* Allocate the local dialog data */
672 pData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEOUTDATA
));
676 /* Link the dialog data to the dialog */
677 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pData
);
679 /* Timeout in seconds */
680 pData
->nTimeout
= 15;
682 /* Load the raw timeout string */
683 LoadString(hApplet
, IDS_TIMEOUTTEXT
, pData
->szRawBuffer
, ARRAYSIZE(pData
->szRawBuffer
));
685 /* Cook the timeout string and show it */
686 _stprintf(pData
->szCookedBuffer
, pData
->szRawBuffer
, pData
->nTimeout
);
687 SetDlgItemText(hwndDlg
, IDC_TIMEOUTTEXT
, pData
->szCookedBuffer
);
689 /* Start the timer (ticks every second)*/
690 SetTimer(hwndDlg
, 1, 1000, NULL
);
694 /* Update the timepout value */
697 /* Update the timeout text */
698 _stprintf(pData
->szCookedBuffer
, pData
->szRawBuffer
, pData
->nTimeout
);
699 SetDlgItemText(hwndDlg
, IDC_TIMEOUTTEXT
, pData
->szCookedBuffer
);
701 /* Kill the timer and return a 'No', if we ran out of time */
702 if (pData
->nTimeout
== 0)
704 KillTimer(hwndDlg
, 1);
705 EndDialog(hwndDlg
, IDNO
);
710 /* Kill the timer and return the clicked button id */
711 KillTimer(hwndDlg
, 1);
712 EndDialog(hwndDlg
, LOWORD(wParam
));
716 /* Free the local dialog data */
717 HeapFree(GetProcessHeap(), 0, pData
);
725 ApplyDisplaySettings(HWND hwndDlg
, PSETTINGS_DATA pData
)
727 TCHAR Message
[1024], Title
[256];
731 RtlZeroMemory(&devmode
, sizeof(devmode
));
732 devmode
.dmSize
= (WORD
)sizeof(devmode
);
733 devmode
.dmPelsWidth
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
734 devmode
.dmPelsHeight
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
735 devmode
.dmBitsPerPel
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
;
736 devmode
.dmDisplayFrequency
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmDisplayFrequency
;
737 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
| DM_BITSPERPEL
| DM_DISPLAYFREQUENCY
;
739 rc
= ChangeDisplaySettingsEx(pData
->CurrentDisplayDevice
->DeviceName
,
746 case DISP_CHANGE_SUCCESSFUL
:
749 case DISP_CHANGE_RESTART
:
750 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
751 LoadString(hApplet
, IDS_APPLY_NEEDS_RESTART
, Message
, sizeof(Message
) / sizeof (TCHAR
));
752 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONINFORMATION
);
755 case DISP_CHANGE_FAILED
:
757 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
758 LoadString(hApplet
, IDS_APPLY_FAILED
, Message
, sizeof(Message
) / sizeof (TCHAR
));
759 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONSTOP
);
763 if (DialogBox(hApplet
, MAKEINTRESOURCE(IDD_CONFIRMSETTINGS
), hwndDlg
, ConfirmDlgProc
) == IDYES
)
765 pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
;
766 pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
;
767 pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
= pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
;
771 devmode
.dmPelsWidth
= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
;
772 devmode
.dmPelsHeight
= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
;
773 devmode
.dmBitsPerPel
= pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
;
774 devmode
.dmDisplayFrequency
= pData
->CurrentDisplayDevice
->InitialSettings
.dmDisplayFrequency
;
776 rc
= ChangeDisplaySettingsEx(pData
->CurrentDisplayDevice
->DeviceName
,
783 case DISP_CHANGE_SUCCESSFUL
:
784 pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
;
785 pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
;
786 pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
= pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
;
787 UpdateDisplay(hwndDlg
, pData
, TRUE
);
790 case DISP_CHANGE_RESTART
:
791 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
792 LoadString(hApplet
, IDS_APPLY_NEEDS_RESTART
, Message
, sizeof(Message
) / sizeof (TCHAR
));
793 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONINFORMATION
);
796 case DISP_CHANGE_FAILED
:
798 LoadString(hApplet
, IDS_DISPLAY_SETTINGS
, Title
, sizeof(Title
) / sizeof(TCHAR
));
799 LoadString(hApplet
, IDS_APPLY_FAILED
, Message
, sizeof(Message
) / sizeof (TCHAR
));
800 MessageBox(hwndDlg
, Message
, Title
, MB_OK
| MB_ICONSTOP
);
806 /* Property page dialog callback */
808 SettingsPageProc(IN HWND hwndDlg
, IN UINT uMsg
, IN WPARAM wParam
, IN LPARAM lParam
)
810 PSETTINGS_DATA pData
;
812 pData
= (PSETTINGS_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
818 SettingsOnInitDialog(hwndDlg
);
823 LPDRAWITEMSTRUCT lpDrawItem
;
824 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
826 if (lpDrawItem
->CtlID
== IDC_SETTINGS_SPECTRUM
)
827 ShowColorSpectrum(lpDrawItem
->hDC
, &lpDrawItem
->rcItem
, pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
, pData
);
832 DWORD controlId
= LOWORD(wParam
);
833 DWORD command
= HIWORD(wParam
);
835 if (controlId
== IDC_SETTINGS_ADVANCED
&& command
== BN_CLICKED
)
836 DisplayAdvancedSettings(hwndDlg
, pData
->CurrentDisplayDevice
);
837 else if (controlId
== IDC_SETTINGS_BPP
&& command
== CBN_SELCHANGE
)
838 OnBPPChanged(hwndDlg
, pData
);
843 switch (LOWORD(wParam
))
853 DWORD newPosition
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_SETTINGS_RESOLUTION
, TBM_GETPOS
, 0, 0);
854 OnResolutionChanged(hwndDlg
, pData
, newPosition
, TRUE
);
859 OnResolutionChanged(hwndDlg
, pData
, HIWORD(wParam
), FALSE
);
866 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
867 if (lpnm
->code
== (UINT
)PSN_APPLY
)
869 if (pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsWidth
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsWidth
870 || pData
->CurrentDisplayDevice
->CurrentSettings
->dmPelsHeight
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmPelsHeight
871 || pData
->CurrentDisplayDevice
->CurrentSettings
->dmBitsPerPel
!= pData
->CurrentDisplayDevice
->InitialSettings
.dmBitsPerPel
)
873 /* Apply new settings */
874 ApplyDisplaySettings(hwndDlg
, pData
);
888 pt
.x
= (SHORT
)LOWORD(lParam
);
889 pt
.y
= (SHORT
)HIWORD(lParam
);
891 hwndMonSel
= GetDlgItem(hwndDlg
,
892 IDC_SETTINGS_MONSEL
);
893 if ((HWND
)wParam
== hwndMonSel
)
895 if (pt
.x
== -1 && pt
.y
== -1)
899 Index
= (INT
)SendMessage(hwndMonSel
,
905 (INT
)SendMessage(hwndMonSel
,
910 pt
.x
= rcMon
.left
+ ((rcMon
.right
- rcMon
.left
) / 2);
911 pt
.y
= rcMon
.top
+ ((rcMon
.bottom
- rcMon
.top
) / 2);
916 MapWindowPoints(hwndMonSel
,
924 MapWindowPoints(NULL
,
929 Index
= (INT
)SendMessage(hwndMonSel
,
937 hPopup
= LoadPopupMenu(hApplet
,
938 MAKEINTRESOURCE(IDM_MONITOR_MENU
));
941 /* FIXME: Enable/Disable menu items */
942 EnableMenuItem(hPopup
,
944 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
945 EnableMenuItem(hPopup
,
947 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
948 EnableMenuItem(hPopup
,
950 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
951 EnableMenuItem(hPopup
,
953 MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
955 uiCmd
= (UINT
)TrackPopupMenu(hPopup
,
956 TPM_RETURNCMD
| TPM_RIGHTBUTTON
,
965 case ID_MENU_ATTACHED
:
966 case ID_MENU_PRIMARY
:
967 case ID_MENU_IDENTIFY
:
968 case ID_MENU_PROPERTIES
:
969 /* FIXME: Implement */
983 PDISPLAY_DEVICE_ENTRY Current
= pData
->DisplayDeviceList
;
985 while (Current
!= NULL
)
987 PDISPLAY_DEVICE_ENTRY Next
= Current
->Flink
;
988 PSETTINGS_ENTRY CurrentSettings
= Current
->Settings
;
989 while (CurrentSettings
!= NULL
)
991 PSETTINGS_ENTRY NextSettings
= CurrentSettings
->Flink
;
992 HeapFree(GetProcessHeap(), 0, CurrentSettings
);
993 CurrentSettings
= NextSettings
;
995 HeapFree(GetProcessHeap(), 0, Current
);
999 for (i
= 0; i
< NUM_SPECTRUM_BITMAPS
; i
++)
1001 if (pData
->hSpectrumBitmaps
[i
])
1002 DeleteObject(pData
->hSpectrumBitmaps
[i
]);
1005 HeapFree(GetProcessHeap(), 0, pData
);