reactos/base/applications/mstsc/connectdialog.c
2019-08-15 14:20:00 +02:00

1352 lines
41 KiB
C

/*
rdesktop: A Remote Desktop Protocol client.
Connection settings dialog
Copyright (C) Ged Murphy 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "precomp.h"
#include <winreg.h>
#include <commdlg.h>
#define MAX_KEY_NAME 255
HINSTANCE hInst;
static VOID ReLoadGeneralPage(PINFO pInfo);
static VOID ReLoadDisplayPage(PINFO pInfo);
static VOID
DoOpenFile(PINFO pInfo)
{
OPENFILENAMEW ofn;
WCHAR szFileName[MAX_PATH] = L"Default.rdp";
static WCHAR szFilter[] = L"Remote Desktop Files (*.RDP)\0*.rdp\0";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = pInfo->hGeneralPage;
ofn.nMaxFile = MAX_PATH;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrDefExt = L"RDP";
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szFileName;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
if (GetOpenFileNameW(&ofn))
{
LoadRdpSettingsFromFile(pInfo->pRdpSettings, szFileName);
ReLoadGeneralPage(pInfo);
ReLoadDisplayPage(pInfo);
}
}
static VOID
DoSaveAs(PINFO pInfo)
{
OPENFILENAMEW ofn;
WCHAR szFileName[MAX_PATH] = L"Default.rdp";
static WCHAR szFilter[] = L"Remote Desktop Files (*.RDP)\0*.rdp\0";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = pInfo->hGeneralPage;
ofn.nMaxFile = MAX_PATH;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrDefExt = L"RDP";
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szFileName;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
if (GetSaveFileNameW(&ofn))
{
SaveAllSettings(pInfo);
SaveRdpSettingsToFile(szFileName, pInfo->pRdpSettings);
}
}
static VOID
OnTabWndSelChange(PINFO pInfo)
{
switch (TabCtrl_GetCurSel(pInfo->hTab))
{
case 0: //General
ShowWindow(pInfo->hGeneralPage, SW_SHOW);
ShowWindow(pInfo->hDisplayPage, SW_HIDE);
BringWindowToTop(pInfo->hGeneralPage);
break;
case 1: //Display
ShowWindow(pInfo->hGeneralPage, SW_HIDE);
ShowWindow(pInfo->hDisplayPage, SW_SHOW);
BringWindowToTop(pInfo->hDisplayPage);
break;
}
}
static VOID
LoadUsernameHint(HWND hDlg, INT iCur)
{
WCHAR szValue[MAXVALUE+1000];
WCHAR szName[MAX_KEY_NAME];
WCHAR szKeyName[] = L"Software\\Microsoft\\Terminal Server Client\\Servers";
PWCHAR lpAddress;
HKEY hKey;
HKEY hSubKey;
LONG lRet = ERROR_SUCCESS;
INT iIndex = 0;
DWORD dwSize = MAX_KEY_NAME;
SendDlgItemMessageW(hDlg, IDC_SERVERCOMBO, CB_GETLBTEXT, (WPARAM)iCur, (LPARAM)szValue);
/* remove possible port number */
lpAddress = wcstok(szValue, L":");
if (lpAddress == NULL)
return;
if (RegOpenKeyExW(HKEY_CURRENT_USER,
szKeyName,
0,
KEY_READ,
&hKey) == ERROR_SUCCESS)
{
while (lRet == ERROR_SUCCESS)
{
dwSize = MAX_KEY_NAME;
lRet = RegEnumKeyExW(hKey, iIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
if(lRet == ERROR_SUCCESS && wcscmp(szName, lpAddress) == 0)
{
if(RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
break;
dwSize = MAXVALUE * sizeof(WCHAR);
if(RegQueryValueExW(hKey, L"UsernameHint", 0, NULL, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS)
{
SetDlgItemTextW(hDlg, IDC_NAMEEDIT, szValue);
}
RegCloseKey(hSubKey);
break;
}
iIndex++;
}
RegCloseKey(hKey);
}
}
static VOID
FillServerAddressCombo(PINFO pInfo)
{
HKEY hKey;
WCHAR KeyName[] = L"Software\\Microsoft\\Terminal Server Client\\Default";
WCHAR Name[MAX_KEY_NAME];
LONG ret = ERROR_SUCCESS;
DWORD size;
INT i = 0;
BOOL found = FALSE;
if (RegOpenKeyExW(HKEY_CURRENT_USER,
KeyName,
0,
KEY_READ,
&hKey) == ERROR_SUCCESS)
{
while (ret == ERROR_SUCCESS)
{
size = MAX_KEY_NAME;
ret = RegEnumValueW(hKey,
i,
Name,
&size,
NULL,
NULL,
NULL,
NULL);
if (ret == ERROR_SUCCESS)
{
size = sizeof(Name);
if (RegQueryValueExW(hKey,
Name,
0,
NULL,
NULL,
&size) == ERROR_SUCCESS)
{
LPWSTR lpAddress = HeapAlloc(GetProcessHeap(),
0,
size);
if (lpAddress)
{
if (RegQueryValueExW(hKey,
Name,
0,
NULL,
(LPBYTE)lpAddress,
&size) == ERROR_SUCCESS)
{
SendDlgItemMessageW(pInfo->hGeneralPage,
IDC_SERVERCOMBO,
CB_ADDSTRING,
0,
(LPARAM)lpAddress);
found = TRUE;
}
HeapFree(GetProcessHeap(),
0,
lpAddress);
}
}
}
i++;
}
RegCloseKey(hKey);
}
if (LoadStringW(hInst,
IDS_BROWSESERVER,
Name,
sizeof(Name) / sizeof(WCHAR)))
{
SendDlgItemMessageW(pInfo->hGeneralPage,
IDC_SERVERCOMBO,
CB_ADDSTRING,
0,
(LPARAM)Name);
}
if(found)
{
SendDlgItemMessageW(pInfo->hGeneralPage,
IDC_SERVERCOMBO,
CB_SETCURSEL,
0,
0);
LoadUsernameHint(pInfo->hGeneralPage, 0);
}
}
static VOID
ReLoadGeneralPage(PINFO pInfo)
{
LPWSTR lpText;
/* add file address */
lpText = GetStringFromSettings(pInfo->pRdpSettings,
L"full address");
if (lpText)
{
SetDlgItemTextW(pInfo->hGeneralPage,
IDC_SERVERCOMBO,
lpText);
}
/* set user name */
lpText = GetStringFromSettings(pInfo->pRdpSettings,
L"username");
if (lpText)
{
SetDlgItemTextW(pInfo->hGeneralPage,
IDC_NAMEEDIT,
lpText);
}
}
static VOID
GeneralOnInit(HWND hwnd,
PINFO pInfo)
{
SetWindowLongPtrW(hwnd,
GWLP_USERDATA,
(LONG_PTR)pInfo);
pInfo->hGeneralPage = hwnd;
SetWindowPos(pInfo->hGeneralPage,
NULL,
2,
22,
0,
0,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
pInfo->hLogon = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_LOGON),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (pInfo->hLogon)
{
SendDlgItemMessageW(pInfo->hGeneralPage,
IDC_LOGONICON,
STM_SETICON,
(WPARAM)pInfo->hLogon,
0);
}
pInfo->hConn = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_CONN),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (pInfo->hConn)
{
SendDlgItemMessageW(pInfo->hGeneralPage,
IDC_CONNICON,
STM_SETICON,
(WPARAM)pInfo->hConn,
0);
}
FillServerAddressCombo(pInfo);
ReLoadGeneralPage(pInfo);
}
INT_PTR CALLBACK
GeneralDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PINFO pInfo = (PINFO)GetWindowLongPtrW(hDlg,
GWLP_USERDATA);
switch (message)
{
case WM_INITDIALOG:
GeneralOnInit(hDlg, (PINFO)lParam);
return TRUE;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_SERVERCOMBO:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
INT last, cur;
cur = SendDlgItemMessageW(hDlg,
IDC_SERVERCOMBO,
CB_GETCURSEL,
0,
0);
last = SendDlgItemMessageW(hDlg,
IDC_SERVERCOMBO,
CB_GETCOUNT,
0,
0);
if ((cur + 1) == last)
MessageBoxW(hDlg, L"SMB is not yet supported", L"RDP error", MB_ICONERROR);
else
{
LoadUsernameHint(hDlg, cur);
}
}
break;
case IDC_SAVE:
SaveAllSettings(pInfo);
SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
break;
case IDC_SAVEAS:
DoSaveAs(pInfo);
break;
case IDC_OPEN:
DoOpenFile(pInfo);
break;
}
break;
}
case WM_CLOSE:
{
if (pInfo->hLogon)
DestroyIcon(pInfo->hLogon);
if (pInfo->hConn)
DestroyIcon(pInfo->hConn);
break;
}
}
return 0;
}
static PSETTINGS_ENTRY
GetPossibleSettings(IN LPCWSTR lpDeviceName,
OUT DWORD* pSettingsCount,
OUT PSETTINGS_ENTRY* CurrentSettings)
{
DEVMODEW devmode;
DWORD NbSettings = 0;
DWORD iMode = 0;
DWORD dwFlags = 0;
PSETTINGS_ENTRY Settings = NULL;
HDC hDC;
PSETTINGS_ENTRY Current;
DWORD bpp, xres, yres, checkbpp;
/* Get current settings */
*CurrentSettings = NULL;
hDC = CreateICW(NULL, lpDeviceName, NULL, NULL);
bpp = GetDeviceCaps(hDC, PLANES);
bpp *= GetDeviceCaps(hDC, BITSPIXEL);
xres = GetDeviceCaps(hDC, HORZRES);
yres = GetDeviceCaps(hDC, VERTRES);
DeleteDC(hDC);
/* List all settings */
devmode.dmSize = (WORD)sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
if (!EnumDisplaySettingsExW(lpDeviceName, ENUM_CURRENT_SETTINGS, &devmode, dwFlags))
return NULL;
while (EnumDisplaySettingsExW(lpDeviceName, iMode, &devmode, dwFlags))
{
if (devmode.dmBitsPerPel==8 ||
devmode.dmBitsPerPel==16 ||
devmode.dmBitsPerPel==24 ||
devmode.dmBitsPerPel==32)
{
checkbpp=1;
}
else
checkbpp=0;
if (devmode.dmPelsWidth < 640 ||
devmode.dmPelsHeight < 480 || checkbpp == 0)
{
iMode++;
continue;
}
Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
if (Current != NULL)
{
/* Sort resolutions by increasing height, and BPP */
PSETTINGS_ENTRY Previous = NULL;
PSETTINGS_ENTRY Next = Settings;
Current->dmPelsWidth = devmode.dmPelsWidth;
Current->dmPelsHeight = devmode.dmPelsHeight;
Current->dmBitsPerPel = devmode.dmBitsPerPel;
while (Next != NULL &&
(Next->dmPelsWidth < Current->dmPelsWidth ||
(Next->dmPelsWidth == Current->dmPelsWidth && Next->dmPelsHeight < Current->dmPelsHeight) ||
(Next->dmPelsHeight == Current->dmPelsHeight &&
Next->dmPelsWidth == Current->dmPelsWidth &&
Next->dmBitsPerPel < Current->dmBitsPerPel )))
{
Previous = Next;
Next = Next->Flink;
}
Current->Blink = Previous;
Current->Flink = Next;
if (Previous == NULL)
Settings = Current;
else
Previous->Flink = Current;
if (Next != NULL)
Next->Blink = Current;
if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
{
*CurrentSettings = Current;
}
NbSettings++;
}
iMode++;
}
*pSettingsCount = NbSettings;
return Settings;
}
static BOOL
AddDisplayDevice(PINFO pInfo, PDISPLAY_DEVICEW DisplayDevice)
{
PDISPLAY_DEVICE_ENTRY newEntry = NULL;
LPWSTR description = NULL;
LPWSTR name = NULL;
LPWSTR key = NULL;
LPWSTR devid = NULL;
SIZE_T descriptionSize, nameSize, keySize, devidSize;
PSETTINGS_ENTRY Current;
DWORD ResolutionsCount = 1;
DWORD i;
newEntry = HeapAlloc(GetProcessHeap(),
0,
sizeof(DISPLAY_DEVICE_ENTRY));
if (!newEntry) goto ByeBye;
ZeroMemory(newEntry, sizeof(DISPLAY_DEVICE_ENTRY));
newEntry->Settings = GetPossibleSettings(DisplayDevice->DeviceName,
&newEntry->SettingsCount,
&newEntry->CurrentSettings);
if (!newEntry->Settings) goto ByeBye;
newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
/* Count different resolutions */
for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
{
if (Current->Flink != NULL &&
((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
(Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
{
ResolutionsCount++;
}
}
newEntry->Resolutions = HeapAlloc(GetProcessHeap(),
0,
ResolutionsCount * (sizeof(RESOLUTION_INFO) + 1));
if (!newEntry->Resolutions) goto ByeBye;
newEntry->ResolutionsCount = ResolutionsCount;
/* Fill resolutions infos */
for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
{
if (Current->Flink == NULL ||
(Current->Flink != NULL &&
((Current->dmPelsWidth != Current->Flink->dmPelsWidth) &&
(Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
{
newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
i++;
}
}
/* fullscreen */
newEntry->Resolutions[i].dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
newEntry->Resolutions[i].dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
descriptionSize = (wcslen(DisplayDevice->DeviceString) + 1) * sizeof(WCHAR);
description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
if (!description) goto ByeBye;
nameSize = (wcslen(DisplayDevice->DeviceName) + 1) * sizeof(WCHAR);
name = HeapAlloc(GetProcessHeap(), 0, nameSize);
if (!name) goto ByeBye;
keySize = (wcslen(DisplayDevice->DeviceKey) + 1) * sizeof(WCHAR);
key = HeapAlloc(GetProcessHeap(), 0, keySize);
if (!key) goto ByeBye;
devidSize = (wcslen(DisplayDevice->DeviceID) + 1) * sizeof(WCHAR);
devid = HeapAlloc(GetProcessHeap(), 0, devidSize);
if (!devid) goto ByeBye;
memcpy(description, DisplayDevice->DeviceString, descriptionSize);
memcpy(name, DisplayDevice->DeviceName, nameSize);
memcpy(key, DisplayDevice->DeviceKey, keySize);
memcpy(devid, DisplayDevice->DeviceID, devidSize);
newEntry->DeviceDescription = description;
newEntry->DeviceName = name;
newEntry->DeviceKey = key;
newEntry->DeviceID = devid;
newEntry->DeviceStateFlags = DisplayDevice->StateFlags;
newEntry->Flink = pInfo->DisplayDeviceList;
pInfo->DisplayDeviceList = newEntry;
return TRUE;
ByeBye:
if (newEntry != NULL)
{
if (newEntry->Settings != NULL)
{
Current = newEntry->Settings;
while (Current != NULL)
{
PSETTINGS_ENTRY Next = Current->Flink;
HeapFree(GetProcessHeap(), 0, Current);
Current = Next;
}
}
if (newEntry->Resolutions != NULL)
HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
HeapFree(GetProcessHeap(), 0, newEntry);
}
if (description != NULL)
HeapFree(GetProcessHeap(), 0, description);
if (name != NULL)
HeapFree(GetProcessHeap(), 0, name);
if (key != NULL)
HeapFree(GetProcessHeap(), 0, key);
if (devid != NULL)
HeapFree(GetProcessHeap(), 0, devid);
return FALSE;
}
static VOID
OnResolutionChanged(PINFO pInfo, INT position)
{
WCHAR Buffer[64];
INT MaxSlider;
MaxSlider = SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_GEOSLIDER,
TBM_GETRANGEMAX,
0,
0);
if (position == MaxSlider)
{
LoadStringW(hInst,
IDS_FULLSCREEN,
Buffer,
sizeof(Buffer) / sizeof(WCHAR));
}
else
{
WCHAR Pixel[64];
if (LoadStringW(hInst,
IDS_PIXEL,
Pixel,
sizeof(Pixel) / sizeof(WCHAR)))
{
swprintf(Buffer,
Pixel,
pInfo->DisplayDeviceList->Resolutions[position].dmPelsWidth,
pInfo->DisplayDeviceList->Resolutions[position].dmPelsHeight,
Pixel);
}
}
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_SETTINGS_RESOLUTION_TEXT,
WM_SETTEXT,
0,
(LPARAM)Buffer);
}
static VOID
FillResolutionsAndColors(PINFO pInfo)
{
PSETTINGS_ENTRY Current;
DWORD index, i, num;
DWORD MaxBpp = 0;
UINT types[5];
pInfo->CurrentDisplayDevice = pInfo->DisplayDeviceList; /* Update global variable */
/* find max bpp */
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_RESETCONTENT,
0,
0);
for (Current = pInfo->DisplayDeviceList->Settings; Current != NULL; Current = Current->Flink)
{
if (Current->dmBitsPerPel > MaxBpp)
MaxBpp = Current->dmBitsPerPel;
}
switch (MaxBpp)
{
case 32: num = 4; break;
case 24: num = 3; break;
case 16: num = 2; break;
case 15: num = 1; break;
case 8: num = 0; break;
default: num = 0; break;
}
types[0] = IDS_256COLORS;
types[1] = IDS_HIGHCOLOR15;
types[2] = IDS_HIGHCOLOR16;
types[3] = IDS_HIGHCOLOR24;
types[4] = IDS_HIGHCOLOR32;
/* Fill color depths combo box */
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_RESETCONTENT,
0,
0);
for (i = 0, Current = pInfo->DisplayDeviceList->Settings;
i <= num && Current != NULL;
i++, Current = Current->Flink)
{
WCHAR Buffer[64];
if (LoadStringW(hInst,
types[i],
Buffer,
sizeof(Buffer) / sizeof(WCHAR)))
{
index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_FINDSTRINGEXACT,
(WPARAM)-1,
(LPARAM)Buffer);
if (index == (DWORD)CB_ERR)
{
index = (DWORD)SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_ADDSTRING,
0,
(LPARAM)Buffer);
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_SETITEMDATA,
index,
types[i]);
}
}
}
/* Fill resolutions slider */
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_GEOSLIDER,
TBM_CLEARTICS,
TRUE,
0);
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_GEOSLIDER,
TBM_SETRANGE,
TRUE,
MAKELONG(0, pInfo->DisplayDeviceList->ResolutionsCount)); //extra 1 for full screen
}
static VOID
ReLoadDisplayPage(PINFO pInfo)
{
DWORD index;
INT width, height, pos = 0;
INT bpp, num, i, screenmode;
BOOL bSet = FALSE;
/* get fullscreen info */
screenmode = GetIntegerFromSettings(pInfo->pRdpSettings, L"screen mode id");
/* set trackbar position */
width = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopwidth");
height = GetIntegerFromSettings(pInfo->pRdpSettings, L"desktopheight");
if (width != -1 && height != -1)
{
if(screenmode == 2)
{
pos = SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_GEOSLIDER,
TBM_GETRANGEMAX,
0,
0);
}
else
{
for (index = 0; index < pInfo->CurrentDisplayDevice->ResolutionsCount; index++)
{
if (pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsWidth == width &&
pInfo->CurrentDisplayDevice->Resolutions[index].dmPelsHeight == height)
{
pos = index;
break;
}
}
}
}
/* set slider position */
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_GEOSLIDER,
TBM_SETPOS,
TRUE,
pos);
OnResolutionChanged(pInfo, pos);
/* set color combo */
bpp = GetIntegerFromSettings(pInfo->pRdpSettings, L"session bpp");
num = SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_GETCOUNT,
0,
0);
for (i = 0; i < num; i++)
{
INT data = SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_GETITEMDATA,
i,
0);
if (data == bpp)
{
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_SETCURSEL,
i,
0);
bSet = TRUE;
break;
}
}
if (!bSet)
{
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_BPPCOMBO,
CB_SETCURSEL,
num - 1,
0);
}
}
static VOID
DisplayOnInit(HWND hwnd,
PINFO pInfo)
{
DISPLAY_DEVICEW displayDevice;
DWORD iDevNum = 0;
BOOL GotDev = FALSE;
SetWindowLongPtrW(hwnd,
GWLP_USERDATA,
(LONG_PTR)pInfo);
pInfo->hDisplayPage = hwnd;
SetWindowPos(pInfo->hDisplayPage,
NULL,
2,
22,
0,
0,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
pInfo->hRemote = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_REMOTE),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (pInfo->hRemote)
{
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_REMICON,
STM_SETICON,
(WPARAM)pInfo->hRemote,
0);
}
pInfo->hColor = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_COLORS),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (pInfo->hColor)
{
SendDlgItemMessageW(pInfo->hDisplayPage,
IDC_COLORSICON,
STM_SETICON,
(WPARAM)pInfo->hColor,
0);
}
pInfo->hSpectrum = LoadImageW(hInst,
MAKEINTRESOURCEW(IDB_SPECT),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR);
if (pInfo->hSpectrum)
{
GetObjectW(pInfo->hSpectrum,
sizeof(BITMAP),
&pInfo->bitmap);
}
/* Get video cards list */
displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
while (EnumDisplayDevicesW(NULL, iDevNum, &displayDevice, 0x1))
{
if ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)
{
if (AddDisplayDevice(pInfo, &displayDevice))
GotDev = TRUE;
}
iDevNum++;
}
if (GotDev)
{
FillResolutionsAndColors(pInfo);
ReLoadDisplayPage(pInfo);
}
}
INT_PTR CALLBACK
DisplayDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PINFO pInfo = (PINFO)GetWindowLongPtrW(hDlg,
GWLP_USERDATA);
switch (message)
{
case WM_INITDIALOG:
DisplayOnInit(hDlg, (PINFO)lParam);
return TRUE;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpDrawItem;
lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
if(lpDrawItem->CtlID == IDC_COLORIMAGE)
{
HDC hdcMem;
HBITMAP hSpecOld;
hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
if (hdcMem != NULL)
{
hSpecOld = SelectObject(hdcMem, pInfo->hSpectrum);
StretchBlt(lpDrawItem->hDC,
lpDrawItem->rcItem.left,
lpDrawItem->rcItem.top,
lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
hdcMem,
0,
0,
pInfo->bitmap.bmWidth,
pInfo->bitmap.bmHeight,
SRCCOPY);
SelectObject(hdcMem, hSpecOld);
DeleteDC(hdcMem);
}
}
break;
}
case WM_HSCROLL:
{
switch (LOWORD(wParam))
{
case TB_LINEUP:
case TB_LINEDOWN:
case TB_PAGEUP:
case TB_PAGEDOWN:
case TB_TOP:
case TB_BOTTOM:
case TB_ENDTRACK:
{
INT newPosition = (DWORD)SendDlgItemMessageW(hDlg, IDC_GEOSLIDER, TBM_GETPOS, 0, 0);
OnResolutionChanged(pInfo, newPosition);
break;
}
case TB_THUMBTRACK:
OnResolutionChanged(pInfo, HIWORD(wParam));
break;
}
break;
}
case WM_CLOSE:
{
if (pInfo->hRemote)
DestroyIcon(pInfo->hRemote);
if (pInfo->hColor)
DestroyIcon(pInfo->hColor);
if (pInfo->hSpectrum)
DeleteObject(pInfo->hSpectrum);
break;
}
break;
}
return 0;
}
static BOOL
OnMainCreate(HWND hwnd,
PRDPSETTINGS pRdpSettings)
{
PINFO pInfo;
TCITEMW item;
BOOL bRet = FALSE;
pInfo = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(INFO));
if (pInfo)
{
SetWindowLongPtrW(hwnd,
GWLP_USERDATA,
(LONG_PTR)pInfo);
pInfo->hSelf = hwnd;
/* add main settings pointer */
pInfo->pRdpSettings = pRdpSettings;
/* set the dialog icons */
pInfo->hMstscSm = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_MSTSC),
IMAGE_ICON,
16,
16,
LR_DEFAULTCOLOR);
if (pInfo->hMstscSm)
{
SendMessageW(hwnd,
WM_SETICON,
ICON_SMALL,
(WPARAM)pInfo->hMstscSm);
}
pInfo->hMstscLg = LoadImageW(hInst,
MAKEINTRESOURCEW(IDI_MSTSC),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (pInfo->hMstscLg)
{
SendMessageW(hwnd,
WM_SETICON,
ICON_BIG,
(WPARAM)pInfo->hMstscLg);
}
pInfo->hHeader = (HBITMAP)LoadImageW(hInst,
MAKEINTRESOURCEW(IDB_HEADER),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR);
if (pInfo->hHeader)
{
GetObjectW(pInfo->hHeader,
sizeof(BITMAP),
&pInfo->headerbitmap);
}
/* setup the tabs */
pInfo->hTab = GetDlgItem(hwnd, IDC_TAB);
if (pInfo->hTab)
{
if (CreateDialogParamW(hInst,
MAKEINTRESOURCEW(IDD_GENERAL),
pInfo->hTab,
GeneralDlgProc,
(LPARAM)pInfo))
{
WCHAR str[256];
ZeroMemory(&item, sizeof(TCITEM));
item.mask = TCIF_TEXT;
if (LoadStringW(hInst, IDS_TAB_GENERAL, str, 256))
item.pszText = str;
item.cchTextMax = 256;
(void)TabCtrl_InsertItem(pInfo->hTab, 0, &item);
}
if (CreateDialogParamW(hInst,
MAKEINTRESOURCEW(IDD_DISPLAY),
pInfo->hTab,
DisplayDlgProc,
(LPARAM)pInfo))
{
WCHAR str[256];
ZeroMemory(&item, sizeof(TCITEM));
item.mask = TCIF_TEXT;
if (LoadStringW(hInst, IDS_TAB_DISPLAY, str, 256))
item.pszText = str;
item.cchTextMax = 256;
(void)TabCtrl_InsertItem(pInfo->hTab, 1, &item);
}
OnTabWndSelChange(pInfo);
}
}
return bRet;
}
static void Cleanup(PINFO pInfo)
{
if (pInfo)
{
if (pInfo->hMstscSm)
DestroyIcon(pInfo->hMstscSm);
if (pInfo->hMstscLg)
DestroyIcon(pInfo->hMstscLg);
if (pInfo->hHeader)
DeleteObject(pInfo->hHeader);
if (pInfo->hSpectrum)
DeleteObject(pInfo->hSpectrum);
if (pInfo->hRemote)
DestroyIcon(pInfo->hRemote);
if (pInfo->hLogon)
DestroyIcon(pInfo->hLogon);
if (pInfo->hConn)
DestroyIcon(pInfo->hConn);
if (pInfo->hColor)
DestroyIcon(pInfo->hColor);
HeapFree(GetProcessHeap(),
0,
pInfo);
}
}
static INT_PTR CALLBACK
DlgProc(HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PINFO pInfo;
/* Get the window context */
pInfo = (PINFO)GetWindowLongPtrW(hDlg,
GWLP_USERDATA);
if (pInfo == NULL && Message != WM_INITDIALOG)
{
goto HandleDefaultMessage;
}
switch(Message)
{
case WM_INITDIALOG:
OnMainCreate(hDlg, (PRDPSETTINGS)lParam);
break;
case WM_COMMAND:
{
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
if (LOWORD(wParam) == IDOK )
{
SaveAllSettings(pInfo);
SaveRdpSettingsToFile(NULL, pInfo->pRdpSettings);
}
Cleanup(pInfo);
EndDialog(hDlg, LOWORD(wParam));
}
break;
}
case WM_NOTIFY:
{
//INT idctrl;
LPNMHDR pnmh;
//idctrl = (int)wParam;
pnmh = (LPNMHDR)lParam;
if (//(pnmh->hwndFrom == pInfo->hSelf) &&
(pnmh->idFrom == IDC_TAB) &&
(pnmh->code == TCN_SELCHANGE))
{
OnTabWndSelChange(pInfo);
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hDlg, &ps);
if (hdc != NULL)
{
HDC hdcMem = CreateCompatibleDC(hdc);
if (hdcMem)
{
WCHAR szBuffer[32];
RECT bmpRc, txtRc;
LOGFONTW lf;
HFONT hFont, hFontOld;
HBITMAP hBmpOld;
GetClientRect(pInfo->hSelf, &bmpRc);
hBmpOld = SelectObject(hdcMem, pInfo->hHeader);
StretchBlt(hdc,
0,
0,
bmpRc.right,
pInfo->headerbitmap.bmHeight,
hdcMem,
0,
0,
pInfo->headerbitmap.bmWidth,
pInfo->headerbitmap.bmHeight,
SRCCOPY);
SelectObject(hdcMem, hBmpOld);
txtRc.left = bmpRc.right / 4;
txtRc.top = 10;
txtRc.right = bmpRc.right * 3 / 4;
txtRc.bottom = pInfo->headerbitmap.bmHeight / 2;
ZeroMemory(&lf, sizeof(LOGFONTW));
if (LoadStringW(hInst,
IDS_HEADERTEXT1,
szBuffer,
sizeof(szBuffer) / sizeof(WCHAR)))
{
lf.lfHeight = 20;
lf.lfCharSet = OEM_CHARSET;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfWeight = FW_MEDIUM;
wcscpy(lf.lfFaceName, L"Tahoma");
hFont = CreateFontIndirectW(&lf);
if (hFont)
{
hFontOld = SelectObject(hdc, hFont);
DPtoLP(hdc, (PPOINT)&txtRc, 2);
SetTextColor(hdc, RGB(255,255,255));
SetBkMode(hdc, TRANSPARENT);
DrawTextW(hdc,
szBuffer,
-1,
&txtRc,
DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP | DT_CENTER); //DT_CENTER makes the text visible in RTL layouts...
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
}
}
txtRc.left = bmpRc.right / 4;
txtRc.top = txtRc.bottom - 5;
#ifdef __REACTOS__
txtRc.right = bmpRc.right * 4 / 5;
#else
txtRc.right = bmpRc.right * 3 / 4;
#endif
txtRc.bottom = pInfo->headerbitmap.bmHeight * 9 / 10;
if (LoadStringW(hInst,
IDS_HEADERTEXT2,
szBuffer,
sizeof(szBuffer) / sizeof(WCHAR)))
{
lf.lfHeight = 24;
lf.lfCharSet = OEM_CHARSET;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfWeight = FW_EXTRABOLD;
wcscpy(lf.lfFaceName, L"Tahoma");
hFont = CreateFontIndirectW(&lf);
if (hFont)
{
hFontOld = SelectObject(hdc, hFont);
DPtoLP(hdc, (PPOINT)&txtRc, 2);
SetTextColor(hdc, RGB(255,255,255));
SetBkMode(hdc, TRANSPARENT);
DrawTextW(hdc,
szBuffer,
-1,
&txtRc,
DT_TOP | DT_SINGLELINE);
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
}
}
DeleteDC(hdcMem);
}
EndPaint(hDlg, &ps);
}
break;
}
case WM_CLOSE:
{
Cleanup(pInfo);
EndDialog(hDlg, 0);
}
break;
HandleDefaultMessage:
default:
return FALSE;
}
return FALSE;
}
BOOL
OpenRDPConnectDialog(HINSTANCE hInstance,
PRDPSETTINGS pRdpSettings)
{
INITCOMMONCONTROLSEX iccx;
hInst = hInstance;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccx.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&iccx);
return (DialogBoxParamW(hInst,
MAKEINTRESOURCEW(IDD_CONNECTDIALOG),
NULL,
DlgProc,
(LPARAM)pRdpSettings) == IDOK);
}