c67ecd9a9e6a0d51ab9adb722a6f31eb4a5ac6d4
[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 #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 #ifdef _MSC_VER
651 _swprintf(Buffer,
652 Pixel,
653 pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
654 pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
655 Pixel);
656 #else
657 swprintf(Buffer,
658 Pixel,
659 pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
660 pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
661 Pixel);
662 #endif
663 }
664 }
665
666 SendDlgItemMessageW(pInfo->hDisplayPage,
667 IDC_SETTINGS_RESOLUTION_TEXT,
668 WM_SETTEXT,
669 0,
670 (LPARAM)Buffer);
671 }
672
673
674 static VOID
675 FillResolutionsAndColors(PINFO pInfo)
676 {
677 PSETTINGS_ENTRY Current;
678 DWORD index, i, num;
679 DWORD MaxBpp = 0;
680 UINT types[4];
681
682 pInfo->CurrentDisplayDevice = pInfo->DisplayDeviceList; /* Update global variable */
683
684 /* find max bpp */
685 SendDlgItemMessageW(pInfo->hDisplayPage,
686 IDC_BPPCOMBO,
687 CB_RESETCONTENT,
688 0,
689 0);
690 for (Current = pInfo->DisplayDeviceList->Settings; Current != NULL; Current = Current->Flink)
691 {
692 if (Current->dmBitsPerPel > MaxBpp)
693 MaxBpp = Current->dmBitsPerPel;
694 }
695 switch (MaxBpp)
696 {
697 case 32:
698 case 24: num = 4; break;
699 case 16: num = 3; break;
700 case 8: num = 1; break;
701 default: num = 0; break;
702 }
703
704 types[0] = IDS_256COLORS;
705 types[1] = IDS_HIGHCOLOR15;
706 types[2] = IDS_HIGHCOLOR16;
707 types[3] = IDS_HIGHCOLOR24;
708
709 /* Fill color depths combo box */
710 SendDlgItemMessageW(pInfo->hDisplayPage,
711 IDC_BPPCOMBO,
712 CB_RESETCONTENT,
713 0,
714 0);
715
716 for (i = 0, Current = pInfo->DisplayDeviceList->Settings;
717 i <= num && Current != NULL;
718 i++, Current = Current->Flink)
719 {
720 WCHAR Buffer[64];
721 if (LoadStringW(hInst,
722 types[i],
723 Buffer,
724 sizeof(Buffer) / sizeof(WCHAR)))
725 {
726 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
727 IDC_BPPCOMBO,
728 CB_FINDSTRINGEXACT,
729 (WPARAM)-1,
730 (LPARAM)Buffer);
731 if (index == (DWORD)CB_ERR)
732 {
733 index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
734 IDC_BPPCOMBO,
735 CB_ADDSTRING,
736 0,
737 (LPARAM)Buffer);
738 SendDlgItemMessageW(pInfo->hDisplayPage,
739 IDC_BPPCOMBO,
740 CB_SETITEMDATA,
741 index,
742 types[i]);
743 }
744 }
745 }
746
747 /* Fill resolutions slider */
748 SendDlgItemMessageW(pInfo->hDisplayPage,
749 IDC_GEOSLIDER,
750 TBM_CLEARTICS,
751 TRUE,
752 0);
753 SendDlgItemMessageW(pInfo->hDisplayPage,
754 IDC_GEOSLIDER,
755 TBM_SETRANGE,
756 TRUE,
757 MAKELONG(0, pInfo->DisplayDeviceList->ResolutionsCount)); //extra 1 for full screen
758
759
760 }
761
762
763 static VOID
764 ReLoadDisplayPage(PINFO pInfo)
765 {
766 DWORD index;
767 INT width, height, pos = 0;
768 INT bpp, num, i, screenmode;
769 BOOL bSet = FALSE;
770
771 /* get fullscreen info */
772 screenmode = GetIntegerFromSettings(pInfo->pRdpSettings, L"screen mode id");
773
774 /* set trackbar position */
775 width = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopwidth");
776 height = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopheight");
777
778 if (width != -1 && height != -1)
779 {
780 if(screenmode == 2)
781 {
782 pos = SendDlgItemMessageW(pInfo->hDisplayPage,
783 IDC_GEOSLIDER,
784 TBM_GETRANGEMAX,
785 0,
786 0);
787 }
788 else
789 {
790 for (index = 0; index < pInfo->CurrentDisplayDevice->ResolutionsCount; index++)
791 {
792 if (pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsWidth == width &&
793 pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsHeight == height)
794 {
795 pos = index;
796 break;
797 }
798 }
799 }
800 }
801
802 /* set slider position */
803 SendDlgItemMessageW(pInfo->hDisplayPage,
804 IDC_GEOSLIDER,
805 TBM_SETPOS,
806 TRUE,
807 pos);
808
809 OnResolutionChanged(pInfo, pos);
810
811
812 /* set color combo */
813 bpp = GetIntegerFromSettings(pInfo->pRdpSettings, L"session bpp");
814
815 num = SendDlgItemMessageW(pInfo->hDisplayPage,
816 IDC_BPPCOMBO,
817 CB_GETCOUNT,
818 0,
819 0);
820 for (i = 0; i < num; i++)
821 {
822 INT data = SendDlgItemMessageW(pInfo->hDisplayPage,
823 IDC_BPPCOMBO,
824 CB_GETITEMDATA,
825 i,
826 0);
827 if (data == bpp)
828 {
829 SendDlgItemMessageW(pInfo->hDisplayPage,
830 IDC_BPPCOMBO,
831 CB_SETCURSEL,
832 i,
833 0);
834 bSet = TRUE;
835 break;
836 }
837 }
838
839 if (!bSet)
840 {
841 SendDlgItemMessageW(pInfo->hDisplayPage,
842 IDC_BPPCOMBO,
843 CB_SETCURSEL,
844 num - 1,
845 0);
846 }
847 }
848
849
850 static VOID
851 DisplayOnInit(HWND hwnd,
852 PINFO pInfo)
853 {
854 DISPLAY_DEVICEW displayDevice;
855 DWORD iDevNum = 0;
856 BOOL GotDev = FALSE;
857
858 SetWindowLongPtrW(hwnd,
859 GWLP_USERDATA,
860 (LONG_PTR)pInfo);
861
862 pInfo->hDisplayPage = hwnd;
863
864 SetWindowPos(pInfo->hDisplayPage,
865 NULL,
866 2,
867 22,
868 0,
869 0,
870 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
871
872 pInfo->hRemote = LoadImageW(hInst,
873 MAKEINTRESOURCEW(IDI_REMOTE),
874 IMAGE_ICON,
875 32,
876 32,
877 LR_DEFAULTCOLOR);
878 if (pInfo->hRemote)
879 {
880 SendDlgItemMessageW(pInfo->hDisplayPage,
881 IDC_REMICON,
882 STM_SETICON,
883 (WPARAM)pInfo->hRemote,
884 0);
885 }
886
887 pInfo->hColor = LoadImageW(hInst,
888 MAKEINTRESOURCEW(IDI_COLORS),
889 IMAGE_ICON,
890 32,
891 32,
892 LR_DEFAULTCOLOR);
893 if (pInfo->hColor)
894 {
895 SendDlgItemMessageW(pInfo->hDisplayPage,
896 IDC_COLORSICON,
897 STM_SETICON,
898 (WPARAM)pInfo->hColor,
899 0);
900 }
901
902 pInfo->hSpectrum = LoadImageW(hInst,
903 MAKEINTRESOURCEW(IDB_SPECT),
904 IMAGE_BITMAP,
905 0,
906 0,
907 LR_DEFAULTCOLOR);
908 if (pInfo->hSpectrum)
909 {
910 GetObjectW(pInfo->hSpectrum,
911 sizeof(BITMAP),
912 &pInfo->bitmap);
913 }
914
915 /* Get video cards list */
916 displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
917 while (EnumDisplayDevicesW(NULL, iDevNum, &displayDevice, 0x1))
918 {
919 if ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)
920 {
921 if (AddDisplayDevice(pInfo, &displayDevice))
922 GotDev = TRUE;
923 }
924 iDevNum++;
925 }
926
927 if (GotDev)
928 {
929 FillResolutionsAndColors(pInfo);
930 ReLoadDisplayPage(pInfo);
931 }
932 }
933
934
935 INT_PTR CALLBACK
936 DisplayDlgProc(HWND hDlg,
937 UINT message,
938 WPARAM wParam,
939 LPARAM lParam)
940 {
941 PINFO pInfo = (PINFO)GetWindowLongPtrW(hDlg,
942 GWLP_USERDATA);
943
944 switch (message)
945 {
946 case WM_INITDIALOG:
947 DisplayOnInit(hDlg, (PINFO)lParam);
948 return TRUE;
949
950 case WM_DRAWITEM:
951 {
952 LPDRAWITEMSTRUCT lpDrawItem;
953 lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
954 if(lpDrawItem->CtlID == IDC_COLORIMAGE)
955 {
956 HDC hdcMem;
957 HBITMAP hSpecOld;
958 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
959 if (hdcMem != NULL)
960 {
961 hSpecOld = SelectObject(hdcMem, pInfo->hSpectrum);
962 StretchBlt(lpDrawItem->hDC,
963 lpDrawItem->rcItem.left,
964 lpDrawItem->rcItem.top,
965 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
966 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
967 hdcMem,
968 0,
969 0,
970 pInfo->bitmap.bmWidth,
971 pInfo->bitmap.bmHeight,
972 SRCCOPY);
973 SelectObject(hdcMem, hSpecOld);
974 DeleteDC(hdcMem);
975 }
976 }
977 break;
978 }
979
980 case WM_HSCROLL:
981 {
982 switch (LOWORD(wParam))
983 {
984 case TB_LINEUP:
985 case TB_LINEDOWN:
986 case TB_PAGEUP:
987 case TB_PAGEDOWN:
988 case TB_TOP:
989 case TB_BOTTOM:
990 case TB_ENDTRACK:
991 {
992 INT newPosition = (DWORD)SendDlgItemMessageW(hDlg, IDC_GEOSLIDER, TBM_GETPOS, 0, 0);
993 OnResolutionChanged(pInfo, newPosition);
994 break;
995 }
996
997 case TB_THUMBTRACK:
998 OnResolutionChanged(pInfo, HIWORD(wParam));
999 break;
1000 }
1001 break;
1002 }
1003
1004 case WM_CLOSE:
1005 {
1006 if (pInfo->hRemote)
1007 DestroyIcon(pInfo->hRemote);
1008
1009 if (pInfo->hColor)
1010 DestroyIcon(pInfo->hColor);
1011
1012 if (pInfo->hSpectrum)
1013 DeleteObject(pInfo->hSpectrum);
1014
1015 break;
1016 }
1017
1018 break;
1019 }
1020 return 0;
1021 }
1022
1023
1024 static BOOL
1025 OnMainCreate(HWND hwnd,
1026 PRDPSETTINGS pRdpSettings)
1027 {
1028 PINFO pInfo;
1029 TCITEMW item;
1030 BOOL bRet = FALSE;
1031
1032 pInfo = HeapAlloc(GetProcessHeap(),
1033 HEAP_ZERO_MEMORY,
1034 sizeof(INFO));
1035 if (pInfo)
1036 {
1037 SetWindowLongPtrW(hwnd,
1038 GWLP_USERDATA,
1039 (LONG_PTR)pInfo);
1040
1041 pInfo->hSelf = hwnd;
1042
1043 /* add main settings pointer */
1044 pInfo->pRdpSettings = pRdpSettings;
1045
1046 /* set the dialog icons */
1047 pInfo->hMstscSm = LoadImageW(hInst,
1048 MAKEINTRESOURCEW(IDI_MSTSC),
1049 IMAGE_ICON,
1050 16,
1051 16,
1052 LR_DEFAULTCOLOR);
1053 if (pInfo->hMstscSm)
1054 {
1055 SendMessageW(hwnd,
1056 WM_SETICON,
1057 ICON_SMALL,
1058 (WPARAM)pInfo->hMstscSm);
1059 }
1060 pInfo->hMstscLg = LoadImageW(hInst,
1061 MAKEINTRESOURCEW(IDI_MSTSC),
1062 IMAGE_ICON,
1063 32,
1064 32,
1065 LR_DEFAULTCOLOR);
1066 if (pInfo->hMstscLg)
1067 {
1068 SendMessageW(hwnd,
1069 WM_SETICON,
1070 ICON_BIG,
1071 (WPARAM)pInfo->hMstscLg);
1072 }
1073
1074 pInfo->hHeader = (HBITMAP)LoadImageW(hInst,
1075 MAKEINTRESOURCEW(IDB_HEADER),
1076 IMAGE_BITMAP,
1077 0,
1078 0,
1079 LR_DEFAULTCOLOR);
1080 if (pInfo->hHeader)
1081 {
1082 GetObjectW(pInfo->hHeader,
1083 sizeof(BITMAP),
1084 &pInfo->headerbitmap);
1085 }
1086
1087 /* setup the tabs */
1088 pInfo->hTab = GetDlgItem(hwnd, IDC_TAB);
1089 if (pInfo->hTab)
1090 {
1091 if (CreateDialogParamW(hInst,
1092 MAKEINTRESOURCEW(IDD_GENERAL),
1093 pInfo->hTab,
1094 GeneralDlgProc,
1095 (LPARAM)pInfo))
1096 {
1097 WCHAR str[256];
1098 ZeroMemory(&item, sizeof(TCITEM));
1099 item.mask = TCIF_TEXT;
1100 if (LoadStringW(hInst, IDS_TAB_GENERAL, str, 256))
1101 item.pszText = str;
1102 item.cchTextMax = 256;
1103 (void)TabCtrl_InsertItem(pInfo->hTab, 0, &item);
1104 }
1105
1106 if (CreateDialogParamW(hInst,
1107 MAKEINTRESOURCEW(IDD_DISPLAY),
1108 pInfo->hTab,
1109 DisplayDlgProc,
1110 (LPARAM)pInfo))
1111 {
1112 WCHAR str[256];
1113 ZeroMemory(&item, sizeof(TCITEM));
1114 item.mask = TCIF_TEXT;
1115 if (LoadStringW(hInst, IDS_TAB_DISPLAY, str, 256))
1116 item.pszText = str;
1117 item.cchTextMax = 256;
1118 (void)TabCtrl_InsertItem(pInfo->hTab, 1, &item);
1119 }
1120
1121 OnTabWndSelChange(pInfo);
1122 }
1123 }
1124
1125 return bRet;
1126 }
1127
1128 static void Cleanup(PINFO pInfo)
1129 {
1130 if (pInfo)
1131 {
1132 if (pInfo->hMstscSm)
1133 DestroyIcon(pInfo->hMstscSm);
1134 if (pInfo->hMstscLg)
1135 DestroyIcon(pInfo->hMstscLg);
1136 if (pInfo->hHeader)
1137 DeleteObject(pInfo->hHeader);
1138 if (pInfo->hSpectrum)
1139 DeleteObject(pInfo->hSpectrum);
1140 if (pInfo->hRemote)
1141 DestroyIcon(pInfo->hRemote);
1142 if (pInfo->hLogon)
1143 DestroyIcon(pInfo->hLogon);
1144 if (pInfo->hConn)
1145 DestroyIcon(pInfo->hConn);
1146 if (pInfo->hColor)
1147 DestroyIcon(pInfo->hColor);
1148 HeapFree(GetProcessHeap(),
1149 0,
1150 pInfo);
1151 }
1152 }
1153
1154 static INT_PTR CALLBACK
1155 DlgProc(HWND hDlg,
1156 UINT Message,
1157 WPARAM wParam,
1158 LPARAM lParam)
1159 {
1160 PINFO pInfo;
1161
1162 /* Get the window context */
1163 pInfo = (PINFO)GetWindowLongPtrW(hDlg,
1164 GWLP_USERDATA);
1165 if (pInfo == NULL && Message != WM_INITDIALOG)
1166 {
1167 goto HandleDefaultMessage;
1168 }
1169
1170 switch(Message)
1171 {
1172 case WM_INITDIALOG:
1173 OnMainCreate(hDlg, (PRDPSETTINGS)lParam);
1174 break;
1175
1176 case WM_COMMAND:
1177 {
1178 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
1179 {
1180 if (LOWORD(wParam) == IDOK )
1181 {
1182 SaveAllSettings(pInfo);
1183 SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
1184 }
1185 Cleanup(pInfo);
1186 EndDialog(hDlg, LOWORD(wParam));
1187 }
1188
1189 break;
1190 }
1191
1192 case WM_NOTIFY:
1193 {
1194 //INT idctrl;
1195 LPNMHDR pnmh;
1196 //idctrl = (int)wParam;
1197 pnmh = (LPNMHDR)lParam;
1198 if (//(pnmh->hwndFrom == pInfo->hSelf) &&
1199 (pnmh->idFrom == IDC_TAB) &&
1200 (pnmh->code == TCN_SELCHANGE))
1201 {
1202 OnTabWndSelChange(pInfo);
1203 }
1204
1205 break;
1206 }
1207
1208 case WM_PAINT:
1209 {
1210 PAINTSTRUCT ps;
1211 HDC hdc;
1212
1213 hdc = BeginPaint(hDlg, &ps);
1214 if (hdc != NULL)
1215 {
1216 HDC hdcMem = CreateCompatibleDC(hdc);
1217 if (hdcMem)
1218 {
1219 WCHAR szBuffer[32];
1220 RECT bmpRc, txtRc;
1221 LOGFONTW lf;
1222 HFONT hFont, hFontOld;
1223 HBITMAP hBmpOld;
1224
1225 GetClientRect(pInfo->hSelf, &bmpRc);
1226
1227 hBmpOld = SelectObject(hdcMem, pInfo->hHeader);
1228 StretchBlt(hdc,
1229 0,
1230 0,
1231 bmpRc.right,
1232 pInfo->headerbitmap.bmHeight,
1233 hdcMem,
1234 0,
1235 0,
1236 pInfo->headerbitmap.bmWidth,
1237 pInfo->headerbitmap.bmHeight,
1238 SRCCOPY);
1239
1240 SelectObject(hdcMem, hBmpOld);
1241 txtRc.left = bmpRc.right / 4;
1242 txtRc.top = 10;
1243 txtRc.right = bmpRc.right * 3 / 4;
1244 txtRc.bottom = pInfo->headerbitmap.bmHeight / 2;
1245
1246 ZeroMemory(&lf, sizeof(LOGFONTW));
1247
1248 if (LoadStringW(hInst,
1249 IDS_HEADERTEXT1,
1250 szBuffer,
1251 sizeof(szBuffer) / sizeof(WCHAR)))
1252 {
1253 lf.lfHeight = 24;
1254 lf.lfCharSet = OEM_CHARSET;
1255 lf.lfQuality = DEFAULT_QUALITY;
1256 lf.lfWeight = FW_MEDIUM;
1257 wcscpy(lf.lfFaceName, L"Tahoma");
1258
1259 hFont = CreateFontIndirectW(&lf);
1260 if (hFont)
1261 {
1262 hFontOld = SelectObject(hdc, hFont);
1263
1264 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1265 SetTextColor(hdc, RGB(255,255,255));
1266 SetBkMode(hdc, TRANSPARENT);
1267 DrawTextW(hdc,
1268 szBuffer,
1269 -1,
1270 &txtRc,
1271 DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP);
1272 SelectObject(hdc, hFontOld);
1273 DeleteObject(hFont);
1274 }
1275 }
1276
1277 txtRc.left = bmpRc.right / 4;
1278 txtRc.top = txtRc.bottom - 5;
1279 txtRc.right = bmpRc.right * 3 / 4;
1280 txtRc.bottom = pInfo->headerbitmap.bmHeight * 9 / 10;
1281
1282 if (LoadStringW(hInst,
1283 IDS_HEADERTEXT2,
1284 szBuffer,
1285 sizeof(szBuffer) / sizeof(WCHAR)))
1286 {
1287 lf.lfHeight = 30;
1288 lf.lfCharSet = OEM_CHARSET;
1289 lf.lfQuality = DEFAULT_QUALITY;
1290 lf.lfWeight = FW_EXTRABOLD;
1291 wcscpy(lf.lfFaceName, L"Tahoma");
1292
1293 hFont = CreateFontIndirectW(&lf);
1294 if (hFont)
1295 {
1296 hFontOld = SelectObject(hdc, hFont);
1297
1298 DPtoLP(hdc, (PPOINT)&txtRc, 2);
1299 SetTextColor(hdc, RGB(255,255,255));
1300 SetBkMode(hdc, TRANSPARENT);
1301 DrawTextW(hdc,
1302 szBuffer,
1303 -1,
1304 &txtRc,
1305 DT_TOP | DT_SINGLELINE);
1306 SelectObject(hdc, hFontOld);
1307 DeleteObject(hFont);
1308 }
1309 }
1310
1311 DeleteDC(hdcMem);
1312 }
1313
1314 EndPaint(hDlg, &ps);
1315 }
1316
1317 break;
1318 }
1319
1320 case WM_CLOSE:
1321 {
1322 Cleanup(pInfo);
1323 EndDialog(hDlg, 0);
1324 }
1325 break;
1326
1327 HandleDefaultMessage:
1328 default:
1329 return FALSE;
1330 }
1331
1332 return FALSE;
1333 }
1334
1335
1336 BOOL
1337 OpenRDPConnectDialog(HINSTANCE hInstance,
1338 PRDPSETTINGS pRdpSettings)
1339 {
1340 INITCOMMONCONTROLSEX iccx;
1341
1342 hInst = hInstance;
1343
1344 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
1345 iccx.dwICC = ICC_TAB_CLASSES;
1346 InitCommonControlsEx(&iccx);
1347
1348 return (DialogBoxParamW(hInst,
1349 MAKEINTRESOURCEW(IDD_CONNECTDIALOG),
1350 NULL,
1351 DlgProc,
1352 (LPARAM)pRdpSettings) == IDOK);
1353 }