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