xref: /reactos/dll/shellext/deskmon/deskmon.c (revision fced1c11)
1c2c66affSColin Finck #include "precomp.h"
2c2c66affSColin Finck 
3c2c66affSColin Finck #include <tchar.h>
417154c94SStanislav Motylkov #include <winreg.h>
517154c94SStanislav Motylkov #include <cfgmgr32.h>
6c2c66affSColin Finck 
7c2c66affSColin Finck #define NDEBUG
8c2c66affSColin Finck #include <debug.h>
9c2c66affSColin Finck 
10c2c66affSColin Finck #include "resource.h"
11c2c66affSColin Finck 
12c2c66affSColin Finck static HINSTANCE hInstance;
1317154c94SStanislav Motylkov static BOOL bFoundAdapter;
1417154c94SStanislav Motylkov static DEVINST diAdapter;
15c2c66affSColin Finck 
16c2c66affSColin Finck #ifdef UNICODE
17c2c66affSColin Finck typedef INT_PTR (WINAPI *PDEVICEPROPERTIES)(HWND,LPCWSTR,LPCWSTR,BOOL);
18c2c66affSColin Finck #define FUNC_DEVICEPROPERTIES "DevicePropertiesW"
19c2c66affSColin Finck #else
20c2c66affSColin Finck typedef INT_PTR (WINAPI *PDEVICEPROPERTIES)(HWND,LPCSTR,LPCSTR,BOOL);
21c2c66affSColin Finck #define FUNC_DEVICEPROPERTIES "DevicePropertiesA"
22c2c66affSColin Finck #endif
23c2c66affSColin Finck 
2417154c94SStanislav Motylkov /**
2517154c94SStanislav Motylkov  * @brief
2617154c94SStanislav Motylkov  * Converts a Hardware ID (DeviceID from EnumDisplayDevices)
2717154c94SStanislav Motylkov  * to an unique Device Instance ID.
2817154c94SStanislav Motylkov  *
2917154c94SStanislav Motylkov  * @param[in] lpDeviceID
3017154c94SStanislav Motylkov  * A pointer to a null-terminated string
3117154c94SStanislav Motylkov  * containing a Hardware ID concatenated with driver key.
3217154c94SStanislav Motylkov  * e.g. "Monitor\Default_Monitor\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000"
3317154c94SStanislav Motylkov  *
3417154c94SStanislav Motylkov  * @return
3517154c94SStanislav Motylkov  * A pointer to a null-terminated string
3617154c94SStanislav Motylkov  * containing an unique Device Instance ID
3717154c94SStanislav Motylkov  * or NULL in case of error.
3817154c94SStanislav Motylkov  * e.g. "DISPLAY\DEFAULT_MONITOR\4&2ABFAA30&0&00000001&00&02"
3917154c94SStanislav Motylkov  *
4017154c94SStanislav Motylkov  * @remarks
4117154c94SStanislav Motylkov  * The caller must free the returned string with LocalFree.
4217154c94SStanislav Motylkov  */
43c2c66affSColin Finck static LPTSTR
GetMonitorDevInstID(LPCTSTR lpDeviceID)44c2c66affSColin Finck GetMonitorDevInstID(LPCTSTR lpDeviceID)
45c2c66affSColin Finck {
4617154c94SStanislav Motylkov     CONFIGRET cr;
4717154c94SStanislav Motylkov     DEVINST diChild;
4817154c94SStanislav Motylkov     TCHAR szProperty[256];
4917154c94SStanislav Motylkov     DWORD dwSize;
5017154c94SStanislav Motylkov     LPTSTR lpDevInstId = NULL;
5117154c94SStanislav Motylkov 
5217154c94SStanislav Motylkov     if (!bFoundAdapter)
53c2c66affSColin Finck         return NULL;
5417154c94SStanislav Motylkov 
5517154c94SStanislav Motylkov     /* Look for child monitor devices of selected video adapter */
5617154c94SStanislav Motylkov     cr = CM_Get_Child(&diChild, diAdapter, 0);
5717154c94SStanislav Motylkov     if (cr != CR_SUCCESS)
5817154c94SStanislav Motylkov     {
5917154c94SStanislav Motylkov         DPRINT1("CM_Get_Child failed: %d\n", cr);
6017154c94SStanislav Motylkov         return NULL;
6117154c94SStanislav Motylkov     }
6217154c94SStanislav Motylkov 
6317154c94SStanislav Motylkov     do
6417154c94SStanislav Motylkov     {
6517154c94SStanislav Motylkov         /* Get Hardware ID for each of them */
6617154c94SStanislav Motylkov         dwSize = sizeof(szProperty) - sizeof(TCHAR);
6717154c94SStanislav Motylkov 
6817154c94SStanislav Motylkov         cr = CM_Get_DevNode_Registry_Property(diChild,
6917154c94SStanislav Motylkov                                               CM_DRP_HARDWAREID,
7017154c94SStanislav Motylkov                                               NULL,
7117154c94SStanislav Motylkov                                               szProperty,
7217154c94SStanislav Motylkov                                               &dwSize,
7317154c94SStanislav Motylkov                                               0);
7417154c94SStanislav Motylkov         if (cr != CR_SUCCESS)
7517154c94SStanislav Motylkov         {
7617154c94SStanislav Motylkov             DPRINT1("CM_Get_DevNode_Registry_Property failed: %d\n", cr);
7717154c94SStanislav Motylkov             continue;
7817154c94SStanislav Motylkov         }
7917154c94SStanislav Motylkov 
8017154c94SStanislav Motylkov         /* Concatenate with driver key */
8117154c94SStanislav Motylkov         _tcscat(szProperty, TEXT("\\"));
8217154c94SStanislav Motylkov         dwSize = sizeof(szProperty) - sizeof(TCHAR);
8317154c94SStanislav Motylkov         dwSize -= _tcslen(szProperty) * sizeof(TCHAR);
8417154c94SStanislav Motylkov 
8517154c94SStanislav Motylkov         cr = CM_Get_DevNode_Registry_Property(diChild,
8617154c94SStanislav Motylkov                                               CM_DRP_DRIVER,
8717154c94SStanislav Motylkov                                               NULL,
8817154c94SStanislav Motylkov                                               szProperty + _tcslen(szProperty),
8917154c94SStanislav Motylkov                                               &dwSize,
9017154c94SStanislav Motylkov                                               0);
9117154c94SStanislav Motylkov         if (cr != CR_SUCCESS)
9217154c94SStanislav Motylkov         {
9317154c94SStanislav Motylkov             DPRINT1("CM_Get_DevNode_Registry_Property failed: %d\n", cr);
9417154c94SStanislav Motylkov             continue;
9517154c94SStanislav Motylkov         }
9617154c94SStanislav Motylkov 
9717154c94SStanislav Motylkov         /* If the strings match, this is our monitor device node */
9817154c94SStanislav Motylkov         if (_tcscmp(szProperty, lpDeviceID) == 0)
9917154c94SStanislav Motylkov         {
10017154c94SStanislav Motylkov             cr = CM_Get_Device_ID_Size(&dwSize,
10117154c94SStanislav Motylkov                                        diChild,
10217154c94SStanislav Motylkov                                        0);
10317154c94SStanislav Motylkov             if (cr != CR_SUCCESS)
10417154c94SStanislav Motylkov             {
10517154c94SStanislav Motylkov                 DPRINT1("CM_Get_Device_ID_Size failed: %d\n", cr);
10617154c94SStanislav Motylkov                 break;
10717154c94SStanislav Motylkov             }
10817154c94SStanislav Motylkov 
10917154c94SStanislav Motylkov             lpDevInstId = LocalAlloc(LMEM_FIXED,
11017154c94SStanislav Motylkov                                      (dwSize + 1) * sizeof(TCHAR));
11117154c94SStanislav Motylkov             if (lpDevInstId == NULL)
11217154c94SStanislav Motylkov             {
11317154c94SStanislav Motylkov                 DPRINT1("LocalAlloc failed\n");
11417154c94SStanislav Motylkov                 break;
11517154c94SStanislav Motylkov             }
11617154c94SStanislav Motylkov 
11717154c94SStanislav Motylkov             cr = CM_Get_Device_ID(diChild,
11817154c94SStanislav Motylkov                                   lpDevInstId,
11917154c94SStanislav Motylkov                                   dwSize + 1,
12017154c94SStanislav Motylkov                                   0);
12117154c94SStanislav Motylkov             if (cr != CR_SUCCESS)
12217154c94SStanislav Motylkov             {
12317154c94SStanislav Motylkov                 DPRINT1("CM_Get_Device_ID failed: %d\n", cr);
12417154c94SStanislav Motylkov                 LocalFree((HLOCAL)lpDevInstId);
12517154c94SStanislav Motylkov                 lpDevInstId = NULL;
12617154c94SStanislav Motylkov             }
12717154c94SStanislav Motylkov 
12817154c94SStanislav Motylkov             break;
12917154c94SStanislav Motylkov         }
13017154c94SStanislav Motylkov     } while (CM_Get_Sibling(&diChild, diChild, 0) == CR_SUCCESS);
13117154c94SStanislav Motylkov 
13217154c94SStanislav Motylkov     return lpDevInstId;
133c2c66affSColin Finck }
134c2c66affSColin Finck 
135c2c66affSColin Finck static VOID
ShowMonitorProperties(PDESKMONITOR This)136c2c66affSColin Finck ShowMonitorProperties(PDESKMONITOR This)
137c2c66affSColin Finck {
138c2c66affSColin Finck     HMODULE hDevMgr;
139c2c66affSColin Finck     PDEVICEPROPERTIES pDeviceProperties;
140c2c66affSColin Finck     LPTSTR lpDevInstID;
141c2c66affSColin Finck 
142c2c66affSColin Finck     if (This->SelMonitor != NULL)
143c2c66affSColin Finck     {
144c2c66affSColin Finck         lpDevInstID = GetMonitorDevInstID(This->SelMonitor->dd.DeviceID);
145c2c66affSColin Finck         if (lpDevInstID != NULL)
146c2c66affSColin Finck         {
147c2c66affSColin Finck             hDevMgr = LoadLibrary(TEXT("devmgr.dll"));
148c2c66affSColin Finck             if (hDevMgr != NULL)
149c2c66affSColin Finck             {
150c2c66affSColin Finck                 pDeviceProperties = (PDEVICEPROPERTIES)GetProcAddress(hDevMgr,
151c2c66affSColin Finck                                                                       FUNC_DEVICEPROPERTIES);
152c2c66affSColin Finck                 if (pDeviceProperties != NULL)
153c2c66affSColin Finck                 {
154c2c66affSColin Finck                     pDeviceProperties(This->hwndDlg,
155c2c66affSColin Finck                                       NULL,
15617154c94SStanislav Motylkov                                       lpDevInstID,
157c2c66affSColin Finck                                       FALSE);
158c2c66affSColin Finck                 }
159c2c66affSColin Finck 
160c2c66affSColin Finck                 FreeLibrary(hDevMgr);
161c2c66affSColin Finck             }
162c2c66affSColin Finck 
163c2c66affSColin Finck             LocalFree((HLOCAL)lpDevInstID);
164c2c66affSColin Finck         }
165c2c66affSColin Finck     }
166c2c66affSColin Finck }
167c2c66affSColin Finck 
168c2c66affSColin Finck static VOID
UpdateMonitorSelection(PDESKMONITOR This)169c2c66affSColin Finck UpdateMonitorSelection(PDESKMONITOR This)
170c2c66affSColin Finck {
171c2c66affSColin Finck     INT i;
17217154c94SStanislav Motylkov     LPTSTR lpDevInstID = NULL;
173c2c66affSColin Finck 
174c2c66affSColin Finck     if (This->dwMonitorCount > 1)
175c2c66affSColin Finck     {
176c2c66affSColin Finck         This->SelMonitor = NULL;
177c2c66affSColin Finck 
178c2c66affSColin Finck         i = (INT)SendDlgItemMessage(This->hwndDlg,
179c2c66affSColin Finck                                     IDC_MONITORLIST,
180c2c66affSColin Finck                                     LB_GETCURSEL,
181c2c66affSColin Finck                                     0,
182c2c66affSColin Finck                                     0);
183c2c66affSColin Finck         if (i >= 0)
184c2c66affSColin Finck         {
185c2c66affSColin Finck             This->SelMonitor = (PDESKMONINFO)SendDlgItemMessage(This->hwndDlg,
186c2c66affSColin Finck                                                                 IDC_MONITORLIST,
187c2c66affSColin Finck                                                                 LB_GETITEMDATA,
188c2c66affSColin Finck                                                                 (WPARAM)i,
189c2c66affSColin Finck                                                                 0);
190c2c66affSColin Finck         }
191c2c66affSColin Finck     }
192c2c66affSColin Finck     else
193c2c66affSColin Finck         This->SelMonitor = This->Monitors;
194c2c66affSColin Finck 
19517154c94SStanislav Motylkov     if (This->SelMonitor != NULL)
19617154c94SStanislav Motylkov         lpDevInstID = GetMonitorDevInstID(This->SelMonitor->dd.DeviceID);
19717154c94SStanislav Motylkov 
198c2c66affSColin Finck     EnableWindow(GetDlgItem(This->hwndDlg,
199c2c66affSColin Finck                             IDC_MONITORPROPERTIES),
20017154c94SStanislav Motylkov                  lpDevInstID != NULL && lpDevInstID[0] != TEXT('\0'));
20117154c94SStanislav Motylkov 
20217154c94SStanislav Motylkov     if (lpDevInstID != NULL)
20317154c94SStanislav Motylkov         LocalFree((HLOCAL)lpDevInstID);
204c2c66affSColin Finck }
205c2c66affSColin Finck 
206c2c66affSColin Finck static VOID
UpdatePruningControls(PDESKMONITOR This)207c2c66affSColin Finck UpdatePruningControls(PDESKMONITOR This)
208c2c66affSColin Finck {
209c2c66affSColin Finck     EnableWindow(GetDlgItem(This->hwndDlg,
210c2c66affSColin Finck                             IDC_PRUNINGCHECK),
211c2c66affSColin Finck                  This->bModesPruned && !This->bKeyIsReadOnly);
212c2c66affSColin Finck     CheckDlgButton(This->hwndDlg,
213c2c66affSColin Finck                    IDC_PRUNINGCHECK,
214c2c66affSColin Finck                    (This->bModesPruned && This->bPruningOn) ? BST_CHECKED : BST_UNCHECKED);
215c2c66affSColin Finck }
216c2c66affSColin Finck 
217c2c66affSColin Finck static VOID
GetPruningSettings(PDESKMONITOR This)218c2c66affSColin Finck GetPruningSettings(PDESKMONITOR This)
219c2c66affSColin Finck {
220c2c66affSColin Finck     BOOL bModesPruned = FALSE, bKeyIsReadOnly = FALSE, bPruningOn = FALSE;
221c2c66affSColin Finck 
222c2c66affSColin Finck     if (This->DeskExtInterface != NULL)
223c2c66affSColin Finck     {
224c2c66affSColin Finck         This->DeskExtInterface->GetPruningMode(This->DeskExtInterface->Context,
225c2c66affSColin Finck                                                &bModesPruned,
226c2c66affSColin Finck                                                &bKeyIsReadOnly,
227c2c66affSColin Finck                                                &bPruningOn);
228c2c66affSColin Finck     }
229c2c66affSColin Finck 
230c2c66affSColin Finck     /* Check the boolean values against zero before assigning it to the bitfields! */
231c2c66affSColin Finck     This->bModesPruned = (bModesPruned != FALSE);
232c2c66affSColin Finck     This->bKeyIsReadOnly = (bKeyIsReadOnly != FALSE);
233c2c66affSColin Finck     This->bPruningOn = (bPruningOn != FALSE);
234c2c66affSColin Finck 
235c2c66affSColin Finck     UpdatePruningControls(This);
236c2c66affSColin Finck }
237c2c66affSColin Finck 
238c2c66affSColin Finck static VOID
UpdateRefreshFrequencyList(PDESKMONITOR This)239c2c66affSColin Finck UpdateRefreshFrequencyList(PDESKMONITOR This)
240c2c66affSColin Finck {
241c2c66affSColin Finck     PDEVMODEW lpCurrentMode, lpMode;
242c2c66affSColin Finck     TCHAR szBuffer[64];
243c2c66affSColin Finck     DWORD dwIndex;
244c2c66affSColin Finck     INT i;
245c2c66affSColin Finck     BOOL bHasDef = FALSE;
246c2c66affSColin Finck     BOOL bAdded = FALSE;
247c2c66affSColin Finck 
248c2c66affSColin Finck     /* Fill the refresh rate combo box */
249c2c66affSColin Finck     SendDlgItemMessage(This->hwndDlg,
250c2c66affSColin Finck                        IDC_REFRESHRATE,
251c2c66affSColin Finck                        CB_RESETCONTENT,
252c2c66affSColin Finck                        0,
253c2c66affSColin Finck                        0);
254c2c66affSColin Finck 
255c2c66affSColin Finck     lpCurrentMode = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
256c2c66affSColin Finck     dwIndex = 0;
257c2c66affSColin Finck 
258c2c66affSColin Finck     do
259c2c66affSColin Finck     {
260c2c66affSColin Finck         lpMode = This->DeskExtInterface->EnumAllModes(This->DeskExtInterface->Context,
261c2c66affSColin Finck                                                       dwIndex++);
262c2c66affSColin Finck         if (lpMode != NULL &&
263c2c66affSColin Finck             lpMode->dmBitsPerPel == lpCurrentMode->dmBitsPerPel &&
264c2c66affSColin Finck             lpMode->dmPelsWidth == lpCurrentMode->dmPelsWidth &&
265c2c66affSColin Finck             lpMode->dmPelsHeight == lpCurrentMode->dmPelsHeight)
266c2c66affSColin Finck         {
267c2c66affSColin Finck             /* We're only interested in refresh rates for the current resolution and color depth */
268c2c66affSColin Finck 
269c2c66affSColin Finck             if (lpMode->dmDisplayFrequency <= 1)
270c2c66affSColin Finck             {
271c2c66affSColin Finck                 /* Default hardware frequency */
272c2c66affSColin Finck                 if (bHasDef)
273c2c66affSColin Finck                     continue;
274c2c66affSColin Finck 
275c2c66affSColin Finck                 bHasDef = TRUE;
276c2c66affSColin Finck 
277c2c66affSColin Finck                 if (!LoadString(hInstance,
278c2c66affSColin Finck                                 IDS_USEDEFFRQUENCY,
279c2c66affSColin Finck                                 szBuffer,
280c2c66affSColin Finck                                 sizeof(szBuffer) / sizeof(szBuffer[0])))
281c2c66affSColin Finck                 {
282c2c66affSColin Finck                     szBuffer[0] = TEXT('\0');
283c2c66affSColin Finck                 }
284c2c66affSColin Finck             }
285c2c66affSColin Finck             else
286c2c66affSColin Finck             {
287c2c66affSColin Finck                 TCHAR szFmt[64];
288c2c66affSColin Finck 
289c2c66affSColin Finck                 if (!LoadString(hInstance,
290c2c66affSColin Finck                                 IDS_FREQFMT,
291c2c66affSColin Finck                                 szFmt,
292c2c66affSColin Finck                                 sizeof(szFmt) / sizeof(szFmt[0])))
293c2c66affSColin Finck                 {
294c2c66affSColin Finck                     szFmt[0] = TEXT('\0');
295c2c66affSColin Finck                 }
296c2c66affSColin Finck 
297c2c66affSColin Finck                 _sntprintf(szBuffer,
298c2c66affSColin Finck                            sizeof(szBuffer) / sizeof(szBuffer[0]),
299c2c66affSColin Finck                            szFmt,
300c2c66affSColin Finck                            lpMode->dmDisplayFrequency);
301c2c66affSColin Finck             }
302c2c66affSColin Finck 
303c2c66affSColin Finck             i = (INT)SendDlgItemMessage(This->hwndDlg,
304c2c66affSColin Finck                                         IDC_REFRESHRATE,
305c2c66affSColin Finck                                         CB_ADDSTRING,
306c2c66affSColin Finck                                         0,
307c2c66affSColin Finck                                         (LPARAM)szBuffer);
308c2c66affSColin Finck             if (i >= 0)
309c2c66affSColin Finck             {
310c2c66affSColin Finck                 bAdded = TRUE;
311c2c66affSColin Finck 
312c2c66affSColin Finck                 SendDlgItemMessage(This->hwndDlg,
313c2c66affSColin Finck                                    IDC_REFRESHRATE,
314c2c66affSColin Finck                                    CB_SETITEMDATA,
315c2c66affSColin Finck                                    (WPARAM)i,
316c2c66affSColin Finck                                    (LPARAM)lpMode);
317c2c66affSColin Finck 
318c2c66affSColin Finck                 if (lpMode->dmDisplayFrequency == lpCurrentMode->dmDisplayFrequency)
319c2c66affSColin Finck                 {
320c2c66affSColin Finck                     SendDlgItemMessage(This->hwndDlg,
321c2c66affSColin Finck                                        IDC_REFRESHRATE,
322c2c66affSColin Finck                                        CB_SETCURSEL,
323c2c66affSColin Finck                                        (WPARAM)i,
324c2c66affSColin Finck                                        0);
325c2c66affSColin Finck                 }
326c2c66affSColin Finck             }
327c2c66affSColin Finck         }
328c2c66affSColin Finck 
329c2c66affSColin Finck     } while (lpMode != NULL);
330c2c66affSColin Finck 
331c2c66affSColin Finck     EnableWindow(GetDlgItem(This->hwndDlg,
332c2c66affSColin Finck                             IDS_MONITORSETTINGSGROUP),
333c2c66affSColin Finck                  bAdded);
334c2c66affSColin Finck     EnableWindow(GetDlgItem(This->hwndDlg,
335c2c66affSColin Finck                             IDS_REFRESHRATELABEL),
336c2c66affSColin Finck                  bAdded);
337c2c66affSColin Finck     EnableWindow(GetDlgItem(This->hwndDlg,
338c2c66affSColin Finck                             IDC_REFRESHRATE),
339c2c66affSColin Finck                  bAdded);
340c2c66affSColin Finck 
341c2c66affSColin Finck     GetPruningSettings(This);
342c2c66affSColin Finck }
343c2c66affSColin Finck 
344c2c66affSColin Finck static VOID
InitMonitorDialog(PDESKMONITOR This)345c2c66affSColin Finck InitMonitorDialog(PDESKMONITOR This)
346c2c66affSColin Finck {
347c2c66affSColin Finck     PDESKMONINFO pmi, pminext, *pmilink;
34817154c94SStanislav Motylkov     LPTSTR lpDeviceId;
34917154c94SStanislav Motylkov     CONFIGRET cr;
350c2c66affSColin Finck     DISPLAY_DEVICE dd;
351c2c66affSColin Finck     BOOL bRet;
352c2c66affSColin Finck     INT i;
353c2c66affSColin Finck     DWORD dwIndex;
354c2c66affSColin Finck 
355c2c66affSColin Finck     /* Free all allocated monitors */
356c2c66affSColin Finck     pmi = This->Monitors;
357c2c66affSColin Finck     This->Monitors = NULL;
358c2c66affSColin Finck     while (pmi != NULL)
359c2c66affSColin Finck     {
360c2c66affSColin Finck         pminext = pmi->Next;
361c2c66affSColin Finck         LocalFree((HLOCAL)pmi);
362c2c66affSColin Finck         pmi = pminext;
363c2c66affSColin Finck     }
364c2c66affSColin Finck 
365c2c66affSColin Finck     This->SelMonitor = NULL;
366c2c66affSColin Finck     This->dwMonitorCount = 0;
367c2c66affSColin Finck 
36817154c94SStanislav Motylkov     bFoundAdapter = FALSE;
36917154c94SStanislav Motylkov     lpDeviceId = QueryDeskCplString(This->pdtobj,
37017154c94SStanislav Motylkov                                     RegisterClipboardFormat(DESK_EXT_DISPLAYID));
37117154c94SStanislav Motylkov 
37217154c94SStanislav Motylkov     if (lpDeviceId != NULL && lpDeviceId[0] != TEXT('\0'))
37317154c94SStanislav Motylkov     {
37417154c94SStanislav Motylkov         cr = CM_Locate_DevNode(&diAdapter,
37517154c94SStanislav Motylkov                                lpDeviceId,
37617154c94SStanislav Motylkov                                CM_LOCATE_DEVNODE_NORMAL);
37717154c94SStanislav Motylkov         bFoundAdapter = (cr == CR_SUCCESS);
37817154c94SStanislav Motylkov 
37917154c94SStanislav Motylkov         if (!bFoundAdapter)
38017154c94SStanislav Motylkov             DPRINT1("CM_Locate_DevNode failed: %d\n", cr);
38117154c94SStanislav Motylkov     }
38217154c94SStanislav Motylkov 
383c2c66affSColin Finck     if (This->lpDisplayDevice != NULL)
384c2c66affSColin Finck         LocalFree((HLOCAL)This->lpDisplayDevice);
385c2c66affSColin Finck 
386c2c66affSColin Finck     This->lpDisplayDevice = QueryDeskCplString(This->pdtobj,
387c2c66affSColin Finck                                                RegisterClipboardFormat(DESK_EXT_DISPLAYDEVICE));
388c2c66affSColin Finck 
389c2c66affSColin Finck     if (This->DeskExtInterface != NULL)
390c2c66affSColin Finck     {
391c2c66affSColin Finck         if (This->lpDisplayDevice != NULL)
392c2c66affSColin Finck         {
393c2c66affSColin Finck             /* Enumerate all monitors */
394c2c66affSColin Finck             dwIndex = 0;
395c2c66affSColin Finck             pmilink = &This->Monitors;
396c2c66affSColin Finck 
397c2c66affSColin Finck             do
398c2c66affSColin Finck             {
399c2c66affSColin Finck                 dd.cb = sizeof(dd);
400c2c66affSColin Finck                 bRet = EnumDisplayDevices(This->lpDisplayDevice,
401c2c66affSColin Finck                                           dwIndex++,
402c2c66affSColin Finck                                           &dd,
403c2c66affSColin Finck                                           0);
404c2c66affSColin Finck                 if (bRet)
405c2c66affSColin Finck                 {
406c2c66affSColin Finck                     pmi = LocalAlloc(LMEM_FIXED,
407c2c66affSColin Finck                                      sizeof(*pmi));
408c2c66affSColin Finck                     if (pmi != NULL)
409c2c66affSColin Finck                     {
410c2c66affSColin Finck                         CopyMemory(&pmi->dd,
411c2c66affSColin Finck                                    &dd,
412c2c66affSColin Finck                                    sizeof(dd));
413c2c66affSColin Finck                         pmi->Next = NULL;
414c2c66affSColin Finck                         *pmilink = pmi;
415c2c66affSColin Finck                         pmilink = &pmi->Next;
416c2c66affSColin Finck 
417c2c66affSColin Finck                         This->dwMonitorCount++;
418c2c66affSColin Finck                     }
419c2c66affSColin Finck                 }
420c2c66affSColin Finck             } while (bRet);
421c2c66affSColin Finck         }
422c2c66affSColin Finck 
423c2c66affSColin Finck         This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
424c2c66affSColin Finck     }
425c2c66affSColin Finck     else
426c2c66affSColin Finck         This->lpDevModeOnInit = NULL;
427c2c66affSColin Finck 
428c2c66affSColin Finck     This->lpSelDevMode = This->lpDevModeOnInit;
429c2c66affSColin Finck 
430c2c66affSColin Finck     /* Setup the UI depending on how many monitors are attached */
431c2c66affSColin Finck     if (This->dwMonitorCount == 0)
432c2c66affSColin Finck     {
433c2c66affSColin Finck         LPTSTR lpMonitorName;
434c2c66affSColin Finck 
435c2c66affSColin Finck         /* This is a fallback, let's hope that desk.cpl can provide us with a monitor name */
436c2c66affSColin Finck         lpMonitorName = QueryDeskCplString(This->pdtobj,
437c2c66affSColin Finck                                            RegisterClipboardFormat(DESK_EXT_MONITORNAME));
438c2c66affSColin Finck 
439c2c66affSColin Finck         SetDlgItemText(This->hwndDlg,
440c2c66affSColin Finck                        IDC_MONITORNAME,
441c2c66affSColin Finck                        lpMonitorName);
442c2c66affSColin Finck 
443c2c66affSColin Finck         if (lpMonitorName != NULL)
444c2c66affSColin Finck             LocalFree((HLOCAL)lpMonitorName);
445c2c66affSColin Finck     }
446c2c66affSColin Finck     else if (This->dwMonitorCount == 1)
447c2c66affSColin Finck     {
448c2c66affSColin Finck         This->SelMonitor = This->Monitors;
449c2c66affSColin Finck         SetDlgItemText(This->hwndDlg,
450c2c66affSColin Finck                        IDC_MONITORNAME,
451c2c66affSColin Finck                        This->Monitors->dd.DeviceString);
452c2c66affSColin Finck     }
453c2c66affSColin Finck     else
454c2c66affSColin Finck     {
455c2c66affSColin Finck         SendDlgItemMessage(This->hwndDlg,
456c2c66affSColin Finck                            IDC_MONITORLIST,
457c2c66affSColin Finck                            LB_RESETCONTENT,
458c2c66affSColin Finck                            0,
459c2c66affSColin Finck                            0);
460c2c66affSColin Finck 
461c2c66affSColin Finck         pmi = This->Monitors;
462c2c66affSColin Finck         while (pmi != NULL)
463c2c66affSColin Finck         {
464c2c66affSColin Finck             i = (INT)SendDlgItemMessage(This->hwndDlg,
465c2c66affSColin Finck                                         IDC_MONITORLIST,
466c2c66affSColin Finck                                         LB_ADDSTRING,
467c2c66affSColin Finck                                         0,
468c2c66affSColin Finck                                         (LPARAM)pmi->dd.DeviceString);
469c2c66affSColin Finck             if (i >= 0)
470c2c66affSColin Finck             {
471c2c66affSColin Finck                 SendDlgItemMessage(This->hwndDlg,
472c2c66affSColin Finck                                    IDC_MONITORLIST,
473c2c66affSColin Finck                                    LB_SETITEMDATA,
474c2c66affSColin Finck                                    (WPARAM)i,
475c2c66affSColin Finck                                    (LPARAM)pmi);
476c2c66affSColin Finck 
477c2c66affSColin Finck                 if (This->SelMonitor == NULL)
478c2c66affSColin Finck                 {
479c2c66affSColin Finck                     SendDlgItemMessage(This->hwndDlg,
480c2c66affSColin Finck                                        IDC_MONITORLIST,
481c2c66affSColin Finck                                        LB_SETCURSEL,
482c2c66affSColin Finck                                        (WPARAM)i,
483c2c66affSColin Finck                                        0);
484c2c66affSColin Finck 
485c2c66affSColin Finck                     This->SelMonitor = pmi;
486c2c66affSColin Finck                 }
487c2c66affSColin Finck             }
488c2c66affSColin Finck 
489c2c66affSColin Finck             pmi = pmi->Next;
490c2c66affSColin Finck         }
491c2c66affSColin Finck     }
492c2c66affSColin Finck 
493c2c66affSColin Finck     /* Show/Hide controls */
494c2c66affSColin Finck     ShowWindow(GetDlgItem(This->hwndDlg,
495c2c66affSColin Finck                           IDC_MONITORNAME),
496c2c66affSColin Finck                (This->dwMonitorCount <= 1 ? SW_SHOW : SW_HIDE));
497c2c66affSColin Finck     ShowWindow(GetDlgItem(This->hwndDlg,
498c2c66affSColin Finck                           IDC_MONITORLIST),
499c2c66affSColin Finck                (This->dwMonitorCount > 1 ? SW_SHOW : SW_HIDE));
500c2c66affSColin Finck 
501c2c66affSColin Finck     UpdateRefreshFrequencyList(This);
502c2c66affSColin Finck     UpdateMonitorSelection(This);
503c2c66affSColin Finck }
504c2c66affSColin Finck 
505c2c66affSColin Finck static VOID
UpdatePruningSelection(PDESKMONITOR This)506c2c66affSColin Finck UpdatePruningSelection(PDESKMONITOR This)
507c2c66affSColin Finck {
508c2c66affSColin Finck     BOOL bPruningOn;
509c2c66affSColin Finck 
510c2c66affSColin Finck     if (This->DeskExtInterface != NULL && This->bModesPruned && !This->bKeyIsReadOnly)
511c2c66affSColin Finck     {
512c2c66affSColin Finck         bPruningOn = IsDlgButtonChecked(This->hwndDlg,
513c2c66affSColin Finck                                         IDC_PRUNINGCHECK) != BST_UNCHECKED;
514c2c66affSColin Finck 
515c2c66affSColin Finck         if (bPruningOn != This->bPruningOn)
516c2c66affSColin Finck         {
517c2c66affSColin Finck             /* Tell desk.cpl to turn on/off pruning mode */
518c2c66affSColin Finck             This->bPruningOn = bPruningOn;
519c2c66affSColin Finck             This->DeskExtInterface->SetPruningMode(This->DeskExtInterface->Context,
520c2c66affSColin Finck                                                    bPruningOn);
521c2c66affSColin Finck 
522c2c66affSColin Finck             /* Fill the refresh rate combobox again, we now receive a filtered
523c2c66affSColin Finck                or unfiltered device mode list from desk.cpl (depending on whether
524c2c66affSColin Finck                pruning is active or not) */
525c2c66affSColin Finck             UpdateRefreshFrequencyList(This);
526c2c66affSColin Finck 
527c2c66affSColin Finck             (void)PropSheet_Changed(GetParent(This->hwndDlg),
528c2c66affSColin Finck                                     This->hwndDlg);
529c2c66affSColin Finck         }
530c2c66affSColin Finck     }
531c2c66affSColin Finck }
532c2c66affSColin Finck 
533c2c66affSColin Finck static VOID
UpdateRefreshRateSelection(PDESKMONITOR This)534c2c66affSColin Finck UpdateRefreshRateSelection(PDESKMONITOR This)
535c2c66affSColin Finck {
536c2c66affSColin Finck     PDEVMODEW lpCurrentDevMode;
537c2c66affSColin Finck     INT i;
538c2c66affSColin Finck 
539c2c66affSColin Finck     if (This->DeskExtInterface != NULL)
540c2c66affSColin Finck     {
541c2c66affSColin Finck         i = (INT)SendDlgItemMessage(This->hwndDlg,
542c2c66affSColin Finck                                     IDC_REFRESHRATE,
543c2c66affSColin Finck                                     CB_GETCURSEL,
544c2c66affSColin Finck                                     0,
545c2c66affSColin Finck                                     0);
546c2c66affSColin Finck         if (i >= 0)
547c2c66affSColin Finck         {
548c2c66affSColin Finck             lpCurrentDevMode = This->lpSelDevMode;
549c2c66affSColin Finck             This->lpSelDevMode = (PDEVMODEW)SendDlgItemMessage(This->hwndDlg,
550c2c66affSColin Finck                                                                IDC_REFRESHRATE,
551c2c66affSColin Finck                                                                CB_GETITEMDATA,
552c2c66affSColin Finck                                                                (WPARAM)i,
553c2c66affSColin Finck                                                                0);
554c2c66affSColin Finck 
555c2c66affSColin Finck             if (This->lpSelDevMode != NULL && This->lpSelDevMode != lpCurrentDevMode)
556c2c66affSColin Finck             {
557c2c66affSColin Finck                 This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
558c2c66affSColin Finck                                                        This->lpSelDevMode);
559c2c66affSColin Finck 
560c2c66affSColin Finck                 UpdateRefreshFrequencyList(This);
561c2c66affSColin Finck 
562c2c66affSColin Finck                 (void)PropSheet_Changed(GetParent(This->hwndDlg),
563c2c66affSColin Finck                                         This->hwndDlg);
564c2c66affSColin Finck             }
565c2c66affSColin Finck         }
566c2c66affSColin Finck     }
567c2c66affSColin Finck }
568c2c66affSColin Finck 
569c2c66affSColin Finck static LONG
ApplyMonitorChanges(PDESKMONITOR This)570c2c66affSColin Finck ApplyMonitorChanges(PDESKMONITOR This)
571c2c66affSColin Finck {
572c2c66affSColin Finck     LONG lChangeRet;
573c2c66affSColin Finck 
574c2c66affSColin Finck     if (This->DeskExtInterface != NULL)
575c2c66affSColin Finck     {
576c2c66affSColin Finck         /* Change the display settings through desk.cpl */
577c2c66affSColin Finck         lChangeRet = DeskCplExtDisplaySaveSettings(This->DeskExtInterface,
578c2c66affSColin Finck                                                    This->hwndDlg);
579c2c66affSColin Finck         if (lChangeRet == DISP_CHANGE_SUCCESSFUL)
580c2c66affSColin Finck         {
581c2c66affSColin Finck             /* Save the new mode */
582c2c66affSColin Finck             This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
583c2c66affSColin Finck             This->lpSelDevMode = This->lpDevModeOnInit;
584c2c66affSColin Finck             return PSNRET_NOERROR;
585c2c66affSColin Finck         }
586c2c66affSColin Finck         else if (lChangeRet == DISP_CHANGE_RESTART)
587c2c66affSColin Finck         {
588c2c66affSColin Finck             /* Notify desk.cpl that the user needs to reboot */
589c2c66affSColin Finck             PropSheet_RestartWindows(GetParent(This->hwndDlg));
590c2c66affSColin Finck             return PSNRET_NOERROR;
591c2c66affSColin Finck         }
592c2c66affSColin Finck     }
593c2c66affSColin Finck 
594c2c66affSColin Finck     InitMonitorDialog(This);
595c2c66affSColin Finck 
596c2c66affSColin Finck     return PSNRET_INVALID_NOCHANGEPAGE;
597c2c66affSColin Finck }
598c2c66affSColin Finck 
599c2c66affSColin Finck static VOID
ResetMonitorChanges(PDESKMONITOR This)600c2c66affSColin Finck ResetMonitorChanges(PDESKMONITOR This)
601c2c66affSColin Finck {
602c2c66affSColin Finck     if (This->DeskExtInterface != NULL && This->lpDevModeOnInit != NULL)
603c2c66affSColin Finck     {
604c2c66affSColin Finck         This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
605c2c66affSColin Finck                                                This->lpDevModeOnInit);
606c2c66affSColin Finck     }
607c2c66affSColin Finck }
608c2c66affSColin Finck 
609c2c66affSColin Finck static INT_PTR CALLBACK
MonitorDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)610c2c66affSColin Finck MonitorDlgProc(HWND hwndDlg,
611c2c66affSColin Finck                UINT uMsg,
612c2c66affSColin Finck                WPARAM wParam,
613c2c66affSColin Finck                LPARAM lParam)
614c2c66affSColin Finck {
615c2c66affSColin Finck     PDESKMONITOR This;
616c2c66affSColin Finck     INT_PTR Ret = 0;
617c2c66affSColin Finck 
618c2c66affSColin Finck     if (uMsg != WM_INITDIALOG)
619c2c66affSColin Finck     {
6200182dcd7STimo Kreuzer         This = (PDESKMONITOR)GetWindowLongPtr(hwndDlg, DWLP_USER);
621c2c66affSColin Finck     }
622c2c66affSColin Finck 
623c2c66affSColin Finck     switch (uMsg)
624c2c66affSColin Finck     {
625c2c66affSColin Finck         case WM_INITDIALOG:
626c2c66affSColin Finck             This = (PDESKMONITOR)((LPCPROPSHEETPAGE)lParam)->lParam;
627c2c66affSColin Finck             This->hwndDlg = hwndDlg;
6280182dcd7STimo Kreuzer             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
629c2c66affSColin Finck 
630c2c66affSColin Finck             InitMonitorDialog(This);
631c2c66affSColin Finck             Ret = TRUE;
632c2c66affSColin Finck             break;
633c2c66affSColin Finck 
634c2c66affSColin Finck         case WM_COMMAND:
635c2c66affSColin Finck             switch (LOWORD(wParam))
636c2c66affSColin Finck             {
637c2c66affSColin Finck                 case IDC_MONITORPROPERTIES:
638c2c66affSColin Finck                     ShowMonitorProperties(This);
639c2c66affSColin Finck                     break;
640c2c66affSColin Finck 
641c2c66affSColin Finck                 case IDC_MONITORLIST:
642c2c66affSColin Finck                     if (HIWORD(wParam) == LBN_SELCHANGE)
643c2c66affSColin Finck                         UpdateMonitorSelection(This);
644c2c66affSColin Finck                     break;
645c2c66affSColin Finck 
646c2c66affSColin Finck                 case IDC_PRUNINGCHECK:
647c2c66affSColin Finck                     if (HIWORD(wParam) == BN_CLICKED)
648c2c66affSColin Finck                         UpdatePruningSelection(This);
649c2c66affSColin Finck                     break;
650c2c66affSColin Finck 
651c2c66affSColin Finck                 case IDC_REFRESHRATE:
652c2c66affSColin Finck                     if (HIWORD(wParam) == CBN_SELCHANGE)
653c2c66affSColin Finck                         UpdateRefreshRateSelection(This);
654c2c66affSColin Finck                     break;
655c2c66affSColin Finck             }
656c2c66affSColin Finck             break;
657c2c66affSColin Finck 
658c2c66affSColin Finck         case WM_NOTIFY:
659c2c66affSColin Finck         {
660c2c66affSColin Finck             NMHDR *nmh = (NMHDR *)lParam;
661c2c66affSColin Finck 
662c2c66affSColin Finck             switch (nmh->code)
663c2c66affSColin Finck             {
664c2c66affSColin Finck                 case PSN_APPLY:
665c2c66affSColin Finck                 {
666c2c66affSColin Finck                     SetWindowLongPtr(hwndDlg,
6670182dcd7STimo Kreuzer                                      DWLP_MSGRESULT,
668c2c66affSColin Finck                                      ApplyMonitorChanges(This));
669*fced1c11SStanislav Motylkov                     Ret = TRUE;
670c2c66affSColin Finck                     break;
671c2c66affSColin Finck                 }
672c2c66affSColin Finck 
673c2c66affSColin Finck                 case PSN_RESET:
674c2c66affSColin Finck                     ResetMonitorChanges(This);
675c2c66affSColin Finck                     break;
676c2c66affSColin Finck 
677c2c66affSColin Finck                 case PSN_SETACTIVE:
678c2c66affSColin Finck                     UpdateRefreshFrequencyList(This);
679c2c66affSColin Finck                     break;
680c2c66affSColin Finck             }
681c2c66affSColin Finck             break;
682c2c66affSColin Finck         }
683c2c66affSColin Finck     }
684c2c66affSColin Finck 
685c2c66affSColin Finck     return Ret;
686c2c66affSColin Finck }
687c2c66affSColin Finck 
688c2c66affSColin Finck static VOID
IDeskMonitor_Destroy(PDESKMONITOR This)689c2c66affSColin Finck IDeskMonitor_Destroy(PDESKMONITOR This)
690c2c66affSColin Finck {
691c2c66affSColin Finck     PDESKMONINFO pmi, pminext;
692c2c66affSColin Finck 
693c2c66affSColin Finck     if (This->pdtobj != NULL)
694c2c66affSColin Finck     {
695c2c66affSColin Finck         IDataObject_Release(This->pdtobj);
696c2c66affSColin Finck         This->pdtobj = NULL;
697c2c66affSColin Finck     }
698c2c66affSColin Finck 
699c2c66affSColin Finck     if (This->DeskExtInterface != NULL)
700c2c66affSColin Finck     {
701c2c66affSColin Finck         LocalFree((HLOCAL)This->DeskExtInterface);
702c2c66affSColin Finck         This->DeskExtInterface = NULL;
703c2c66affSColin Finck     }
704c2c66affSColin Finck 
705c2c66affSColin Finck     if (This->lpDisplayDevice != NULL)
706c2c66affSColin Finck     {
707c2c66affSColin Finck         LocalFree((HLOCAL)This->lpDisplayDevice);
708c2c66affSColin Finck         This->lpDisplayDevice = NULL;
709c2c66affSColin Finck     }
710c2c66affSColin Finck 
711c2c66affSColin Finck     /* Free all monitors */
712c2c66affSColin Finck     pmi = This->Monitors;
713c2c66affSColin Finck     This->Monitors = NULL;
714c2c66affSColin Finck     while (pmi != NULL)
715c2c66affSColin Finck     {
716c2c66affSColin Finck         pminext = pmi->Next;
717c2c66affSColin Finck         LocalFree((HLOCAL)pmi);
718c2c66affSColin Finck         pmi = pminext;
719c2c66affSColin Finck     }
720c2c66affSColin Finck }
721c2c66affSColin Finck 
722c2c66affSColin Finck ULONG
IDeskMonitor_AddRef(PDESKMONITOR This)723c2c66affSColin Finck IDeskMonitor_AddRef(PDESKMONITOR This)
724c2c66affSColin Finck {
725c2c66affSColin Finck     ULONG ret;
726c2c66affSColin Finck 
727c2c66affSColin Finck     ret = InterlockedIncrement((PLONG)&This->ref);
728c2c66affSColin Finck     if (ret == 1)
729c2c66affSColin Finck         InterlockedIncrement(&dll_refs);
730c2c66affSColin Finck 
731c2c66affSColin Finck     return ret;
732c2c66affSColin Finck }
733c2c66affSColin Finck 
734c2c66affSColin Finck ULONG
IDeskMonitor_Release(PDESKMONITOR This)735c2c66affSColin Finck IDeskMonitor_Release(PDESKMONITOR This)
736c2c66affSColin Finck {
737c2c66affSColin Finck     ULONG ret;
738c2c66affSColin Finck 
739c2c66affSColin Finck     ret = InterlockedDecrement((PLONG)&This->ref);
740c2c66affSColin Finck     if (ret == 0)
741c2c66affSColin Finck     {
742c2c66affSColin Finck         IDeskMonitor_Destroy(This);
743c2c66affSColin Finck         InterlockedDecrement(&dll_refs);
744c2c66affSColin Finck 
745c2c66affSColin Finck         HeapFree(GetProcessHeap(),
746c2c66affSColin Finck                  0,
747c2c66affSColin Finck                  This);
748c2c66affSColin Finck     }
749c2c66affSColin Finck 
750c2c66affSColin Finck     return ret;
751c2c66affSColin Finck }
752c2c66affSColin Finck 
753c2c66affSColin Finck HRESULT STDMETHODCALLTYPE
IDeskMonitor_QueryInterface(PDESKMONITOR This,REFIID iid,PVOID * pvObject)754c2c66affSColin Finck IDeskMonitor_QueryInterface(PDESKMONITOR This,
755c2c66affSColin Finck                             REFIID iid,
756c2c66affSColin Finck                             PVOID *pvObject)
757c2c66affSColin Finck {
758c2c66affSColin Finck     *pvObject = NULL;
759c2c66affSColin Finck 
760c2c66affSColin Finck     if (IsEqualIID(iid,
761c2c66affSColin Finck                    &IID_IShellPropSheetExt) ||
762c2c66affSColin Finck         IsEqualIID(iid,
763c2c66affSColin Finck                    &IID_IUnknown))
764c2c66affSColin Finck     {
765c2c66affSColin Finck         *pvObject = impl_to_interface(This, IShellPropSheetExt);
766c2c66affSColin Finck     }
767c2c66affSColin Finck     else if (IsEqualIID(iid,
768c2c66affSColin Finck                         &IID_IShellExtInit))
769c2c66affSColin Finck     {
770c2c66affSColin Finck         *pvObject = impl_to_interface(This, IShellExtInit);
771c2c66affSColin Finck     }
772c2c66affSColin Finck     else if (IsEqualIID(iid,
773c2c66affSColin Finck                         &IID_IClassFactory))
774c2c66affSColin Finck     {
775c2c66affSColin Finck         *pvObject = impl_to_interface(This, IClassFactory);
776c2c66affSColin Finck     }
777c2c66affSColin Finck     else
778c2c66affSColin Finck     {
779c2c66affSColin Finck         DPRINT1("IDeskMonitor::QueryInterface(%p,%p): E_NOINTERFACE\n", iid, pvObject);
780c2c66affSColin Finck         return E_NOINTERFACE;
781c2c66affSColin Finck     }
782c2c66affSColin Finck 
783c2c66affSColin Finck     IDeskMonitor_AddRef(This);
784c2c66affSColin Finck     return S_OK;
785c2c66affSColin Finck }
786c2c66affSColin Finck 
787c2c66affSColin Finck HRESULT
IDeskMonitor_Initialize(PDESKMONITOR This,LPCITEMIDLIST pidlFolder,IDataObject * pdtobj,HKEY hkeyProgID)788c2c66affSColin Finck IDeskMonitor_Initialize(PDESKMONITOR This,
789c2c66affSColin Finck                         LPCITEMIDLIST pidlFolder,
790c2c66affSColin Finck                         IDataObject *pdtobj,
791c2c66affSColin Finck                         HKEY hkeyProgID)
792c2c66affSColin Finck {
793c2c66affSColin Finck     DPRINT1("IDeskMonitor::Initialize(%p,%p,%p)\n", pidlFolder, pdtobj, hkeyProgID);
794c2c66affSColin Finck 
795c2c66affSColin Finck     if (pdtobj != NULL)
796c2c66affSColin Finck     {
797c2c66affSColin Finck         IDataObject_AddRef(pdtobj);
798c2c66affSColin Finck         This->pdtobj = pdtobj;
799c2c66affSColin Finck 
800c2c66affSColin Finck         /* Get a copy of the desk.cpl extension interface */
801c2c66affSColin Finck         This->DeskExtInterface = QueryDeskCplExtInterface(This->pdtobj);
802c2c66affSColin Finck         if (This->DeskExtInterface != NULL)
803c2c66affSColin Finck             return S_OK;
804c2c66affSColin Finck     }
805c2c66affSColin Finck 
806c2c66affSColin Finck     return S_FALSE;
807c2c66affSColin Finck }
808c2c66affSColin Finck 
809c2c66affSColin Finck HRESULT
IDeskMonitor_AddPages(PDESKMONITOR This,LPFNADDPROPSHEETPAGE pfnAddPage,LPARAM lParam)810c2c66affSColin Finck IDeskMonitor_AddPages(PDESKMONITOR This,
811c2c66affSColin Finck                       LPFNADDPROPSHEETPAGE pfnAddPage,
812c2c66affSColin Finck                       LPARAM lParam)
813c2c66affSColin Finck {
814c2c66affSColin Finck     HPROPSHEETPAGE hpsp;
815c2c66affSColin Finck     PROPSHEETPAGE psp;
816c2c66affSColin Finck 
817c2c66affSColin Finck     DPRINT1("IDeskMonitor::AddPages(%p,%p)\n", pfnAddPage, lParam);
818c2c66affSColin Finck 
819c2c66affSColin Finck     psp.dwSize = sizeof(psp);
820c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT;
821c2c66affSColin Finck     psp.hInstance = hInstance;
822c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_MONITOR);
823c2c66affSColin Finck     psp.pfnDlgProc = MonitorDlgProc;
824c2c66affSColin Finck     psp.lParam = (LPARAM)This;
825c2c66affSColin Finck 
826c2c66affSColin Finck     hpsp = CreatePropertySheetPage(&psp);
827c2c66affSColin Finck     if (hpsp != NULL && pfnAddPage(hpsp, lParam))
828c2c66affSColin Finck         return S_OK;
829c2c66affSColin Finck 
830c2c66affSColin Finck     return S_FALSE;
831c2c66affSColin Finck }
832c2c66affSColin Finck 
833c2c66affSColin Finck HRESULT
IDeskMonitor_ReplacePage(PDESKMONITOR This,EXPPS uPageID,LPFNADDPROPSHEETPAGE pfnReplacePage,LPARAM lParam)834c2c66affSColin Finck IDeskMonitor_ReplacePage(PDESKMONITOR This,
835c2c66affSColin Finck                          EXPPS uPageID,
836c2c66affSColin Finck                          LPFNADDPROPSHEETPAGE pfnReplacePage,
837c2c66affSColin Finck                          LPARAM lParam)
838c2c66affSColin Finck {
839c2c66affSColin Finck     DPRINT1("IDeskMonitor::ReplacePage(%u,%p,%p)\n", uPageID, pfnReplacePage, lParam);
840c2c66affSColin Finck     return E_NOTIMPL;
841c2c66affSColin Finck }
842c2c66affSColin Finck 
843c2c66affSColin Finck HRESULT
IDeskMonitor_Constructor(REFIID riid,LPVOID * ppv)844c2c66affSColin Finck IDeskMonitor_Constructor(REFIID riid,
845c2c66affSColin Finck                          LPVOID *ppv)
846c2c66affSColin Finck {
847c2c66affSColin Finck     PDESKMONITOR This;
848c2c66affSColin Finck     HRESULT hRet = E_OUTOFMEMORY;
849c2c66affSColin Finck 
850c2c66affSColin Finck     DPRINT1("IDeskMonitor::Constructor(%p,%p)\n", riid, ppv);
851c2c66affSColin Finck 
852c2c66affSColin Finck     This = HeapAlloc(GetProcessHeap(),
853c2c66affSColin Finck                      0,
854c2c66affSColin Finck                      sizeof(*This));
855c2c66affSColin Finck     if (This != NULL)
856c2c66affSColin Finck     {
857c2c66affSColin Finck         ZeroMemory(This,
858c2c66affSColin Finck                    sizeof(*This));
859c2c66affSColin Finck 
860c2c66affSColin Finck         IDeskMonitor_InitIface(This);
861c2c66affSColin Finck 
862c2c66affSColin Finck         hRet = IDeskMonitor_QueryInterface(This,
863c2c66affSColin Finck                                            riid,
864c2c66affSColin Finck                                            ppv);
865c2c66affSColin Finck         if (!SUCCEEDED(hRet))
866c2c66affSColin Finck             IDeskMonitor_Release(This);
867c2c66affSColin Finck     }
868c2c66affSColin Finck 
869c2c66affSColin Finck     return hRet;
870c2c66affSColin Finck }
871c2c66affSColin Finck 
872c2c66affSColin Finck BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD dwReason,LPVOID lpvReserved)873c2c66affSColin Finck DllMain(HINSTANCE hinstDLL,
874c2c66affSColin Finck         DWORD dwReason,
875c2c66affSColin Finck         LPVOID lpvReserved)
876c2c66affSColin Finck {
877c2c66affSColin Finck     switch (dwReason)
878c2c66affSColin Finck     {
879c2c66affSColin Finck         case DLL_PROCESS_ATTACH:
880c2c66affSColin Finck             hInstance = hinstDLL;
881c2c66affSColin Finck             DisableThreadLibraryCalls(hInstance);
882c2c66affSColin Finck             break;
883c2c66affSColin Finck     }
884c2c66affSColin Finck 
885c2c66affSColin Finck     return TRUE;
886c2c66affSColin Finck }
887