Display advanced display settings and allow shell extensions to extend it. Not yet fully functional/working

svn path=/trunk/; revision=29210
This commit is contained in:
Thomas Bluemel 2007-09-26 06:20:16 +00:00
parent ad47c9b3a9
commit 3b6747e11c
8 changed files with 1277 additions and 69 deletions

View file

@ -0,0 +1,187 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Display Control Panel
* FILE: dll/cpl/desk/advmon.c
* PURPOSE: Advanced monitor/display settings
*/
#include "desk.h"
#define MAX_ADVANCED_PAGES 32
static BOOL CALLBACK
PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
{
PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
if (ppsh != NULL && ppsh->nPages < MAX_ADVANCED_PAGES)
{
ppsh->phpage[ppsh->nPages++] = hpage;
return TRUE;
}
return FALSE;
}
static BOOL
InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc, LPARAM lParam)
{
HPROPSHEETPAGE hPage;
PROPSHEETPAGE psp;
if (ppsh->nPages < MAX_ADVANCED_PAGES)
{
ZeroMemory(&psp, sizeof(psp));
psp.dwSize = sizeof(psp);
psp.dwFlags = PSP_DEFAULT;
psp.hInstance = hApplet;
psp.pszTemplate = MAKEINTRESOURCE(idDlg);
psp.pfnDlgProc = DlgProc;
psp.lParam = lParam;
hPage = CreatePropertySheetPage(&psp);
if (hPage != NULL)
{
return PropSheetAddPage(hPage, (LPARAM)ppsh);
}
}
return FALSE;
}
static INT_PTR CALLBACK
AdvGeneralPageProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PDISPLAY_DEVICE_ENTRY DispDevice = NULL;
INT_PTR Ret = 0;
if (uMsg != WM_INITDIALOG)
DispDevice = (PDISPLAY_DEVICE_ENTRY)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
{
case WM_INITDIALOG:
DispDevice = (PDISPLAY_DEVICE_ENTRY)(((LPPROPSHEETPAGE)lParam)->lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)DispDevice);
Ret = TRUE;
break;
}
return Ret;
}
static LPTSTR
QueryDevSettingsString(IDataObject *pdo, UINT cfFormat)
{
FORMATETC fetc;
STGMEDIUM medium;
SIZE_T BufLen;
LPWSTR lpRecvBuffer;
LPTSTR lpStr = NULL;
fetc.cfFormat = (CLIPFORMAT)cfFormat;
fetc.ptd = NULL;
fetc.dwAspect = DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.tymed = TYMED_HGLOBAL;
if (SUCCEEDED(IDataObject_GetData(pdo, &fetc, &medium)) && medium.hGlobal != NULL)
{
/* We always receive the string in unicode! */
lpRecvBuffer = (LPWSTR)GlobalLock(medium.hGlobal);
BufLen = wcslen(lpRecvBuffer) + 1;
lpStr = LocalAlloc(LMEM_FIXED, BufLen * sizeof(TCHAR));
if (lpStr != NULL)
{
#ifdef UNICODE
wcscpy(lpStr, lpRecvBuffer);
#else
WideCharToMultiByte(CP_APC, 0, lpRecvBuffer, -1, lpStr, BufLen, NULL, NULL);
#endif
}
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
}
return lpStr;
}
static VOID
BuildAdvPropTitle(IDataObject *pdo, LPTSTR lpBuffer, DWORD dwBufferLen)
{
UINT uiMonitorName, uiDisplayName;
LPTSTR lpMonitorName, lpDisplayName;
TCHAR szFormatBuff[32];
if (!LoadString(hApplet, IDS_ADVANCEDTITLEFMT, szFormatBuff, sizeof(szFormatBuff) / sizeof(szFormatBuff[0])))
{
szFormatBuff[0] = _T('\0');
}
uiMonitorName = RegisterClipboardFormat(TEXT("Monitor Name"));
uiDisplayName = RegisterClipboardFormat(TEXT("Display Name"));
lpMonitorName = QueryDevSettingsString(pdo, uiMonitorName);
lpDisplayName = QueryDevSettingsString(pdo, uiDisplayName);
_sntprintf(lpBuffer, dwBufferLen, szFormatBuff, lpMonitorName, lpDisplayName);
if (lpMonitorName != NULL)
LocalFree((HLOCAL)lpMonitorName);
if (lpDisplayName != NULL)
LocalFree((HLOCAL)lpDisplayName);
}
BOOL
DisplayAdvancedSettings(HWND hWndParent, PDISPLAY_DEVICE_ENTRY DisplayDevice)
{
TCHAR szCaption[128];
HPROPSHEETPAGE hpsp[MAX_ADVANCED_PAGES];
PROPSHEETHEADER psh;
HPSXA hpsxaDev, hpsxaDisp;
BOOL Ret;
IDataObject *pdo;
/* FIXME: Build the "%s and %s" caption string for the monitor and adapter name */
szCaption[0] = _T('\0');
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPTITLE;
psh.hwndParent = hWndParent;
psh.hInstance = hApplet;
psh.pszCaption = szCaption;
psh.phpage = hpsp;
InitPropSheetPage(&psh, IDD_ADVANCED_GENERAL, AdvGeneralPageProc, (LPARAM)DisplayDevice);
pdo = CreateDevSettings(DisplayDevice);
if (pdo != NULL)
BuildAdvPropTitle(pdo, szCaption, sizeof(szCaption) / sizeof(szCaption[0]));
hpsxaDev = SHCreatePropSheetExtArrayEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Device"), MAX_ADVANCED_PAGES - psh.nPages, pdo);
if (hpsxaDev != NULL)
SHAddFromPropSheetExtArray(hpsxaDev, PropSheetAddPage, (LPARAM)&psh);
hpsxaDisp = SHCreatePropSheetExtArrayEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Display"), MAX_ADVANCED_PAGES - psh.nPages, pdo);
if (hpsxaDisp != NULL)
SHAddFromPropSheetExtArray(hpsxaDisp, PropSheetAddPage, (LPARAM)&psh);
Ret = (LONG)(PropertySheet(&psh) != -1);
if (hpsxaDisp != NULL)
SHDestroyPropSheetExtArray(hpsxaDisp);
if (hpsxaDev != NULL)
SHDestroyPropSheetExtArray(hpsxaDev);
IDataObject_Release(pdo);
return Ret;
}

View file

@ -33,26 +33,66 @@ APPLET Applets[NUM_APPLETS] =
}
};
static VOID
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
static BOOL CALLBACK
PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
{
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = PSP_DEFAULT;
psp->hInstance = hApplet;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pfnDlgProc = DlgProc;
PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
{
ppsh->phpage[ppsh->nPages++] = hpage;
return TRUE;
}
return FALSE;
}
static BOOL
InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc)
{
HPROPSHEETPAGE hPage;
PROPSHEETPAGE psp;
if (ppsh->nPages < MAX_DESK_PAGES)
{
ZeroMemory(&psp, sizeof(psp));
psp.dwSize = sizeof(psp);
psp.dwFlags = PSP_DEFAULT;
psp.hInstance = hApplet;
psp.pszTemplate = MAKEINTRESOURCE(idDlg);
psp.pfnDlgProc = DlgProc;
hPage = CreatePropertySheetPage(&psp);
if (hPage != NULL)
{
return PropSheetAddPage(hPage, (LPARAM)ppsh);
}
}
return FALSE;
}
static const struct
{
WORD idDlg;
DLGPROC DlgProc;
} PropPages[] =
{
{ IDD_BACKGROUND, BackgroundPageProc },
{ IDD_SCREENSAVER, ScreenSaverPageProc },
{ IDD_APPEARANCE, AppearancePageProc },
{ IDD_SETTINGS, SettingsPageProc },
};
/* Display Applet */
static LONG APIENTRY
DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
{
PROPSHEETPAGE psp[4];
HPROPSHEETPAGE hpsp[MAX_DESK_PAGES];
PROPSHEETHEADER psh;
HPSXA hpsxa;
TCHAR Caption[1024];
LONG ret;
UINT i;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
@ -63,21 +103,41 @@ DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_PROPTITLE;
psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
psh.hwndParent = NULL;
psh.hInstance = hApplet;
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
psh.pszCaption = Caption;
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nPages = 0;
psh.nStartPage = 0;
psh.ppsp = psp;
psh.phpage = hpsp;
InitPropSheetPage(&psp[0], IDD_BACKGROUND, (DLGPROC) BackgroundPageProc);
InitPropSheetPage(&psp[1], IDD_SCREENSAVER, (DLGPROC) ScreenSaverPageProc);
InitPropSheetPage(&psp[2], IDD_APPEARANCE, (DLGPROC) AppearancePageProc);
InitPropSheetPage(&psp[3], IDD_SETTINGS, (DLGPROC) SettingsPageProc);
/* Allow shell extensions to replace the background page */
hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
return (LONG)(PropertySheet(&psh) != -1);
for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
{
/* Override the background page if requested by a shell extension */
if (PropPages[i].idDlg == IDD_BACKGROUND && hpsxa != NULL &&
SHReplaceFromPropSheetExtArray(hpsxa, CPLPAGE_DISPLAY_BACKGROUND, PropSheetAddPage, (LPARAM)&psh) != 0)
{
/* The shell extension added one or more pages to replace the background page.
Don't create the built-in page anymore! */
continue;
}
InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc);
}
/* NOTE: Don;t call SHAddFromPropSheetExtArray here because this applet only allows
replacing the background page but not extending the applet by more pages */
ret = (LONG)(PropertySheet(&psh) != -1);
if (hpsxa != NULL)
SHDestroyPropSheetExtArray(hpsxa);
return ret;
}

View file

@ -1,6 +1,7 @@
#ifndef __CPL_DESK_H__
#define __CPL_DESK_H__
#define COBJMACROS
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
@ -8,6 +9,9 @@
#include <tchar.h>
#include <setupapi.h>
#include <stdio.h>
#include <shlobj.h>
#include <regstr.h>
#include <cplext.h>
#include "resource.h"
@ -37,7 +41,51 @@ INT AllocAndLoadString(LPTSTR *lpTarget,
HINSTANCE hInst,
UINT uID);
DWORD DbgPrint(PCH Format,...);
ULONG __cdecl DbgPrint(PCCH Format,...);
#define MAX_DESK_PAGES 32
/* As slider control can't contain user data, we have to keep an
* array of RESOLUTION_INFO to have our own associated data.
*/
typedef struct _RESOLUTION_INFO
{
DWORD dmPelsWidth;
DWORD dmPelsHeight;
} RESOLUTION_INFO, *PRESOLUTION_INFO;
typedef struct _SETTINGS_ENTRY
{
struct _SETTINGS_ENTRY *Blink;
struct _SETTINGS_ENTRY *Flink;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
} SETTINGS_ENTRY, *PSETTINGS_ENTRY;
typedef struct _DISPLAY_DEVICE_ENTRY
{
struct _DISPLAY_DEVICE_ENTRY *Flink;
LPTSTR DeviceDescription;
LPTSTR DeviceName;
LPTSTR DeviceKey;
LPTSTR DeviceID;
DWORD DeviceStateFlags;
PSETTINGS_ENTRY Settings; /* sorted by increasing dmPelsHeight, BPP */
DWORD SettingsCount;
PRESOLUTION_INFO Resolutions;
DWORD ResolutionsCount;
PSETTINGS_ENTRY CurrentSettings; /* Points into Settings list */
SETTINGS_ENTRY InitialSettings;
} DISPLAY_DEVICE_ENTRY, *PDISPLAY_DEVICE_ENTRY;
BOOL
DisplayAdvancedSettings(HWND hWndParent, PDISPLAY_DEVICE_ENTRY DisplayDevice);
IDataObject *
CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo);
HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY,LPCWSTR,UINT,IDataObject*);
#endif /* __CPL_DESK_H__ */

View file

@ -15,15 +15,19 @@
<library>gdi32</library>
<library>comctl32</library>
<library>comdlg32</library>
<library>ole32</library>
<library>setupapi</library>
<library>shell32</library>
<library>ntdll</library>
<library>msimg32</library>
<library>msvcrt</library>
<library>uuid</library>
<file>advmon.c</file>
<file>appearance.c</file>
<file>background.c</file>
<file>classinst.c</file>
<file>desk.c</file>
<file>devsett.c</file>
<file>dibitmap.c</file>
<file>misc.c</file>
<file>preview.c</file>

View file

@ -0,0 +1,910 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Display Control Panel
* FILE: lib/cpl/desk/devsett.c
* PURPOSE: ReactOS Display Control Panel Shell Extension Support
*/
#include "desk.h"
#define NDEBUG
#include <debug.h>
#define DEBUG_DEVSETTINGS
#define DESK_EXT_CALLBACK CALLBACK
typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_ENUMALLMODES)(PVOID Context, DWORD Index);
typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_GETCURRENTMODE)(PVOID Context);
typedef BOOL (DESK_EXT_CALLBACK *PDESK_EXT_SETCURRENTMODE)(PVOID Context, const DEVMODEW *pDevMode);
typedef VOID (DESK_EXT_CALLBACK *PDESK_EXT_GETPRUNINGMODE)(PVOID Context, PBOOL pbModesPruned, PBOOL pbKeyIsReadOnly, PBOOL pbPruningOn);
typedef VOID (DESK_EXT_CALLBACK *PDESK_EXT_SETPRUNINGMODE)(PVOID Context, BOOL PruningOn);
typedef struct _DESK_EXT_INTERFACE
{
/* NOTE: This structure is binary compatible to XP. The windows shell
extensions rely on this structure to be properly filled! */
DWORD cbSize;
PVOID Context; /* This value is passed on to the callback routines */
/* Callback routines called by the shell extensions */
PDESK_EXT_ENUMALLMODES EnumAllModes;
PDESK_EXT_SETCURRENTMODE SetCurrentMode;
PDESK_EXT_GETCURRENTMODE GetCurrentMode;
PDESK_EXT_SETPRUNINGMODE SetPruningMode;
PDESK_EXT_GETPRUNINGMODE GetPruningMode;
/* HardwareInformation.* values provided in the device registry key */
WCHAR MemorySize[128];
WCHAR ChipType[128];
WCHAR DacType[128];
WCHAR AdapterString[128];
WCHAR BiosString[128];
} DESK_EXT_INTERFACE, *PDESK_EXT_INTERFACE;
typedef struct _CDevSettings
{
const struct IDataObjectVtbl *lpIDataObjectVtbl;
DWORD ref;
CLIPFORMAT cfExtInterface; /* "Desk.cpl extension interface" */
CLIPFORMAT cfDisplayDevice; /* "Display Device" */
CLIPFORMAT cfDisplayName; /* "Display Name" */
CLIPFORMAT cfDisplayId; /* "Display ID" */
CLIPFORMAT cfMonitorName; /* "Monitor Name" */
CLIPFORMAT cfMonitorDevice; /* "Monitor Device" */
CLIPFORMAT cfMonitorId; /* "Monitor ID" */
CLIPFORMAT cfDisplayKey; /* "Display Key" */
CLIPFORMAT cfDisplayStateFlags; /* "Display State Flags" */
CLIPFORMAT cfPruningMode; /* "Pruning Mode" */
PWSTR pDisplayDevice;
PWSTR pDisplayName;
PWSTR pDisplayKey;
PWSTR pDisplayId;
PWSTR pMonitorName;
PWSTR pMonitorDevice;
PWSTR pMonitorId;
DESK_EXT_INTERFACE ExtInterface;
DWORD StateFlags;
union
{
DWORD Flags;
struct
{
DWORD bModesPruned : 1;
DWORD bKeyIsReadOnly : 1;
DWORD bPruningOn : 1;
};
};
} CDevSettings, *PCDevSettings;
#define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
static __inline PCDevSettings
impl_from_IDataObject(struct IDataObject *iface)
{
return (PCDevSettings)((ULONG_PTR)iface - FIELD_OFFSET(CDevSettings,
lpIDataObjectVtbl));
}
static __inline VOID
pCDevSettings_FreeString(PWCHAR *psz)
{
if (*psz != NULL)
{
LocalFree((HLOCAL)*psz);
*psz = NULL;
}
}
static PWSTR
pCDevSettings_AllocAndCopyString(const TCHAR *pszSrc)
{
INT c;
PWSTR str;
c = _tcslen(pszSrc) + 1;
str = (PWSTR)LocalAlloc(LMEM_FIXED,
c * sizeof(WCHAR));
if (str != NULL)
{
#ifdef UNICODE
wcscpy(str,
pszSrc);
#else
MultiByteToWideChar(CP_APC,
0,
pszSrc,
-1,
str,
c);
#endif
}
return str;
}
static PWSTR
pCDevSettings_GetMonitorName(const WCHAR *pszDisplayDevice)
{
DISPLAY_DEVICEW dd, dd2;
PWSTR str = NULL;
dd.cb = sizeof(dd);
if (EnumDisplayDevicesW(pszDisplayDevice,
0,
&dd,
0))
{
dd2.cb = sizeof(dd2);
if (EnumDisplayDevicesW(pszDisplayDevice,
1,
&dd2,
0))
{
/* There's more than one monitor connected... */
LoadStringW(hApplet,
IDS_MULTIPLEMONITORS,
dd.DeviceString,
sizeof(dd.DeviceString) / sizeof(dd.DeviceString[0]));
}
}
else
{
/* We can't enumerate a monitor, make sure this fact is reported
to the user! */
LoadStringW(hApplet,
IDS_UNKNOWNMONITOR,
dd.DeviceString,
sizeof(dd.DeviceString) / sizeof(dd.DeviceString[0]));
}
str = LocalAlloc(LMEM_FIXED,
(wcslen(dd.DeviceString) + 1) * sizeof(WCHAR));
if (str != NULL)
{
wcscpy(str,
dd.DeviceString);
}
return str;
}
static PWSTR
pCDevSettings_GetMonitorDevice(const WCHAR *pszDisplayDevice)
{
DISPLAY_DEVICEW dd;
PWSTR str = NULL;
dd.cb = sizeof(dd);
if (EnumDisplayDevicesW(pszDisplayDevice,
0,
&dd,
0))
{
str = LocalAlloc(LMEM_FIXED,
(wcslen(dd.DeviceName) + 1) * sizeof(WCHAR));
if (str != NULL)
{
wcscpy(str,
dd.DeviceName);
}
}
return str;
}
static PWSTR
pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice)
{
/* FIXME: Implement */
DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice);
return NULL;
}
static HKEY
pCDevSettings_OpenDeviceKey(PCDevSettings This,
BOOL ReadOnly)
{
static const WCHAR szRegPrefix[] = L"\\Registry\\Machine\\";
PWSTR lpRegKey;
REGSAM Access = KEY_READ;
HKEY hKey;
lpRegKey = This->pDisplayKey;
if (lpRegKey != NULL)
{
if (wcslen(lpRegKey) >= wcslen(szRegPrefix) &&
!wcsnicmp(lpRegKey,
szRegPrefix,
wcslen(szRegPrefix)))
{
lpRegKey += wcslen(szRegPrefix);
}
if (!ReadOnly)
Access |= KEY_WRITE;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
lpRegKey,
0,
Access,
&hKey) == ERROR_SUCCESS)
{
return hKey;
}
}
return NULL;
}
PDEVMODEW DESK_EXT_CALLBACK
CDevSettings_EnumAllModes(PVOID Context,
DWORD Index)
{
//PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
/* FIXME: Implement */
DPRINT1("CDevSettings::EnumAllModes(%u)\n", Index);
return NULL;
}
PDEVMODEW DESK_EXT_CALLBACK
CDevSettings_GetCurrentMode(PVOID Context)
{
//PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
/* FIXME: Implement */
DPRINT1("CDevSettings::GetCurrentMode\n");
return NULL;
}
BOOL DESK_EXT_CALLBACK
CDevSettings_SetCurrentMode(PVOID Context,
const DEVMODEW *pDevMode)
{
//PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
/* FIXME: Implement */
DPRINT1("CDevSettings::SetCurrentMode(0x%p)\n", pDevMode);
return FALSE;
}
VOID DESK_EXT_CALLBACK
CDevSettings_GetPruningMode(PVOID Context,
PBOOL pbModesPruned,
PBOOL pbKeyIsReadOnly,
PBOOL pbPruningOn)
{
PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
DPRINT1("CDevSettings::GetPruningMode(%p,%p,%p)\n", pbModesPruned, pbKeyIsReadOnly, pbPruningOn);
*pbModesPruned = This->bModesPruned;
*pbKeyIsReadOnly = This->bKeyIsReadOnly;
*pbPruningOn = This->bPruningOn;
}
VOID DESK_EXT_CALLBACK
CDevSettings_SetPruningMode(PVOID Context,
BOOL PruningOn)
{
HKEY hKey;
DWORD dwValue;
PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
DPRINT1("CDevSettings::SetPruningMode(%d)\n", PruningOn);
if (This->bModesPruned && !This->bKeyIsReadOnly &&
PruningOn != This->bPruningOn)
{
This->bPruningOn = (PruningOn != FALSE);
hKey = pCDevSettings_OpenDeviceKey(This,
FALSE);
if (hKey != NULL)
{
dwValue = (DWORD)This->bPruningOn;
RegSetValueEx(hKey,
TEXT("PruningMode"),
0,
REG_DWORD,
(const BYTE *)&dwValue,
sizeof(dwValue));
RegCloseKey(hKey);
}
}
}
static VOID
pCDevSettings_ReadHardwareInfo(HKEY hKey,
LPCTSTR lpValueName,
LPWSTR lpBuffer)
{
DWORD type = REG_BINARY;
DWORD size = 128 * sizeof(WCHAR);
RegQueryValueEx(hKey,
lpValueName,
NULL,
&type,
(PBYTE)lpBuffer,
&size);
}
static VOID
pCDevSettings_InitializeExtInterface(PCDevSettings This)
{
PDESK_EXT_INTERFACE Interface = &This->ExtInterface;
HKEY hKeyDev;
ZeroMemory(Interface,
sizeof(*Interface));
Interface->cbSize = sizeof(*Interface);
/* Initialize the callback table */
Interface->Context = impl_to_interface(This, IDataObject);
Interface->EnumAllModes = CDevSettings_EnumAllModes;
Interface->SetCurrentMode = CDevSettings_SetCurrentMode;
Interface->GetCurrentMode = CDevSettings_GetCurrentMode;
Interface->SetPruningMode = CDevSettings_SetPruningMode;
Interface->GetPruningMode = CDevSettings_GetPruningMode;
/* Read the HardwareInformation.* values from the registry key */
hKeyDev = pCDevSettings_OpenDeviceKey(This,
TRUE);
if (hKeyDev != NULL)
{
DWORD dwType, dwMemSize = 0;
DWORD dwSize = sizeof(dwMemSize);
if (RegQueryValueEx(hKeyDev,
TEXT("HardwareInformation.MemorySize"),
NULL,
&dwType,
(PBYTE)&dwMemSize,
&dwSize) == ERROR_SUCCESS &&
(dwType == REG_BINARY || dwType == REG_DWORD) &&
dwSize == sizeof(dwMemSize))
{
dwMemSize /= 1024;
if (dwMemSize > 1024)
{
dwMemSize /= 1024;
if (dwMemSize > 1024)
{
wsprintf(Interface->MemorySize,
_T("%u GB"),
dwMemSize / 1024);
}
else
{
wsprintf(Interface->MemorySize,
_T("%u MB"),
dwMemSize);
}
}
else
{
wsprintf(Interface->MemorySize,
_T("%u KB"),
dwMemSize);
}
}
pCDevSettings_ReadHardwareInfo(hKeyDev,
TEXT("HardwareInformation.ChipType"),
Interface->ChipType);
pCDevSettings_ReadHardwareInfo(hKeyDev,
TEXT("HardwareInformation.DacType"),
Interface->DacType);
pCDevSettings_ReadHardwareInfo(hKeyDev,
TEXT("HardwareInformation.AdapterString"),
Interface->AdapterString);
pCDevSettings_ReadHardwareInfo(hKeyDev,
TEXT("HardwareInformation.BiosString"),
Interface->BiosString);
RegCloseKey(hKeyDev);
}
}
static HRESULT
pCDevSettings_Initialize(PCDevSettings This,
PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo)
{
HKEY hKey;
This->Flags = 0;
This->StateFlags = DisplayDeviceInfo->DeviceStateFlags;
DPRINT1("This->StateFlags: %x\n", This->StateFlags);
/* Register clipboard formats */
This->cfExtInterface = RegisterClipboardFormat(TEXT("Desk.cpl extension interface"));
This->cfDisplayDevice = RegisterClipboardFormat(TEXT("Display Device"));
This->cfDisplayName = RegisterClipboardFormat(TEXT("Display Name"));
This->cfDisplayId = RegisterClipboardFormat(TEXT("Display ID"));
This->cfDisplayKey = RegisterClipboardFormat(TEXT("Display Key"));
This->cfDisplayStateFlags = RegisterClipboardFormat(TEXT("Display State Flags"));
This->cfMonitorName = RegisterClipboardFormat(TEXT("Monitor Name"));
This->cfMonitorDevice = RegisterClipboardFormat(TEXT("Monitor Device"));
This->cfMonitorId = RegisterClipboardFormat(TEXT("Monitor ID"));
This->cfPruningMode = RegisterClipboardFormat(TEXT("Pruning Mode"));
/* Copy the device name */
This->pDisplayDevice = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceName);
DPRINT1("This->pDisplayDevice: %ws\n", This->pDisplayDevice);
This->pDisplayName = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceDescription);
DPRINT1("This->pDisplayName: %ws\n", This->pDisplayName);
This->pDisplayKey = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceKey);
DPRINT1("This->pDisplayKey: %ws\n", This->pDisplayKey);
This->pDisplayId = pCDevSettings_GetDeviceInstanceId(This->pDisplayDevice);
DPRINT1("This->pDisplayId: %ws\n", This->pDisplayId);
This->pMonitorName = pCDevSettings_GetMonitorName(This->pDisplayDevice);
DPRINT1("This->pMonitorName: %ws\n", This->pMonitorName);
This->pMonitorDevice = pCDevSettings_GetMonitorDevice(This->pDisplayDevice);
DPRINT1("This->pMonitorDevice: %ws\n", This->pMonitorDevice);
This->pMonitorId = pCDevSettings_GetDeviceInstanceId( This->pMonitorDevice);
DPRINT1("This->pMonitorId: %ws\n", This->pMonitorId);
/* Check pruning mode */
This->bModesPruned = ((DisplayDeviceInfo->DeviceStateFlags & DISPLAY_DEVICE_MODESPRUNED) != 0);
hKey = pCDevSettings_OpenDeviceKey(This,
FALSE);
if (hKey == NULL)
{
hKey = pCDevSettings_OpenDeviceKey(This,
FALSE);
This->bKeyIsReadOnly = TRUE;
}
if (hKey != NULL)
{
DWORD dw = 0;
DWORD dwType, dwSize;
dwSize = sizeof(dw);
if (RegQueryValueEx(hKey,
TEXT("PruningMode"),
NULL,
&dwType,
(PBYTE)&dw,
&dwSize) == ERROR_SUCCESS)
{
if (dwType == REG_DWORD && dwSize == sizeof(dw))
This->bPruningOn = (dw != 0);
}
RegCloseKey(hKey);
}
/* Initialize the shell extension interface */
pCDevSettings_InitializeExtInterface(This);
return S_OK;
}
static VOID
pCDevSettings_Free(PCDevSettings This)
{
pCDevSettings_FreeString(&This->pDisplayDevice);
pCDevSettings_FreeString(&This->pDisplayName);
pCDevSettings_FreeString(&This->pDisplayKey);
pCDevSettings_FreeString(&This->pDisplayId);
pCDevSettings_FreeString(&This->pMonitorName);
pCDevSettings_FreeString(&This->pMonitorDevice);
pCDevSettings_FreeString(&This->pMonitorId);
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_QueryInterface(IDataObject* iface,
REFIID riid,
void** ppvObject)
{
PCDevSettings This = impl_from_IDataObject(iface);
*ppvObject = NULL;
if (IsEqualGUID(riid,
&IID_IUnknown) ||
IsEqualGUID(riid,
&IID_IDataObject))
{
*ppvObject = (PVOID)impl_to_interface(This, IDataObject);
return S_OK;
}
else
{
DPRINT1("CDevSettings::QueryInterface: Queried unknown interface\n");
}
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE
CDevSettings_AddRef(IDataObject* iface)
{
PCDevSettings This = impl_from_IDataObject(iface);
return (ULONG)InterlockedIncrement((PLONG)&This->ref);
}
static ULONG STDMETHODCALLTYPE
CDevSettings_Release(IDataObject* iface)
{
ULONG refs;
PCDevSettings This = impl_from_IDataObject(iface);
refs = (ULONG)InterlockedDecrement((PLONG)&This->ref);
if (refs == 0)
pCDevSettings_Free(This);
return refs;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_GetData(IDataObject* iface,
FORMATETC* pformatetcIn,
STGMEDIUM* pmedium)
{
static const WCHAR szEmpty[] = {0};
HRESULT hr;
PCWSTR pszRet = NULL;
PWSTR pszBuf;
PCDevSettings This = impl_from_IDataObject(iface);
ZeroMemory(pmedium,
sizeof(STGMEDIUM));
hr = IDataObject_QueryGetData(iface,
pformatetcIn);
if (SUCCEEDED(hr))
{
/* Return the reqested data back to the shell extension */
if (pformatetcIn->cfFormat == This->cfDisplayDevice)
{
pszRet = This->pDisplayDevice;
DPRINT1("CDevSettings::GetData returns display device %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfDisplayName)
{
pszRet = This->pDisplayName;
DPRINT1("CDevSettings::GetData returns display name %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfDisplayKey)
{
pszRet = This->pDisplayKey;
DPRINT1("CDevSettings::GetData returns display key %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfDisplayId)
{
pszRet = This->pDisplayId;
DPRINT1("CDevSettings::GetData returns display id %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfMonitorName)
{
pszRet = This->pMonitorName;
DPRINT1("CDevSettings::GetData returns monitor name %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfMonitorDevice)
{
pszRet = This->pMonitorDevice;
DPRINT1("CDevSettings::GetData returns monitor device %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfMonitorId)
{
pszRet = This->pMonitorId;
DPRINT1("CDevSettings::GetData returns monitor id %ws\n", pszRet);
}
else if (pformatetcIn->cfFormat == This->cfExtInterface)
{
PDESK_EXT_INTERFACE pIface;
pIface = GlobalAlloc(GPTR,
sizeof(*pIface));
if (pIface != NULL)
{
CopyMemory(pIface,
&This->ExtInterface,
sizeof(This->ExtInterface));
DPRINT1("CDevSettings::GetData returns the desk.cpl extension interface\n");
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = pIface;
return S_OK;
}
else
return E_OUTOFMEMORY;
}
else if (pformatetcIn->cfFormat == This->cfDisplayStateFlags)
{
PDWORD pdw;
pdw = GlobalAlloc(GPTR,
sizeof(*pdw));
if (pdw != NULL)
{
*pdw = This->StateFlags;
DPRINT1("CDevSettings::GetData returns the display state flags %x\n", This->StateFlags);
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = pdw;
return S_OK;
}
else
return E_OUTOFMEMORY;
}
else if (pformatetcIn->cfFormat == This->cfPruningMode)
{
PBYTE pb;
pb = GlobalAlloc(GPTR,
sizeof(*pb));
if (pb != NULL)
{
*pb = (This->bModesPruned && This->bPruningOn);
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = pb;
return S_OK;
}
else
return E_OUTOFMEMORY;
}
/* NOTE: This only returns null-terminated strings! */
if (pszRet == NULL)
pszRet = szEmpty;
pszBuf = GlobalAlloc(GPTR,
(_tcslen(pszRet) + 1) * sizeof(WCHAR));
if (pszBuf != NULL)
{
_tcscpy(pszBuf,
pszRet);
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = pszBuf;
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
return hr;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_GetDataHere(IDataObject* iface,
FORMATETC* pformatetc,
STGMEDIUM* pmedium)
{
ZeroMemory(pformatetc,
sizeof(*pformatetc));
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_QueryGetData(IDataObject* iface,
FORMATETC* pformatetc)
{
#if DEBUG
TCHAR szFormatName[255];
#endif
PCDevSettings This = impl_from_IDataObject(iface);
if (pformatetc->dwAspect != DVASPECT_CONTENT)
return DV_E_DVASPECT;
if (pformatetc->lindex != -1)
return DV_E_LINDEX;
if (!(pformatetc->tymed & TYMED_HGLOBAL))
return DV_E_TYMED;
/* Check if the requested data can be provided */
if (pformatetc->cfFormat == This->cfExtInterface ||
pformatetc->cfFormat == This->cfDisplayDevice ||
pformatetc->cfFormat == This->cfDisplayName ||
pformatetc->cfFormat == This->cfDisplayId ||
pformatetc->cfFormat == This->cfDisplayKey ||
pformatetc->cfFormat == This->cfDisplayStateFlags ||
pformatetc->cfFormat == This->cfMonitorDevice ||
pformatetc->cfFormat == This->cfMonitorName ||
pformatetc->cfFormat == This->cfMonitorId ||
pformatetc->cfFormat == This->cfPruningMode)
{
return S_OK;
}
#if DEBUG
else
{
if (GetClipboardFormatName(pformatetc->cfFormat,
szFormatName,
sizeof(szFormatName) / sizeof(szFormatName[0])))
{
DPRINT1("CDevSettings::QueryGetData(\"%ws\")\n", szFormatName);
}
else
{
DPRINT1("CDevSettings::QueryGetData(Format %u)\n", (unsigned int)pformatetc->cfFormat);
}
}
#endif
return DV_E_FORMATETC;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_GetCanonicalFormatEtc(IDataObject* iface,
FORMATETC* pformatectIn,
FORMATETC* pformatetcOut)
{
HRESULT hr;
DPRINT1("CDevSettings::GetCanonicalFormatEtc\n");
hr = IDataObject_QueryGetData(iface,
pformatectIn);
if (SUCCEEDED(hr))
{
CopyMemory(pformatetcOut,
pformatectIn,
sizeof(FORMATETC));
/* Make sure the data is target device independent */
if (pformatectIn->ptd == NULL)
hr = DATA_S_SAMEFORMATETC;
else
{
pformatetcOut->ptd = NULL;
hr = S_OK;
}
}
else
{
ZeroMemory(pformatetcOut,
sizeof(FORMATETC));
}
return hr;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_SetData(IDataObject* iface,
FORMATETC* pformatetc,
STGMEDIUM* pmedium,
BOOL fRelease)
{
DPRINT1("CDevSettings::SetData UNIMPLEMENTED\n");
return E_NOTIMPL;
}
static __inline VOID
pCDevSettings_FillFormatEtc(FORMATETC *pFormatEtc,
CLIPFORMAT cf)
{
pFormatEtc->cfFormat = cf;
pFormatEtc->ptd = NULL;
pFormatEtc->dwAspect = DVASPECT_CONTENT;
pFormatEtc->lindex = -1;
pFormatEtc->tymed = TYMED_HGLOBAL;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_EnumFormatEtc(IDataObject* iface,
DWORD dwDirection,
IEnumFORMATETC** ppenumFormatEtc)
{
HRESULT hr;
FORMATETC fetc[10];
PCDevSettings This = impl_from_IDataObject(iface);
*ppenumFormatEtc = NULL;
if (dwDirection == DATADIR_GET)
{
pCDevSettings_FillFormatEtc(&fetc[0],
This->cfExtInterface);
pCDevSettings_FillFormatEtc(&fetc[1],
This->cfDisplayDevice);
pCDevSettings_FillFormatEtc(&fetc[2],
This->cfDisplayName);
pCDevSettings_FillFormatEtc(&fetc[3],
This->cfDisplayId);
pCDevSettings_FillFormatEtc(&fetc[4],
This->cfDisplayKey);
pCDevSettings_FillFormatEtc(&fetc[5],
This->cfDisplayStateFlags);
pCDevSettings_FillFormatEtc(&fetc[6],
This->cfMonitorName);
pCDevSettings_FillFormatEtc(&fetc[7],
This->cfMonitorDevice);
pCDevSettings_FillFormatEtc(&fetc[8],
This->cfMonitorId);
pCDevSettings_FillFormatEtc(&fetc[9],
This->cfPruningMode);
hr = SHCreateStdEnumFmtEtc(sizeof(fetc) / sizeof(fetc[0]),
fetc,
ppenumFormatEtc);
}
else
hr = E_NOTIMPL;
return hr;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_DAdvise(IDataObject* iface,
FORMATETC* pformatetc,
DWORD advf,
IAdviseSink* pAdvSink,
DWORD* pdwConnection)
{
*pdwConnection = 0;
return OLE_E_ADVISENOTSUPPORTED;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_DUnadvise(IDataObject* iface,
DWORD dwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
static HRESULT STDMETHODCALLTYPE
CDevSettings_EnumDAdvise(IDataObject* iface,
IEnumSTATDATA** ppenumAdvise)
{
*ppenumAdvise = NULL;
return OLE_E_ADVISENOTSUPPORTED;
}
static const struct IDataObjectVtbl vtblIDataObject = {
CDevSettings_QueryInterface,
CDevSettings_AddRef,
CDevSettings_Release,
CDevSettings_GetData,
CDevSettings_GetDataHere,
CDevSettings_QueryGetData,
CDevSettings_GetCanonicalFormatEtc,
CDevSettings_SetData,
CDevSettings_EnumFormatEtc,
CDevSettings_DAdvise,
CDevSettings_DUnadvise,
CDevSettings_EnumDAdvise,
};
IDataObject *
CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo)
{
PCDevSettings This;
This = HeapAlloc(GetProcessHeap(),
0,
sizeof(*This));
if (This != NULL)
{
This->lpIDataObjectVtbl = &vtblIDataObject;
This->ref = 1;
if (SUCCEEDED(pCDevSettings_Initialize(This,
DisplayDeviceInfo)))
{
return impl_to_interface(This, IDataObject);
}
CDevSettings_Release(impl_to_interface(This, IDataObject));
}
return NULL;
}

View file

@ -114,7 +114,14 @@ BEGIN
WS_VSCROLL | WS_TABSTOP
CONTROL "",1813,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,
131,148,103,9
PUSHBUTTON "Ad&vanced...",IDC_SETTINGS_ADVANCED,306,165,56,14
PUSHBUTTON "Ad&vanced...",IDC_SETTINGS_ADVANCED,170,165,70,14
END
IDD_ADVANCED_GENERAL DIALOGEX DISCARDABLE 0, 0, 246, 204
STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "General"
FONT 8, "MS Shell Dlg"
BEGIN
END
IDR_PREVIEW_MENU MENU
@ -124,6 +131,13 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"
IDS_UNKNOWNMONITOR "(Unknown Monitor)"
IDS_ADVANCEDTITLEFMT "%s and %s"
END
STRINGTABLE
BEGIN
IDS_CPLNAME "Display"

View file

@ -22,6 +22,7 @@
#define IDD_APPEARANCE 102
#define IDD_SETTINGS 103
#define IDD_ADVAPPEARANCE 104
#define IDD_ADVANCED_GENERAL 200
/* Background Page */
#define IDC_BACKGROUND_LIST 1000
@ -145,6 +146,9 @@
#define IDS_ELEMENT_22 3222
#define IDS_ELEMENT_23 3223
#define IDS_MULTIPLEMONITORS 3300
#define IDS_UNKNOWNMONITOR 3301
#define IDS_ADVANCEDTITLEFMT 3302
#endif /* __CPL_DESK_RESOURCE_H__ */

View file

@ -10,37 +10,6 @@
#include "desk.h"
/* As slider control can't contain user data, we have to keep an
* array of RESOLUTION_INFO to have our own associated data.
*/
typedef struct _RESOLUTION_INFO
{
DWORD dmPelsWidth;
DWORD dmPelsHeight;
} RESOLUTION_INFO, *PRESOLUTION_INFO;
typedef struct _SETTINGS_ENTRY
{
struct _SETTINGS_ENTRY *Blink;
struct _SETTINGS_ENTRY *Flink;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
} SETTINGS_ENTRY, *PSETTINGS_ENTRY;
typedef struct _DISPLAY_DEVICE_ENTRY
{
struct _DISPLAY_DEVICE_ENTRY *Flink;
LPTSTR DeviceDescription;
LPTSTR DeviceName;
PSETTINGS_ENTRY Settings; /* sorted by increasing dmPelsHeight, BPP */
DWORD SettingsCount;
PRESOLUTION_INFO Resolutions;
DWORD ResolutionsCount;
PSETTINGS_ENTRY CurrentSettings; /* Points into Settings list */
SETTINGS_ENTRY InitialSettings;
} DISPLAY_DEVICE_ENTRY, *PDISPLAY_DEVICE_ENTRY;
typedef struct _GLOBAL_DATA
{
PDISPLAY_DEVICE_ENTRY DisplayDeviceList;
@ -76,7 +45,7 @@ UpdateDisplay(IN HWND hwndDlg, PGLOBAL_DATA pGlobalData, IN BOOL bUpdateThumb)
}
static PSETTINGS_ENTRY
GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTINGS_ENTRY* CurrentSettings)
GetPossibleSettings(IN LPCTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTINGS_ENTRY* CurrentSettings)
{
DEVMODE devmode;
DWORD NbSettings = 0;
@ -168,13 +137,14 @@ GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTIN
}
static BOOL
AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR DeviceName)
AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN const DISPLAY_DEVICE *DisplayDevice)
{
PDISPLAY_DEVICE_ENTRY newEntry = NULL;
LPTSTR description = NULL;
LPTSTR name = NULL;
DWORD descriptionSize;
DWORD nameSize;
LPTSTR key = NULL;
LPTSTR devid = NULL;
DWORD descriptionSize, nameSize, keySize, devidSize;
PSETTINGS_ENTRY Current;
DWORD ResolutionsCount = 1;
DWORD i;
@ -183,7 +153,7 @@ AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR D
memset(newEntry, 0, sizeof(DISPLAY_DEVICE_ENTRY));
if (!newEntry) goto ByeBye;
newEntry->Settings = GetPossibleSettings(DeviceName, &newEntry->SettingsCount, &newEntry->CurrentSettings);
newEntry->Settings = GetPossibleSettings(DisplayDevice->DeviceName, &newEntry->SettingsCount, &newEntry->CurrentSettings);
if (!newEntry->Settings) goto ByeBye;
newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
@ -219,18 +189,31 @@ AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR D
i++;
}
}
descriptionSize = (_tcslen(Description) + 1) * sizeof(TCHAR);
descriptionSize = (_tcslen(DisplayDevice->DeviceString) + 1) * sizeof(TCHAR);
description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
if (!description) goto ByeBye;
nameSize = (_tcslen(DeviceName) + 1) * sizeof(TCHAR);
nameSize = (_tcslen(DisplayDevice->DeviceName) + 1) * sizeof(TCHAR);
name = HeapAlloc(GetProcessHeap(), 0, nameSize);
if (!name) goto ByeBye;
memcpy(description, Description, descriptionSize);
memcpy(name, DeviceName, nameSize);
keySize = (_tcslen(DisplayDevice->DeviceKey) + 1) * sizeof(TCHAR);
key = HeapAlloc(GetProcessHeap(), 0, keySize);
if (!key) goto ByeBye;
devidSize = (_tcslen(DisplayDevice->DeviceID) + 1) * sizeof(TCHAR);
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 = pGlobalData->DisplayDeviceList;
pGlobalData->DisplayDeviceList = newEntry;
return TRUE;
@ -256,6 +239,10 @@ ByeBye:
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;
}
@ -307,11 +294,11 @@ OnInitDialog(IN HWND hwndDlg)
/* Get video cards list */
displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0))
while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0x1))
{
if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0)
{
if (AddDisplayDevice(pGlobalData, displayDevice.DeviceString, displayDevice.DeviceName))
if (AddDisplayDevice(pGlobalData, &displayDevice))
Result++;
}
iDevNum++;
@ -518,12 +505,6 @@ OnResolutionChanged(IN HWND hwndDlg, IN PGLOBAL_DATA pGlobalData, IN DWORD NewPo
/* we shouldn't go there */
}
static VOID
OnAdvancedButton()
{
MessageBox(NULL, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK);
}
/* Property page dialog callback */
INT_PTR CALLBACK
SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
@ -543,7 +524,7 @@ SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lPar
DWORD command = HIWORD(wParam);
if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
OnAdvancedButton();
DisplayAdvancedSettings(hwndDlg, pGlobalData->CurrentDisplayDevice);
else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
OnBPPChanged(hwndDlg, pGlobalData);
break;