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