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