[SHELLEXT][MYDOCS][INF] Add mydocs.dll and .mydocs file extension (#2624)
[reactos.git] / dll / shellext / deskadp / deskadp.c
1 #include "precomp.h"
2
3 #include <tchar.h>
4
5 #define NDEBUG
6 #include <debug.h>
7
8 #include "resource.h"
9
10 static HINSTANCE hInstance;
11
12 typedef INT_PTR (WINAPI *PDEVICEPROPERTIESW)(HWND,LPCWSTR,LPCWSTR,BOOL);
13
14 static VOID
15 GetColorDescription(PDEVMODEW lpDevMode,
16 LPTSTR lpBuffer,
17 DWORD dwBufferLen)
18 {
19 UINT uid = 0;
20
21 switch (lpDevMode->dmBitsPerPel)
22 {
23 case 4:
24 uid = IDS_4BPP;
25 break;
26 case 8:
27 uid = IDS_8BPP;
28 break;
29 case 15:
30 uid = IDS_15BPP;
31 break;
32 case 16:
33 uid = IDS_16BPP;
34 break;
35 case 24:
36 uid = IDS_24BPP;
37 break;
38 case 32:
39 uid = IDS_32BPP;
40 break;
41 }
42
43 if (uid == 0 ||
44 !LoadString(hInstance,
45 uid,
46 lpBuffer,
47 dwBufferLen))
48 {
49 lpBuffer[0] = TEXT('\0');
50 }
51 }
52
53 static VOID
54 GetRefreshRateDescription(PDEVMODEW lpDevMode,
55 LPTSTR lpBuffer,
56 DWORD dwBufferLen)
57 {
58 TCHAR szFormat[64];
59
60 if (lpDevMode->dmDisplayFrequency <= 1)
61 {
62 if (!LoadString(hInstance,
63 IDS_DEFREFRESHRATE,
64 lpBuffer,
65 dwBufferLen))
66 {
67 lpBuffer[0] = TEXT('\0');
68 }
69 }
70 else
71 {
72 if (!LoadString(hInstance,
73 IDES_REFRESHRATEFMT,
74 szFormat,
75 sizeof(szFormat) / sizeof(szFormat[0])))
76 {
77 szFormat[0] = TEXT('\0');
78 }
79
80 _sntprintf(lpBuffer,
81 dwBufferLen,
82 szFormat,
83 lpDevMode->dmDisplayFrequency);
84 }
85 }
86
87 static VOID
88 InitListAllModesDialog(PDESKDISPLAYADAPTER This,
89 HWND hwndListAllModesDlg)
90 {
91 TCHAR szFormat[64], szBuffer[64], szColors[64], szRefreshRate[64];
92 PDEVMODEW lpDevMode, lpCurrentDevMode;
93 DWORD dwIndex = 0;
94 INT i;
95
96 if (This->DeskExtInterface != NULL)
97 {
98 if (!LoadString(hInstance,
99 IDS_MODEFMT,
100 szFormat,
101 sizeof(szFormat) / sizeof(szFormat[0])))
102 {
103 szFormat[0] = TEXT('\0');
104 }
105
106 lpCurrentDevMode = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
107
108 do
109 {
110 lpDevMode = This->DeskExtInterface->EnumAllModes(This->DeskExtInterface->Context,
111 dwIndex++);
112 if (lpDevMode != NULL)
113 {
114 GetColorDescription(lpDevMode,
115 szColors,
116 sizeof(szColors) / sizeof(szColors[0]));
117
118 GetRefreshRateDescription(lpDevMode,
119 szRefreshRate,
120 sizeof(szRefreshRate) / sizeof(szRefreshRate[0]));
121
122 _sntprintf(szBuffer,
123 sizeof(szBuffer) / sizeof(szBuffer[0]),
124 szFormat,
125 lpDevMode->dmPelsWidth,
126 lpDevMode->dmPelsHeight,
127 szColors,
128 szRefreshRate);
129
130 i = (INT)SendDlgItemMessage(hwndListAllModesDlg,
131 IDC_ALLVALIDMODES,
132 LB_ADDSTRING,
133 0,
134 (LPARAM)szBuffer);
135 if (i >= 0)
136 {
137 SendDlgItemMessage(hwndListAllModesDlg,
138 IDC_ALLVALIDMODES,
139 LB_SETITEMDATA,
140 (WPARAM)i,
141 (LPARAM)lpDevMode);
142
143 if (lpDevMode == lpCurrentDevMode)
144 {
145 SendDlgItemMessage(hwndListAllModesDlg,
146 IDC_ALLVALIDMODES,
147 LB_SETCURSEL,
148 (WPARAM)i,
149 0);
150 }
151 }
152 }
153
154 } while (lpDevMode != NULL);
155 }
156 }
157
158 static BOOL
159 ChangeSelectedMode(PDESKDISPLAYADAPTER This,
160 HWND hwndListAllModesDlg)
161 {
162 INT i;
163 PDEVMODEW lpSelDevMode = NULL;
164 BOOL bRet = FALSE;
165
166 i = (INT)SendDlgItemMessage(hwndListAllModesDlg,
167 IDC_ALLVALIDMODES,
168 LB_GETCURSEL,
169 0,
170 0);
171
172 if (i >= 0)
173 {
174 lpSelDevMode = (PDEVMODEW)SendDlgItemMessage(hwndListAllModesDlg,
175 IDC_ALLVALIDMODES,
176 LB_GETITEMDATA,
177 (WPARAM)i,
178 0);
179 }
180
181 if (lpSelDevMode != NULL)
182 {
183 This->lpSelDevMode = lpSelDevMode;
184 bRet = TRUE;
185 }
186
187 return bRet;
188 }
189
190 static INT_PTR CALLBACK
191 ListAllModesDlgProc(HWND hwndDlg,
192 UINT uMsg,
193 WPARAM wParam,
194 LPARAM lParam)
195 {
196 PDESKDISPLAYADAPTER This;
197 INT_PTR Ret = 0;
198
199 if (uMsg != WM_INITDIALOG)
200 {
201 This = (PDESKDISPLAYADAPTER)GetWindowLongPtr(hwndDlg, DWLP_USER);
202 }
203
204 switch (uMsg)
205 {
206 case WM_INITDIALOG:
207 This = (PDESKDISPLAYADAPTER)lParam;
208 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
209
210 InitListAllModesDialog(This,
211 hwndDlg);
212 Ret = TRUE;
213 break;
214
215 case WM_COMMAND:
216 switch (LOWORD(wParam))
217 {
218 case IDOK:
219 if (ChangeSelectedMode(This,
220 hwndDlg))
221 {
222 EndDialog(hwndDlg,
223 IDOK);
224 }
225 break;
226
227 case IDCANCEL:
228 EndDialog(hwndDlg,
229 IDCANCEL);
230 break;
231 }
232 break;
233
234 case WM_CLOSE:
235 EndDialog(hwndDlg,
236 IDCANCEL);
237 break;
238 }
239
240 return Ret;
241 }
242
243 static VOID
244 ShowListAllModes(PDESKDISPLAYADAPTER This)
245 {
246 PDEVMODEW lpPrevSel;
247
248 lpPrevSel = This->lpSelDevMode;
249
250 if (This->DeskExtInterface != NULL &&
251 DialogBoxParam(hInstance,
252 MAKEINTRESOURCE(IDD_LISTALLMODES),
253 This->hwndDlg,
254 ListAllModesDlgProc,
255 (LPARAM)This) == IDOK)
256 {
257 if (lpPrevSel != This->lpSelDevMode)
258 {
259 (void)PropSheet_Changed(GetParent(This->hwndDlg),
260 This->hwndDlg);
261 This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
262 This->lpSelDevMode);
263 }
264 }
265 }
266
267 static VOID
268 ShowAdapterProperties(PDESKDISPLAYADAPTER This)
269 {
270 HMODULE hDevMgr;
271 PDEVICEPROPERTIESW pDevicePropertiesW;
272
273 hDevMgr = LoadLibrary(TEXT("devmgr.dll"));
274 if (hDevMgr != NULL)
275 {
276 pDevicePropertiesW = (PDEVICEPROPERTIESW)GetProcAddress(hDevMgr,
277 "DevicePropertiesW");
278 if (pDevicePropertiesW != NULL)
279 {
280 pDevicePropertiesW(This->hwndDlg,
281 NULL,
282 This->lpDeviceId,
283 FALSE);
284 }
285
286 FreeLibrary(hDevMgr);
287 }
288 }
289
290 static VOID
291 InitDisplayAdapterDialog(PDESKDISPLAYADAPTER This)
292 {
293 LPTSTR lpAdapterName;
294
295 This->lpDeviceId = QueryDeskCplString(This->pdtobj,
296 RegisterClipboardFormat(DESK_EXT_DISPLAYID));
297 EnableWindow(GetDlgItem(This->hwndDlg,
298 IDC_ADAPTERPROPERTIES),
299 This->lpDeviceId != NULL && This->lpDeviceId[0] != TEXT('\0'));
300 lpAdapterName = QueryDeskCplString(This->pdtobj,
301 RegisterClipboardFormat(DESK_EXT_DISPLAYNAME));
302 if (lpAdapterName != NULL)
303 {
304 SetDlgItemText(This->hwndDlg,
305 IDC_ADAPTERNAME,
306 lpAdapterName);
307
308 LocalFree((HLOCAL)lpAdapterName);
309 }
310
311 if (This->DeskExtInterface != NULL)
312 {
313 SetDlgItemTextW(This->hwndDlg,
314 IDC_CHIPTYPE,
315 This->DeskExtInterface->ChipType);
316 SetDlgItemTextW(This->hwndDlg,
317 IDC_DACTYPE,
318 This->DeskExtInterface->DacType);
319 SetDlgItemTextW(This->hwndDlg,
320 IDC_MEMORYSIZE,
321 This->DeskExtInterface->MemorySize);
322 SetDlgItemTextW(This->hwndDlg,
323 IDC_ADAPTERSTRING,
324 This->DeskExtInterface->AdapterString);
325 SetDlgItemTextW(This->hwndDlg,
326 IDC_BIOSINFORMATION,
327 This->DeskExtInterface->BiosString);
328
329 This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
330 }
331 else
332 This->lpDevModeOnInit = NULL;
333
334 This->lpSelDevMode = This->lpDevModeOnInit;
335 }
336
337 static LONG
338 ApplyDisplayAdapterChanges(PDESKDISPLAYADAPTER This)
339 {
340 LONG lChangeRet;
341
342 if (This->DeskExtInterface != NULL)
343 {
344 /* Change the display settings through desk.cpl */
345 lChangeRet = DeskCplExtDisplaySaveSettings(This->DeskExtInterface,
346 This->hwndDlg);
347 if (lChangeRet == DISP_CHANGE_SUCCESSFUL)
348 {
349 /* Save the new mode */
350 This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
351 This->lpSelDevMode = This->lpDevModeOnInit;
352 return PSNRET_NOERROR;
353 }
354 else if (lChangeRet == DISP_CHANGE_RESTART)
355 {
356 /* Notify desk.cpl that the user needs to reboot */
357 PropSheet_RestartWindows(GetParent(This->hwndDlg));
358 return PSNRET_NOERROR;
359 }
360 }
361
362 return PSNRET_INVALID_NOCHANGEPAGE;
363 }
364
365 static VOID
366 ResetDisplayAdapterChanges(PDESKDISPLAYADAPTER This)
367 {
368 if (This->DeskExtInterface != NULL && This->lpDevModeOnInit != NULL)
369 {
370 This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
371 This->lpDevModeOnInit);
372 }
373 }
374
375 static INT_PTR CALLBACK
376 DisplayAdapterDlgProc(HWND hwndDlg,
377 UINT uMsg,
378 WPARAM wParam,
379 LPARAM lParam)
380 {
381 PDESKDISPLAYADAPTER This;
382 INT_PTR Ret = 0;
383
384 if (uMsg != WM_INITDIALOG)
385 {
386 This = (PDESKDISPLAYADAPTER)GetWindowLongPtr(hwndDlg, DWLP_USER);
387 }
388
389 switch (uMsg)
390 {
391 case WM_INITDIALOG:
392 This = (PDESKDISPLAYADAPTER)((LPCPROPSHEETPAGE)lParam)->lParam;
393 This->hwndDlg = hwndDlg;
394 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
395
396 InitDisplayAdapterDialog(This);
397 Ret = TRUE;
398 break;
399
400 case WM_COMMAND:
401 switch (LOWORD(wParam))
402 {
403 case IDC_ADAPTERPROPERTIES:
404 ShowAdapterProperties(This);
405 break;
406
407 case IDC_LISTALLMODES:
408 ShowListAllModes(This);
409 break;
410 }
411
412 break;
413
414 case WM_NOTIFY:
415 {
416 NMHDR *nmh = (NMHDR *)lParam;
417
418 switch (nmh->code)
419 {
420 case PSN_APPLY:
421 {
422 SetWindowLongPtr(hwndDlg,
423 DWLP_MSGRESULT,
424 ApplyDisplayAdapterChanges(This));
425 break;
426 }
427
428 case PSN_RESET:
429 ResetDisplayAdapterChanges(This);
430 break;
431 }
432 break;
433 }
434 }
435
436 return Ret;
437 }
438
439 static VOID
440 IDeskDisplayAdapter_Destroy(PDESKDISPLAYADAPTER This)
441 {
442 if (This->pdtobj != NULL)
443 {
444 IDataObject_Release(This->pdtobj);
445 This->pdtobj = NULL;
446 }
447
448 if (This->DeskExtInterface != NULL)
449 {
450 LocalFree((HLOCAL)This->DeskExtInterface);
451 This->DeskExtInterface = NULL;
452 }
453
454 if (This->lpDeviceId != NULL)
455 {
456 LocalFree((HLOCAL)This->lpDeviceId);
457 This->lpDeviceId = NULL;
458 }
459 }
460
461 ULONG
462 IDeskDisplayAdapter_AddRef(PDESKDISPLAYADAPTER This)
463 {
464 ULONG ret;
465
466 ret = InterlockedIncrement((PLONG)&This->ref);
467 if (ret == 1)
468 InterlockedIncrement(&dll_refs);
469
470 return ret;
471 }
472
473 ULONG
474 IDeskDisplayAdapter_Release(PDESKDISPLAYADAPTER This)
475 {
476 ULONG ret;
477
478 ret = InterlockedDecrement((PLONG)&This->ref);
479 if (ret == 0)
480 {
481 IDeskDisplayAdapter_Destroy(This);
482 InterlockedDecrement(&dll_refs);
483
484 HeapFree(GetProcessHeap(),
485 0,
486 This);
487 }
488
489 return ret;
490 }
491
492 HRESULT STDMETHODCALLTYPE
493 IDeskDisplayAdapter_QueryInterface(PDESKDISPLAYADAPTER This,
494 REFIID iid,
495 PVOID *pvObject)
496 {
497 *pvObject = NULL;
498
499 if (IsEqualIID(iid,
500 &IID_IShellPropSheetExt) ||
501 IsEqualIID(iid,
502 &IID_IUnknown))
503 {
504 *pvObject = impl_to_interface(This, IShellPropSheetExt);
505 }
506 else if (IsEqualIID(iid,
507 &IID_IShellExtInit))
508 {
509 *pvObject = impl_to_interface(This, IShellExtInit);
510 }
511 else if (IsEqualIID(iid,
512 &IID_IClassFactory))
513 {
514 *pvObject = impl_to_interface(This, IClassFactory);
515 }
516 else
517 {
518 DPRINT1("IDeskDisplayAdapter::QueryInterface(%p,%p): E_NOINTERFACE\n", iid, pvObject);
519 return E_NOINTERFACE;
520 }
521
522 IDeskDisplayAdapter_AddRef(This);
523 return S_OK;
524 }
525
526 HRESULT
527 IDeskDisplayAdapter_Initialize(PDESKDISPLAYADAPTER This,
528 LPCITEMIDLIST pidlFolder,
529 IDataObject *pdtobj,
530 HKEY hkeyProgID)
531 {
532 DPRINT1("IDeskDisplayAdapter::Initialize(%p,%p,%p)\n", pidlFolder, pdtobj, hkeyProgID);
533
534 if (pdtobj != NULL)
535 {
536 IDataObject_AddRef(pdtobj);
537 This->pdtobj = pdtobj;
538
539 /* Get a copy of the desk.cpl extension interface */
540 This->DeskExtInterface = QueryDeskCplExtInterface(This->pdtobj);
541 if (This->DeskExtInterface != NULL)
542 return S_OK;
543 }
544
545 return S_FALSE;
546 }
547
548 HRESULT
549 IDeskDisplayAdapter_AddPages(PDESKDISPLAYADAPTER This,
550 LPFNADDPROPSHEETPAGE pfnAddPage,
551 LPARAM lParam)
552 {
553 HPROPSHEETPAGE hpsp;
554 PROPSHEETPAGE psp;
555
556 DPRINT1("IDeskDisplayAdapter::AddPages(%p,%p)\n", pfnAddPage, lParam);
557
558 psp.dwSize = sizeof(psp);
559 psp.dwFlags = PSP_DEFAULT;
560 psp.hInstance = hInstance;
561 psp.pszTemplate = MAKEINTRESOURCE(IDD_DISPLAYADAPTER);
562 psp.pfnDlgProc = DisplayAdapterDlgProc;
563 psp.lParam = (LPARAM)This;
564
565 hpsp = CreatePropertySheetPage(&psp);
566 if (hpsp != NULL && pfnAddPage(hpsp, lParam))
567 return S_OK;
568
569 return S_FALSE;
570 }
571
572 HRESULT
573 IDeskDisplayAdapter_ReplacePage(PDESKDISPLAYADAPTER This,
574 EXPPS uPageID,
575 LPFNADDPROPSHEETPAGE pfnReplacePage,
576 LPARAM lParam)
577 {
578 DPRINT1("IDeskDisplayAdapter::ReplacePage(%u,%p,%p)\n", uPageID, pfnReplacePage, lParam);
579 return E_NOTIMPL;
580 }
581
582 HRESULT
583 IDeskDisplayAdapter_Constructor(REFIID riid,
584 LPVOID *ppv)
585 {
586 PDESKDISPLAYADAPTER This;
587 HRESULT hRet = E_OUTOFMEMORY;
588
589 DPRINT1("IDeskDisplayAdapter::Constructor(%p,%p)\n", riid, ppv);
590
591 This = HeapAlloc(GetProcessHeap(),
592 0,
593 sizeof(*This));
594 if (This != NULL)
595 {
596 ZeroMemory(This,
597 sizeof(*This));
598
599 IDeskDisplayAdapter_InitIface(This);
600
601 hRet = IDeskDisplayAdapter_QueryInterface(This,
602 riid,
603 ppv);
604 if (!SUCCEEDED(hRet))
605 IDeskDisplayAdapter_Release(This);
606 }
607
608 return hRet;
609 }
610
611 BOOL WINAPI
612 DllMain(HINSTANCE hinstDLL,
613 DWORD dwReason,
614 LPVOID lpvReserved)
615 {
616 switch (dwReason)
617 {
618 case DLL_PROCESS_ATTACH:
619 hInstance = hinstDLL;
620 DisableThreadLibraryCalls(hInstance);
621 break;
622 }
623
624 return TRUE;
625 }