Author: weiden
Date: Wed Sep 26 10:20:16 2007
New Revision: 29210
URL:
http://svn.reactos.org/svn/reactos?rev=29210&view=rev
Log:
Display advanced display settings and allow shell extensions to extend it. Not yet fully
functional/working
Added:
trunk/reactos/dll/cpl/desk/advmon.c (with props)
trunk/reactos/dll/cpl/desk/devsett.c (with props)
Modified:
trunk/reactos/dll/cpl/desk/desk.c
trunk/reactos/dll/cpl/desk/desk.h
trunk/reactos/dll/cpl/desk/desk.rbuild
trunk/reactos/dll/cpl/desk/lang/en-US.rc
trunk/reactos/dll/cpl/desk/resource.h
trunk/reactos/dll/cpl/desk/settings.c
Added: trunk/reactos/dll/cpl/desk/advmon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/advmon.c?rev=…
==============================================================================
--- trunk/reactos/dll/cpl/desk/advmon.c (added)
+++ trunk/reactos/dll/cpl/desk/advmon.c Wed Sep 26 10:20:16 2007
@@ -1,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;
+}
Propchange: trunk/reactos/dll/cpl/desk/advmon.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/cpl/desk/desk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/desk.c?rev=29…
==============================================================================
--- trunk/reactos/dll/cpl/desk/desk.c (original)
+++ trunk/reactos/dll/cpl/desk/desk.c Wed Sep 26 10:20:16 2007
@@ -33,26 +33,66 @@
}
};
+static BOOL CALLBACK
+PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
+{
+ PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
+ if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
+ {
+ ppsh->phpage[ppsh->nPages++] = hpage;
+ return TRUE;
+ }
-static VOID
-InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
-{
- ZeroMemory(psp, sizeof(PROPSHEETPAGE));
- psp->dwSize = sizeof(PROPSHEETPAGE);
- psp->dwFlags = PSP_DEFAULT;
- psp->hInstance = hApplet;
- psp->pszTemplate = MAKEINTRESOURCE(idDlg);
- psp->pfnDlgProc = DlgProc;
+ 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 @@
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;
}
Modified: trunk/reactos/dll/cpl/desk/desk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/desk.h?rev=29…
==============================================================================
--- trunk/reactos/dll/cpl/desk/desk.h (original)
+++ trunk/reactos/dll/cpl/desk/desk.h Wed Sep 26 10:20:16 2007
@@ -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 @@
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__ */
Modified: trunk/reactos/dll/cpl/desk/desk.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/desk.rbuild?r…
==============================================================================
--- trunk/reactos/dll/cpl/desk/desk.rbuild (original)
+++ trunk/reactos/dll/cpl/desk/desk.rbuild Wed Sep 26 10:20:16 2007
@@ -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>
Added: trunk/reactos/dll/cpl/desk/devsett.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/devsett.c?rev…
==============================================================================
--- trunk/reactos/dll/cpl/desk/devsett.c (added)
+++ trunk/reactos/dll/cpl/desk/devsett.c Wed Sep 26 10:20:16 2007
@@ -1,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;
+}
Propchange: trunk/reactos/dll/cpl/desk/devsett.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/cpl/desk/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/lang/en-US.rc…
==============================================================================
--- trunk/reactos/dll/cpl/desk/lang/en-US.rc (original)
+++ trunk/reactos/dll/cpl/desk/lang/en-US.rc Wed Sep 26 10:20:16 2007
@@ -114,7 +114,14 @@
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
@@ -122,6 +129,13 @@
MENUITEM "Normal", ID_MENU_NORMAL
MENUITEM "Disabled", ID_MENU_DISABLED
MENUITEM "Selected", ID_MENU_SELECTED
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MULTIPLEMONITORS "(Multiple Monitors)"
+ IDS_UNKNOWNMONITOR "(Unknown Monitor)"
+ IDS_ADVANCEDTITLEFMT "%s and %s"
END
STRINGTABLE
Modified: trunk/reactos/dll/cpl/desk/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/resource.h?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/resource.h (original)
+++ trunk/reactos/dll/cpl/desk/resource.h Wed Sep 26 10:20:16 2007
@@ -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__ */
Modified: trunk/reactos/dll/cpl/desk/settings.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/settings.c?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/settings.c (original)
+++ trunk/reactos/dll/cpl/desk/settings.c Wed Sep 26 10:20:16 2007
@@ -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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
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;