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