Hack: Hackfix the HitTest problem in mstsc as it was done for previous releases
[reactos.git] / reactos / base / applications / mstsc / connectdialog.c
1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Connection settings dialog
4 Copyright (C) Ged Murphy 2007
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <precomp.h>
22
23 #define MAX_KEY_NAME 255
24
25 HINSTANCE hInst;
26
27 static VOID ReLoadGeneralPage(PINFO pInfo);
28 static VOID ReLoadDisplayPage(PINFO pInfo);
29
30
31 static VOID
32 DoOpenFile(PINFO pInfo)
33 {
34 OPENFILENAMEW ofn;
35 WCHAR szFileName[MAX_PATH] = L"";
36 static WCHAR szFilter[] = L"Remote Desktop Files (*rdp)\0*.rdp\0";
37
38 ZeroMemory(&ofn, sizeof(ofn));
39 ofn.lStructSize = sizeof(OPENFILENAMEW);
40 ofn.hwndOwner = pInfo->hGeneralPage;
41 ofn.nMaxFile = MAX_PATH;
42 ofn.nMaxFileTitle = MAX_PATH;
43 ofn.lpstrDefExt = L"rdp";
44 ofn.lpstrFilter = szFilter;
45 ofn.lpstrFile = szFileName;
46 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
47
48 if (GetOpenFileNameW(&ofn))
49 {
50 LoadRdpSettingsFromFile(pInfo->pRdpSettings, szFileName);
51 ReLoadGeneralPage(pInfo);
52 ReLoadDisplayPage(pInfo);
53 }
54 }
55
56
57 static VOID
58 DoSaveAs(PINFO pInfo)
59 {
60 OPENFILENAMEW ofn;
61 WCHAR szFileName[MAX_PATH] = L"";
62 static WCHAR szFilter[] = L"Remote Desktop Files (*rdp)\0*.rdp\0";
63
64 ZeroMemory(&ofn, sizeof(ofn));
65 ofn.lStructSize = sizeof(OPENFILENAMEW);
66 ofn.hwndOwner = pInfo->hGeneralPage;
67 ofn.nMaxFile = MAX_PATH;
68 ofn.nMaxFileTitle = MAX_PATH;
69 ofn.lpstrDefExt = L"rdp";
70 ofn.lpstrFilter = szFilter;
71 ofn.lpstrFile = szFileName;
72 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
73
74 if (GetSaveFileNameW(&ofn))
75 {
76 SaveAllSettings(pInfo);
77 SaveRdpSettingsToFile(szFileName, pInfo->pRdpSettings);
78 }
79 }
80
81
82 static VOID
83 OnTabWndSelChange(PINFO pInfo)
84 {
85 switch (TabCtrl_GetCurSel(pInfo->hTab))
86 {
87 case 0: //General
88 ShowWindow(pInfo->hGeneralPage, SW_SHOW);
89 ShowWindow(pInfo->hDisplayPage, SW_HIDE);
90 BringWindowToTop(pInfo->hGeneralPage);
91 break;
92 case 1: //Display
93 ShowWindow(pInfo->hGeneralPage, SW_HIDE);
94 ShowWindow(pInfo->hDisplayPage, SW_SHOW);
95 BringWindowToTop(pInfo->hDisplayPage);
96 break;
97 }
98 }
99
100
101 static VOID
102 FillServerAddesssCombo(PINFO pInfo)
103 {
104 HKEY hKey;
105 WCHAR KeyName[] = L"Software\\Microsoft\\Terminal Server Client\\Default";
106 WCHAR Name[MAX_KEY_NAME];
107 LONG ret = ERROR_SUCCESS;
108 DWORD size;
109 INT i = 0;
110
111 if (RegOpenKeyExW(HKEY_CURRENT_USER,
112 KeyName,
113 0,
114 KEY_READ,
115 &hKey) == ERROR_SUCCESS)
116 {
117 while (ret == ERROR_SUCCESS)
118 {
119 size = MAX_KEY_NAME;
120 ret = RegEnumValueW(hKey,
121 i,
122 Name,
123 &size,
124 NULL,
125 NULL,
126 NULL,
127 NULL);
128 if (ret == ERROR_SUCCESS)
129 {
130 size = MAX_KEY_NAME;
131 if (RegQueryValueExW(hKey,
132 Name,
133 0,
134 NULL,
135 NULL,
136 &size) == ERROR_SUCCESS)
137 {
138 LPWSTR lpAddress = HeapAlloc(GetProcessHeap(),
139 0,
140 size);
141 if (lpAddress)
142 {
143 if (RegQueryValueExW(hKey,
144 Name,
145 0,
146 NULL,
147 (LPBYTE)lpAddress,
148 &size) == ERROR_SUCCESS)
149 {
150 SendDlgItemMessageW(pInfo->hGeneralPage,
151 IDC_SERVERCOMBO,
152 CB_ADDSTRING,
153 0,
154 (LPARAM)lpAddress);
155 }
156
157 HeapFree(GetProcessHeap(),
158 0,
159 lpAddress);
160 }
161 }
162 }
163
164 i++;
165 }
166 RegCloseKey(hKey);
167 }
168
169 if (LoadStringW(hInst,
170 IDS_BROWSESERVER,
171 Name,
172 sizeof(Name) / sizeof(WCHAR)))
173 {
174 SendDlgItemMessageW(pInfo->hGeneralPage,
175 IDC_SERVERCOMBO,
176 CB_ADDSTRING,
177 0,
178 (LPARAM)Name);
179 }
180 }
181
182
183 static VOID
184 ReLoadGeneralPage(PINFO pInfo)
185 {
186 LPWSTR lpText;
187
188 /* add file address */
189 lpText = GetStringFromSettings(pInfo->pRdpSettings,
190 L"full address");
191 if (lpText)
192 {
193 SetDlgItemTextW(pInfo->hGeneralPage,
194 IDC_SERVERCOMBO,
195 lpText);
196 }
197 }
198
199
200 static VOID
201 GeneralOnInit(PINFO pInfo)
202 {
203 SetWindowPos(pInfo->hGeneralPage,
204 NULL,
205 13,
206 110,
207 0,
208 0,
209 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
210
211 pInfo->hLogon = LoadImageW(hInst,
212 MAKEINTRESOURCEW(IDI_LOGON),
213 IMAGE_ICON,
214 32,
215 32,
216 LR_DEFAULTCOLOR);
217 if (pInfo->hLogon)
218 {
219 SendDlgItemMessageW(pInfo->hGeneralPage,
220 IDC_LOGONICON,
221 STM_SETICON,
222 (WPARAM)pInfo->hLogon,
223 0);
224 }
225
226 pInfo->hConn = LoadImageW(hInst,
227 MAKEINTRESOURCEW(IDI_CONN),
228 IMAGE_ICON,
229 32,
230 32,
231 LR_DEFAULTCOLOR);
232 if (pInfo->hConn)
233 {
234 SendDlgItemMessageW(pInfo->hGeneralPage,
235 IDC_CONNICON,
236 STM_SETICON,
237 (WPARAM)pInfo->hConn,
238 0);
239 }
240
241 FillServerAddesssCombo(pInfo);
242 ReLoadGeneralPage(pInfo);
243 }
244
245
246 INT_PTR CALLBACK
247 GeneralDlgProc(HWND hDlg,
248 UINT message,
249 WPARAM wParam,
250 LPARAM lParam)
251 {
252 PINFO pInfo = (PINFO)GetWindowLongPtrW(GetParent(hDlg),
253 GWLP_USERDATA);
254
255 switch (message)
256 {
257 case WM_INITDIALOG:
258 pInfo->hGeneralPage = hDlg;
259 GeneralOnInit(pInfo);
260 return TRUE;
261
262 case WM_COMMAND:
263 {
264 switch(LOWORD(wParam))
265 {
266 case IDC_SERVERCOMBO:
267 if (HIWORD(wParam) == CBN_SELCHANGE)
268 {
269 INT last, cur;
270
271 cur = SendDlgItemMessageW(hDlg,
272 IDC_SERVERCOMBO,
273 CB_GETCURSEL,
274 0,
275 0);
276 cur++;
277
278 last = SendDlgItemMessageW(hDlg,
279 IDC_SERVERCOMBO,
280 CB_GETCOUNT,
281 0,
282 0);
283 if (cur == last)
284 MessageBoxW(hDlg, L"SMB is not yet supported", L"RDP error", MB_ICONERROR);
285 }
286 break;
287
288 case IDC_SAVE:
289 SaveAllSettings(pInfo);
290 SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
291 break;
292
293 case IDC_SAVEAS:
294 DoSaveAs(pInfo);
295 break;
296
297 case IDC_OPEN:
298 DoOpenFile(pInfo);
299 break;
300 }
301
302 break;
303 }
304
305 case WM_CLOSE:
306 {
307 if (pInfo->hLogon)
308 DestroyIcon(pInfo->hLogon);
309
310 if (pInfo->hConn)
311 DestroyIcon(pInfo->hConn);
312
313 break;
314 }
315 }
316
317 return 0;
318 }
319
320
321 static PSETTINGS_ENTRY
322 GetPossibleSettings(IN LPCWSTR lpDeviceName,
323 OUT DWORD* pSettingsCount,
324 OUT PSETTINGS_ENTRY* CurrentSettings)
325 {
326 DEVMODEW devmode;
327 DWORD NbSettings = 0;
328 DWORD iMode = 0;
329 DWORD dwFlags = 0;
330 PSETTINGS_ENTRY Settings = NULL;
331 HDC hDC;
332 PSETTINGS_ENTRY Current;
333 DWORD bpp, xres, yres, checkbpp;
334
335 /* Get current settings */
336 *CurrentSettings = NULL;
337 hDC = CreateICW(NULL, lpDeviceName, NULL, NULL);
338 bpp = GetDeviceCaps(hDC, PLANES);
339 bpp *= GetDeviceCaps(hDC, BITSPIXEL);
340 xres = GetDeviceCaps(hDC, HORZRES);
341 yres = GetDeviceCaps(hDC, VERTRES);
342 DeleteDC(hDC);
343
344 /* List all settings */
345 devmode.dmSize = (WORD)sizeof(DEVMODE);
346 devmode.dmDriverExtra = 0;
347
348 if (!EnumDisplaySettingsExW(lpDeviceName, ENUM_CURRENT_SETTINGS, &devmode, dwFlags))
349 return NULL;
350
351 while (EnumDisplaySettingsExW(lpDeviceName, iMode, &devmode, dwFlags))
352 {
353 if (devmode.dmBitsPerPel==8 ||
354 devmode.dmBitsPerPel==16 ||
355 devmode.dmBitsPerPel==24 ||
356 devmode.dmBitsPerPel==32)
357 {
358 checkbpp=1;
359 }
360 else
361 checkbpp=0;
362
363 if (devmode.dmPelsWidth < 640 ||
364 devmode.dmPelsHeight < 480 || checkbpp == 0)
365 {
366 iMode++;
367 continue;
368 }
369
370 Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
371 if (Current != NULL)
372 {
373 /* Sort resolutions by increasing height, and BPP */
374 PSETTINGS_ENTRY Previous = NULL;
375 PSETTINGS_ENTRY Next = Settings;
376 Current->dmPelsWidth = devmode.dmPelsWidth;
377 Current->dmPelsHeight = devmode.dmPelsHeight;
378 Current->dmBitsPerPel = devmode.dmBitsPerPel;
379 while (Next != NULL &&
380 (Next->dmPelsWidth < Current->dmPelsWidth ||
381 (Next->dmPelsWidth == Current->dmPelsWidth && Next->dmPelsHeight < Current->dmPelsHeight) ||
382 (Next->dmPelsHeight == Current->dmPelsHeight &&
383 Next->dmPelsWidth == Current->dmPelsWidth &&
384 Next->dmBitsPerPel < Current->dmBitsPerPel )))
385 {
386 Previous = Next;
387 Next = Next->Flink;
388 }
389 Current->Blink = Previous;
390 Current->Flink = Next;
391 if (Previous == NULL)
392 Settings = Current;
393 else
394 Previous->Flink = Current;
395 if (Next != NULL)
396 Next->Blink = Current;
397 if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
398 {
399 *CurrentSettings = Current;
400 }
401 NbSettings++;
402 }
403 iMode++;
404 }
405
406 *pSettingsCount = NbSettings;
407 return Settings;
408 }
409
410
411 static BOOL
412 AddDisplayDevice(PINFO pInfo, PDISPLAY_DEVICEW DisplayDevice)
413 {
414 PDISPLAY_DEVICE_ENTRY newEntry = NULL;
415 LPWSTR description = NULL;
416 LPWSTR name = NULL;
417 LPWSTR key = NULL;
418 LPWSTR devid = NULL;
419 DWORD descriptionSize, nameSize, keySize, devidSize;
420 PSETTINGS_ENTRY Current;
421 DWORD ResolutionsCount = 1;
422 DWORD i;
423
424 newEntry = HeapAlloc(GetProcessHeap(),
425 0,
426 sizeof(DISPLAY_DEVICE_ENTRY));
427 if (!newEntry) goto ByeBye;
428 ZeroMemory(newEntry, sizeof(DISPLAY_DEVICE_ENTRY));
429
430 newEntry->Settings = GetPossibleSettings(DisplayDevice->DeviceName,
431 &newEntry->SettingsCount,
432 &newEntry->CurrentSettings);
433 if (!newEntry->Settings) goto ByeBye;
434
435 newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
436 newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
437 newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
438
439 /* Count different resolutions */
440 for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
441 {
442 if (Current->Flink != NULL &&
443 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
444 (Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
445 {
446 ResolutionsCount++;
447 }
448 }
449
450 newEntry->Resolutions = HeapAlloc(GetProcessHeap(),
451 0,
452 ResolutionsCount * sizeof(RESOLUTION_INFO));
453 if (!newEntry->Resolutions) goto ByeBye;
454
455 newEntry->ResolutionsCount = ResolutionsCount;
456
457 /* Fill resolutions infos */
458 for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
459 {
460 if (Current->Flink == NULL ||
461 (Current->Flink != NULL &&
462 ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
463 (Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
464 {
465 newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
466 newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
467 i++;
468 }
469 }
470 descriptionSize = (wcslen(DisplayDevice->DeviceString) + 1) * sizeof(WCHAR);
471 description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
472 if (!description) goto ByeBye;
473
474 nameSize = (wcslen(DisplayDevice->DeviceName) + 1) * sizeof(WCHAR);
475 name = HeapAlloc(GetProcessHeap(), 0, nameSize);
476 if (!name) goto ByeBye;
477
478 keySize = (wcslen(DisplayDevice->DeviceKey) + 1) * sizeof(WCHAR);
479 key = HeapAlloc(GetProcessHeap(), 0, keySize);
480 if (!key) goto ByeBye;
481
482 devidSize = (wcslen(DisplayDevice->DeviceID) + 1) * sizeof(WCHAR);
483 devid = HeapAlloc(GetProcessHeap(), 0, devidSize);
484 if (!devid) goto ByeBye;
485
486 memcpy(description, DisplayDevice->DeviceString, descriptionSize);
487 memcpy(name, DisplayDevice->DeviceName, nameSize);
488 memcpy(key, DisplayDevice->DeviceKey, keySize);
489 memcpy(devid, DisplayDevice->DeviceID, devidSize);
490 newEntry->DeviceDescription = description;
491 newEntry->DeviceName = name;
492 newEntry->DeviceKey = key;
493 newEntry->DeviceID = devid;
494 newEntry->DeviceStateFlags = DisplayDevice->StateFlags;
495 newEntry->Flink = pInfo->DisplayDeviceList;
496 pInfo->DisplayDeviceList = newEntry;
497 return TRUE;
498
499 ByeBye:
500 if (newEntry != NULL)
501 {
502 if (newEntry->Settings != NULL)
503 {
504 Current = newEntry->Settings;
505 while (Current != NULL)
506 {
507 PSETTINGS_ENTRY Next = Current->Flink;
508 HeapFree(GetProcessHeap(), 0, Current);
509 Current = Next;
510 }
511 }
512 if (newEntry->Resolutions != NULL)
513 HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
514 HeapFree(GetProcessHeap(), 0, newEntry);
515 }
516 if (description != NULL)
517 HeapFree(GetProcessHeap(), 0, description);
518 if (name != NULL)
519 HeapFree(GetProcessHeap(), 0, name);
520 if (key != NULL)
521 HeapFree(GetProcessHeap(), 0, key);
522 if (devid != NULL)
523 HeapFree(GetProcessHeap(), 0, devid);
524 return FALSE;
525 }
526
527
528 static VOID
529 OnResolutionChanged(PINFO pInfo, INT position)
530 {
531 WCHAR Buffer[64];
532 INT MaxSlider;
533
534 MaxSlider = SendDlgItemMessageW(pInfo->hDisplayPage,
535 IDC_GEOSLIDER,
536 TBM_GETRANGEMAX,
537 0,
538 0);
539
540 if (position == MaxSlider)
541 {
542 LoadStringW(hInst,
543 IDS_FULLSCREEN,
544 Buffer,
545 sizeof(Buffer) / sizeof(WCHAR));
546 }
547 else
548 {
549 WCHAR Pixel[64];
550
551 if (LoadStringW(hInst,
552 IDS_PIXEL,
553 Pixel,
554 sizeof(Pixel) / sizeof(WCHAR)))
555 {
556 #ifdef _MSC_VER
557 _swprintf(Buffer,
558 Pixel,
559 pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
560 pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
561 Pixel);
562 #else
563 swprintf(Buffer,
564 Pixel,
565 pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
566 pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
567 Pixel);
568 #endif
569 }
570 }
571
572 SendDlgItemMessageW(pInfo->hDisplayPage,
573 IDC_SETTINGS_RESOLUTION_TEXT,
574 WM_SETTEXT,
575 0,
576 (LPARAM)Buffer);
577 }
578
579
580 static VOID
581 FillResolutionsAndColors(PINFO pInfo)
582 {
583 PSETTINGS_ENTRY Current;
584 DWORD index, i, num;
585 DWORD MaxBpp = 0;
586 UINT types[4];
587
588 pInfo->CurrentDisplayDevice = pInfo->DisplayDeviceList; /* Update global variable */
589
590 /* find max bpp */
591 SendDlgItemMessageW(pInfo->hDisplayPage,
592 IDC_BPPCOMBO,
593 CB_RESETCONTENT,
594 0,
595 0);
596 for (Current = pInfo->DisplayDeviceList->Settings; Current != NULL; Current = Current->Flink)
597 {
598 if (Current->dmBitsPerPel > MaxBpp)
599 MaxBpp = Current->dmBitsPerPel;
600 }
601 switch (MaxBpp)
602 {
603 case 32:
604 case 24: num = 4; break;
605 case 16: num = 3; break;
606 case 8: num = 1; break;
607 default: num = 0; break;
608 }
609
610 types[0] = IDS_256COLORS;
611 types[1] = IDS_HIGHCOLOR15;
612 types[2] = IDS_HIGHCOLOR16;
613 types[3] = IDS_HIGHCOLOR24;
614
615 /* Fill color depths combo box */
616 SendDlgItemMessageW(pInfo->hDisplayPage,
617 IDC_BPPCOMBO,
618 CB_RESETCONTENT,
619 0,
620 0);
621
622 for (i = 0, Current = pInfo->DisplayDeviceList->Settings;
623 i <= num && Current != NULL;
624 i++, Current = Current->Flink)
625 {
626 WCHAR Buffer[64];
627 if (LoadStringW(hInst,
628 types[i],
629 Buffer,
630 sizeof(Buffer) / sizeof(WCHAR)))
631 {
632 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
633 IDC_BPPCOMBO,
634 CB_FINDSTRINGEXACT,
635 (WPARAM)-1,
636 (LPARAM)Buffer);
637 if (index == (DWORD)CB_ERR)
638 {
639 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
640 IDC_BPPCOMBO,
641 CB_ADDSTRING,
642 0,
643 (LPARAM)Buffer);
644 SendDlgItemMessageW(pInfo->hDisplayPage,
645 IDC_BPPCOMBO,
646 CB_SETITEMDATA,
647 index,
648 types[i]);
649 }
650 }
651 }
652
653 /* Fill resolutions slider */
654 SendDlgItemMessageW(pInfo->hDisplayPage,
655 IDC_GEOSLIDER,
656 TBM_CLEARTICS,
657 TRUE,
658 0);
659 SendDlgItemMessageW(pInfo->hDisplayPage,
660 IDC_GEOSLIDER,
661 TBM_SETRANGE,
662 TRUE,
663 MAKELONG(0, pInfo->DisplayDeviceList->ResolutionsCount)); //extra 1 for full screen
664
665
666 }
667
668
669 static VOID
670 ReLoadDisplayPage(PINFO pInfo)
671 {
672 DWORD index;
673 INT width, height, pos = 0;
674 INT bpp, num, i;
675 BOOL bSet = FALSE;
676
677 /* set trackbar position */
678 width = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopwidth");
679 height = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopheight");
680
681 if (width != -1 && height != -1)
682 {
683 for (index = 0; index < pInfo->CurrentDisplayDevice->ResolutionsCount; index++)
684 {
685 if (pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsWidth == width &&
686 pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsHeight == height)
687 {
688 pos = index;
689 break;
690 }
691 }
692 }
693
694 /* set slider position */
695 SendDlgItemMessageW(pInfo->hDisplayPage,
696 IDC_GEOSLIDER,
697 TBM_SETPOS,
698 TRUE,
699 pos);
700
701 OnResolutionChanged(pInfo, pos);
702
703
704 /* set color combo */
705 bpp = GetIntegerFromSettings(pInfo->pRdpSettings, L"session bpp");
706
707 num = SendDlgItemMessageW(pInfo->hDisplayPage,
708 IDC_BPPCOMBO,
709 CB_GETCOUNT,
710 0,
711 0);
712 for (i = 0; i < num; i++)
713 {
714 INT data = SendDlgItemMessageW(pInfo->hDisplayPage,
715 IDC_BPPCOMBO,
716 CB_GETITEMDATA,
717 i,
718 0);
719 if (data == bpp)
720 {
721 SendDlgItemMessageW(pInfo->hDisplayPage,
722 IDC_BPPCOMBO,
723 CB_SETCURSEL,
724 i,
725 0);
726 bSet = TRUE;
727 break;
728 }
729 }
730
731 if (!bSet)
732 {
733 SendDlgItemMessageW(pInfo->hDisplayPage,
734 IDC_BPPCOMBO,
735 CB_SETCURSEL,
736 num - 1,
737 0);
738 }
739 }
740
741
742 static VOID
743 DisplayOnInit(PINFO pInfo)
744 {
745 DISPLAY_DEVICEW displayDevice;
746 DWORD iDevNum = 0;
747 BOOL GotDev = FALSE;
748
749 SetWindowPos(pInfo->hDisplayPage,
750 NULL,
751 13,
752 110,
753 0,
754 0,
755 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
756
757 pInfo->hRemote = LoadImageW(hInst,
758 MAKEINTRESOURCEW(IDI_REMOTE),
759 IMAGE_ICON,
760 32,
761 32,
762 LR_DEFAULTCOLOR);
763 if (pInfo->hRemote)
764 {
765 SendDlgItemMessageW(pInfo->hDisplayPage,
766 IDC_REMICON,
767 STM_SETICON,
768 (WPARAM)pInfo->hRemote,
769 0);
770 }
771
772 pInfo->hColor = LoadImageW(hInst,
773 MAKEINTRESOURCEW(IDI_COLORS),
774 IMAGE_ICON,
775 32,
776 32,
777 LR_DEFAULTCOLOR);
778 if (pInfo->hColor)
779 {
780 SendDlgItemMessageW(pInfo->hDisplayPage,
781 IDC_COLORSICON,
782 STM_SETICON,
783 (WPARAM)pInfo->hColor,
784 0);
785 }
786
787 pInfo->hSpectrum = LoadImageW(hInst,
788 MAKEINTRESOURCEW(IDB_SPECT),
789 IMAGE_BITMAP,
790 0,
791 0,
792 LR_DEFAULTCOLOR);
793 if (pInfo->hSpectrum)
794 {
795 GetObjectW(pInfo->hSpectrum,
796 sizeof(BITMAP),
797 &pInfo->bitmap);
798 }
799
800 /* Get video cards list */
801 displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
802 while (EnumDisplayDevicesW(NULL, iDevNum, &displayDevice, 0x1))
803 {
804 if ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)
805 {
806 if (AddDisplayDevice(pInfo, &displayDevice))
807 GotDev = TRUE;
808 }
809 iDevNum++;
810 }
811
812 if (GotDev)
813 {
814 FillResolutionsAndColors(pInfo);
815 ReLoadDisplayPage(pInfo);
816 }
817 }
818
819
820 INT_PTR CALLBACK
821 DisplayDlgProc(HWND hDlg,
822 UINT message,
823 WPARAM wParam,
824 LPARAM lParam)
825 {
826 PINFO pInfo = (PINFO)GetWindowLongPtrW(GetParent(hDlg),
827 GWLP_USERDATA);
828
829 switch (message)
830 {
831 case WM_INITDIALOG:
832 pInfo->hDisplayPage = hDlg;
833 DisplayOnInit(pInfo);
834 return TRUE;
835
836 case WM_DRAWITEM:
837 {
838 LPDRAWITEMSTRUCT lpDrawItem;
839 lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
840 if(lpDrawItem->CtlID == IDC_COLORIMAGE)
841 {
842 HDC hdcMem;
843 HBITMAP hSpecOld;
844 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
845 if (hdcMem != NULL)
846 {
847 hSpecOld = SelectObject(hdcMem, pInfo->hSpectrum);
848 StretchBlt(lpDrawItem->hDC,
849 lpDrawItem->rcItem.left,
850 lpDrawItem->rcItem.top,
851 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
852 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
853 hdcMem,
854 0,
855 0,
856 pInfo->bitmap.bmWidth,
857 pInfo->bitmap.bmHeight,
858 SRCCOPY);
859 SelectObject(hdcMem, hSpecOld);
860 DeleteDC(hdcMem);
861 }
862 }
863 break;
864 }
865
866 case WM_HSCROLL:
867 {
868 switch (LOWORD(wParam))
869 {
870 case TB_LINEUP:
871 case TB_LINEDOWN:
872 case TB_PAGEUP:
873 case TB_PAGEDOWN:
874 case TB_TOP:
875 case TB_BOTTOM:
876 case TB_ENDTRACK:
877 {
878 INT newPosition = (DWORD)SendDlgItemMessageW(hDlg, IDC_GEOSLIDER, TBM_GETPOS, 0, 0);
879 OnResolutionChanged(pInfo, newPosition);
880 break;
881 }
882
883 case TB_THUMBTRACK:
884 OnResolutionChanged(pInfo, HIWORD(wParam));
885 break;
886 }
887 break;
888 }
889
890 case WM_CLOSE:
891 {
892 if (pInfo->hRemote)
893 DestroyIcon(pInfo->hRemote);
894
895 if (pInfo->hColor)
896 DestroyIcon(pInfo->hColor);
897
898 if (pInfo->hSpectrum)
899 DeleteObject(pInfo->hSpectrum);
900
901 break;
902 }
903
904 break;
905 }
906 return 0;
907 }
908
909
910 static BOOL
911 OnMainCreate(HWND hwnd,
912 PRDPSETTINGS pRdpSettings)
913 {
914 PINFO pInfo;
915 TCITEMW item;
916 BOOL bRet = FALSE;
917
918 pInfo = HeapAlloc(GetProcessHeap(),
919 HEAP_ZERO_MEMORY,
920 sizeof(INFO));
921 if (pInfo)
922 {
923 SetWindowLongPtrW(hwnd,
924 GWLP_USERDATA,
925 (LONG_PTR)pInfo);
926
927 pInfo->hSelf = hwnd;
928
929 /* add main settings pointer */
930 pInfo->pRdpSettings = pRdpSettings;
931
932 /* set the dialog icons */
933 pInfo->hMstscSm = LoadImageW(hInst,
934 MAKEINTRESOURCEW(IDI_MSTSC),
935 IMAGE_ICON,
936 16,
937 16,
938 LR_DEFAULTCOLOR);
939 if (pInfo->hMstscSm)
940 {
941 SendMessageW(hwnd,
942 WM_SETICON,
943 ICON_SMALL,
944 (WPARAM)pInfo->hMstscSm);
945 }
946 pInfo->hMstscLg = LoadImageW(hInst,
947 MAKEINTRESOURCEW(IDI_MSTSC),
948 IMAGE_ICON,
949 32,
950 32,
951 LR_DEFAULTCOLOR);
952 if (pInfo->hMstscLg)
953 {
954 SendMessageW(hwnd,
955 WM_SETICON,
956 ICON_BIG,
957 (WPARAM)pInfo->hMstscLg);
958 }
959
960 pInfo->hHeader = (HBITMAP)LoadImageW(hInst,
961 MAKEINTRESOURCEW(IDB_HEADER),
962 IMAGE_BITMAP,
963 0,
964 0,
965 LR_DEFAULTCOLOR);
966 if (pInfo->hHeader)
967 {
968 GetObjectW(pInfo->hHeader,
969 sizeof(BITMAP),
970 &pInfo->headerbitmap);
971 }
972
973 /* setup the tabs */
974 pInfo->hTab = GetDlgItem(hwnd, IDC_TAB);
975 if (pInfo->hTab)
976 {
977 if (CreateDialogW(hInst,
978 MAKEINTRESOURCEW(IDD_GENERAL),
979 hwnd,
980 (DLGPROC)GeneralDlgProc))
981 {
982 WCHAR str[256];
983 ZeroMemory(&item, sizeof(TCITEM));
984 item.mask = TCIF_TEXT;
985 if (LoadStringW(hInst, IDS_TAB_GENERAL, str, 256))
986 item.pszText = str;
987 item.cchTextMax = 256;
988 (void)TabCtrl_InsertItem(pInfo->hTab, 0, &item);
989 }
990
991 if (CreateDialogW(hInst,
992 MAKEINTRESOURCEW(IDD_DISPLAY),
993 hwnd,
994 (DLGPROC)DisplayDlgProc))
995 {
996 WCHAR str[256];
997 ZeroMemory(&item, sizeof(TCITEM));
998 item.mask = TCIF_TEXT;
999 if (LoadStringW(hInst, IDS_TAB_DISPLAY, str, 256))
1000 item.pszText = str;
1001 item.cchTextMax = 256;
1002 (void)TabCtrl_InsertItem(pInfo->hTab, 1, &item);
1003 }
1004
1005 OnTabWndSelChange(pInfo);
1006 }
1007 }
1008
1009 return bRet;
1010 }
1011
1012 static void Cleanup(PINFO pInfo)
1013 {
1014 if (pInfo)
1015 {
1016 if (pInfo->hMstscSm)
1017 DestroyIcon(pInfo->hMstscSm);
1018 if (pInfo->hMstscLg)
1019 DestroyIcon(pInfo->hMstscLg);
1020 if (pInfo->hHeader)
1021 DeleteObject(pInfo->hHeader);
1022 if (pInfo->hSpectrum)
1023 DeleteObject(pInfo->hSpectrum);
1024 if (pInfo->hRemote)
1025 DestroyIcon(pInfo->hRemote);
1026 if (pInfo->hLogon)
1027 DestroyIcon(pInfo->hLogon);
1028 if (pInfo->hConn)
1029 DestroyIcon(pInfo->hConn);
1030 if (pInfo->hColor)
1031 DestroyIcon(pInfo->hColor);
1032 HeapFree(GetProcessHeap(),
1033 0,
1034 pInfo);
1035 }
1036 }
1037
1038 static INT_PTR CALLBACK
1039 DlgProc(HWND hDlg,
1040 UINT Message,
1041 WPARAM wParam,
1042 LPARAM lParam)
1043 {
1044 PINFO pInfo;
1045
1046 /* Get the window context */
1047 pInfo = (PINFO)GetWindowLongPtrW(hDlg,
1048 GWLP_USERDATA);
1049 if (pInfo == NULL && Message != WM_INITDIALOG)
1050 {
1051 goto HandleDefaultMessage;
1052 }
1053
1054 switch(Message)
1055 {
1056 case WM_INITDIALOG:
1057 OnMainCreate(hDlg, (PRDPSETTINGS)lParam);
1058 break;
1059
1060 case WM_COMMAND:
1061 {
1062 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
1063 {
1064 if (LOWORD(wParam) == IDOK )
1065 {
1066 SaveAllSettings(pInfo);
1067 SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
1068 }
1069 Cleanup(pInfo);
1070 EndDialog(hDlg, LOWORD(wParam));
1071 }
1072
1073 break;
1074 }
1075
1076 case WM_NOTIFY:
1077 {
1078 INT idctrl;
1079 LPNMHDR pnmh;
1080 idctrl = (int)wParam;
1081 pnmh = (LPNMHDR)lParam;
1082 if (//(pnmh->hwndFrom == pInfo->hSelf) &&
1083 (pnmh->idFrom == IDC_TAB) &&
1084 (pnmh->code == TCN_SELCHANGE))
1085 {
1086 OnTabWndSelChange(pInfo);
1087 }
1088
1089 break;
1090 }
1091
1092 case WM_PAINT:
1093 {
1094 PAINTSTRUCT ps;
1095 HDC hdc;
1096
1097 hdc = BeginPaint(hDlg, &ps);
1098 if (hdc != NULL)
1099 {
1100 HDC hdcMem = CreateCompatibleDC(hdc);
1101 if (hdcMem)
1102 {
1103 WCHAR szBuffer[32];
1104 RECT bmpRc, txtRc;
1105 LOGFONTW lf;
1106 HFONT hFont, hFontOld;
1107 HBITMAP hBmpOld;
1108
1109 GetClientRect(pInfo->hSelf, &bmpRc);
1110
1111 hBmpOld = SelectObject(hdcMem, pInfo->hHeader);
1112 StretchBlt(hdc,
1113 0,
1114 0,
1115 bmpRc.right,
1116 pInfo->headerbitmap.bmHeight,
1117 hdcMem,
1118 0,
1119 0,
1120 pInfo->headerbitmap.bmWidth,
1121 pInfo->headerbitmap.bmHeight,
1122 SRCCOPY);
1123
1124 SelectObject(hdcMem, hBmpOld);
1125 txtRc.left = bmpRc.right * 0.25;
1126 txtRc.top = 10;
1127 txtRc.right = bmpRc.right * 0.75;
1128 txtRc.bottom = pInfo->headerbitmap.bmHeight * 0.5;
1129
1130 ZeroMemory(&lf, sizeof(LOGFONTW));
1131
1132 if (LoadStringW(hInst,
1133 IDS_HEADERTEXT1,
1134 szBuffer,
1135 sizeof(szBuffer) / sizeof(WCHAR)))
1136 {
1137 lf.lfHeight = 24;
1138 lf.lfCharSet = OEM_CHARSET;
1139 lf.lfQuality = DEFAULT_QUALITY;
1140 lf.lfWeight = FW_MEDIUM;
1141 wcscpy(lf.lfFaceName, L"Tahoma");
1142
1143 hFont = CreateFontIndirectW(&lf);
1144 if (hFont)
1145 {
1146 hFontOld = SelectObject(hdc, hFont);
1147
1148 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1149 SetTextColor(hdc, RGB(255,255,255));
1150 SetBkMode(hdc, TRANSPARENT);
1151 DrawTextW(hdc,
1152 szBuffer,
1153 -1,
1154 &txtRc,
1155 DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP);
1156 SelectObject(hdc, hFontOld);
1157 DeleteObject(hFont);
1158 }
1159 }
1160
1161 txtRc.left = bmpRc.right * 0.25;
1162 txtRc.top = txtRc.bottom - 5;
1163 txtRc.right = bmpRc.right * 0.75;
1164 txtRc.bottom = pInfo->headerbitmap.bmHeight * 0.9;
1165
1166 if (LoadStringW(hInst,
1167 IDS_HEADERTEXT2,
1168 szBuffer,
1169 sizeof(szBuffer) / sizeof(WCHAR)))
1170 {
1171 lf.lfHeight = 30;
1172 lf.lfCharSet = OEM_CHARSET;
1173 lf.lfQuality = DEFAULT_QUALITY;
1174 lf.lfWeight = FW_EXTRABOLD;
1175 wcscpy(lf.lfFaceName, L"Tahoma");
1176
1177 hFont = CreateFontIndirectW(&lf);
1178 if (hFont)
1179 {
1180 hFontOld = SelectObject(hdc, hFont);
1181
1182 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1183 SetTextColor(hdc, RGB(255,255,255));
1184 SetBkMode(hdc, TRANSPARENT);
1185 DrawTextW(hdc,
1186 szBuffer,
1187 -1,
1188 &txtRc,
1189 DT_TOP | DT_SINGLELINE);
1190 SelectObject(hdc, hFontOld);
1191 DeleteObject(hFont);
1192 }
1193 }
1194
1195 DeleteDC(hdcMem);
1196 }
1197
1198 EndPaint(hDlg, &ps);
1199 }
1200
1201 break;
1202 }
1203
1204 case WM_CLOSE:
1205 {
1206 Cleanup(pInfo);
1207 EndDialog(hDlg, 0);
1208 }
1209 break;
1210
1211 HandleDefaultMessage:
1212 default:
1213 return FALSE;
1214 }
1215
1216 return FALSE;
1217 }
1218
1219
1220 BOOL
1221 OpenRDPConnectDialog(HINSTANCE hInstance,
1222 PRDPSETTINGS pRdpSettings)
1223 {
1224 INITCOMMONCONTROLSEX iccx;
1225
1226 hInst = hInstance;
1227
1228 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
1229 iccx.dwICC = ICC_TAB_CLASSES;
1230 InitCommonControlsEx(&iccx);
1231
1232 return (DialogBoxParamW(hInst,
1233 MAKEINTRESOURCEW(IDD_CONNECTDIALOG),
1234 NULL,
1235 DlgProc,
1236 (LPARAM)pRdpSettings) == IDOK);
1237 }