mirror of
https://github.com/reactos/reactos.git
synced 2024-08-04 10:30:59 +00:00
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:
parent
ad47c9b3a9
commit
3b6747e11c
187
reactos/dll/cpl/desk/advmon.c
Normal file
187
reactos/dll/cpl/desk/advmon.c
Normal 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;
|
||||||
|
}
|
|
@ -33,26 +33,66 @@ APPLET Applets[NUM_APPLETS] =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK
|
||||||
static VOID
|
PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
|
||||||
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
|
|
||||||
{
|
{
|
||||||
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
|
PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
|
||||||
psp->dwSize = sizeof(PROPSHEETPAGE);
|
if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
|
||||||
psp->dwFlags = PSP_DEFAULT;
|
{
|
||||||
psp->hInstance = hApplet;
|
ppsh->phpage[ppsh->nPages++] = hpage;
|
||||||
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
|
return TRUE;
|
||||||
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 */
|
/* Display Applet */
|
||||||
static LONG APIENTRY
|
static LONG APIENTRY
|
||||||
DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
|
DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PROPSHEETPAGE psp[4];
|
HPROPSHEETPAGE hpsp[MAX_DESK_PAGES];
|
||||||
PROPSHEETHEADER psh;
|
PROPSHEETHEADER psh;
|
||||||
|
HPSXA hpsxa;
|
||||||
TCHAR Caption[1024];
|
TCHAR Caption[1024];
|
||||||
|
LONG ret;
|
||||||
|
UINT i;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(lParam);
|
UNREFERENCED_PARAMETER(lParam);
|
||||||
UNREFERENCED_PARAMETER(wParam);
|
UNREFERENCED_PARAMETER(wParam);
|
||||||
|
@ -63,21 +103,41 @@ DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
|
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
|
||||||
psh.dwSize = sizeof(PROPSHEETHEADER);
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
||||||
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_PROPTITLE;
|
psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
|
||||||
psh.hwndParent = NULL;
|
psh.hwndParent = NULL;
|
||||||
psh.hInstance = hApplet;
|
psh.hInstance = hApplet;
|
||||||
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
|
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
|
||||||
psh.pszCaption = Caption;
|
psh.pszCaption = Caption;
|
||||||
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
|
psh.nPages = 0;
|
||||||
psh.nStartPage = 0;
|
psh.nStartPage = 0;
|
||||||
psh.ppsp = psp;
|
psh.phpage = hpsp;
|
||||||
|
|
||||||
InitPropSheetPage(&psp[0], IDD_BACKGROUND, (DLGPROC) BackgroundPageProc);
|
/* Allow shell extensions to replace the background page */
|
||||||
InitPropSheetPage(&psp[1], IDD_SCREENSAVER, (DLGPROC) ScreenSaverPageProc);
|
hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
|
||||||
InitPropSheetPage(&psp[2], IDD_APPEARANCE, (DLGPROC) AppearancePageProc);
|
|
||||||
InitPropSheetPage(&psp[3], IDD_SETTINGS, (DLGPROC) SettingsPageProc);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __CPL_DESK_H__
|
#ifndef __CPL_DESK_H__
|
||||||
#define __CPL_DESK_H__
|
#define __CPL_DESK_H__
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
|
@ -8,6 +9,9 @@
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <regstr.h>
|
||||||
|
#include <cplext.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
|
@ -37,7 +41,51 @@ INT AllocAndLoadString(LPTSTR *lpTarget,
|
||||||
HINSTANCE hInst,
|
HINSTANCE hInst,
|
||||||
UINT uID);
|
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__ */
|
#endif /* __CPL_DESK_H__ */
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,19 @@
|
||||||
<library>gdi32</library>
|
<library>gdi32</library>
|
||||||
<library>comctl32</library>
|
<library>comctl32</library>
|
||||||
<library>comdlg32</library>
|
<library>comdlg32</library>
|
||||||
|
<library>ole32</library>
|
||||||
<library>setupapi</library>
|
<library>setupapi</library>
|
||||||
<library>shell32</library>
|
<library>shell32</library>
|
||||||
<library>ntdll</library>
|
<library>ntdll</library>
|
||||||
<library>msimg32</library>
|
<library>msimg32</library>
|
||||||
<library>msvcrt</library>
|
<library>msvcrt</library>
|
||||||
|
<library>uuid</library>
|
||||||
|
<file>advmon.c</file>
|
||||||
<file>appearance.c</file>
|
<file>appearance.c</file>
|
||||||
<file>background.c</file>
|
<file>background.c</file>
|
||||||
<file>classinst.c</file>
|
<file>classinst.c</file>
|
||||||
<file>desk.c</file>
|
<file>desk.c</file>
|
||||||
|
<file>devsett.c</file>
|
||||||
<file>dibitmap.c</file>
|
<file>dibitmap.c</file>
|
||||||
<file>misc.c</file>
|
<file>misc.c</file>
|
||||||
<file>preview.c</file>
|
<file>preview.c</file>
|
||||||
|
|
910
reactos/dll/cpl/desk/devsett.c
Normal file
910
reactos/dll/cpl/desk/devsett.c
Normal 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;
|
||||||
|
}
|
|
@ -114,7 +114,14 @@ BEGIN
|
||||||
WS_VSCROLL | WS_TABSTOP
|
WS_VSCROLL | WS_TABSTOP
|
||||||
CONTROL "",1813,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,
|
CONTROL "",1813,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,
|
||||||
131,148,103,9
|
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
|
END
|
||||||
|
|
||||||
IDR_PREVIEW_MENU MENU
|
IDR_PREVIEW_MENU MENU
|
||||||
|
@ -124,6 +131,13 @@ BEGIN
|
||||||
MENUITEM "Selected", ID_MENU_SELECTED
|
MENUITEM "Selected", ID_MENU_SELECTED
|
||||||
END
|
END
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
IDS_MULTIPLEMONITORS "(Multiple Monitors)"
|
||||||
|
IDS_UNKNOWNMONITOR "(Unknown Monitor)"
|
||||||
|
IDS_ADVANCEDTITLEFMT "%s and %s"
|
||||||
|
END
|
||||||
|
|
||||||
STRINGTABLE
|
STRINGTABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_CPLNAME "Display"
|
IDS_CPLNAME "Display"
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define IDD_APPEARANCE 102
|
#define IDD_APPEARANCE 102
|
||||||
#define IDD_SETTINGS 103
|
#define IDD_SETTINGS 103
|
||||||
#define IDD_ADVAPPEARANCE 104
|
#define IDD_ADVAPPEARANCE 104
|
||||||
|
#define IDD_ADVANCED_GENERAL 200
|
||||||
|
|
||||||
/* Background Page */
|
/* Background Page */
|
||||||
#define IDC_BACKGROUND_LIST 1000
|
#define IDC_BACKGROUND_LIST 1000
|
||||||
|
@ -145,6 +146,9 @@
|
||||||
#define IDS_ELEMENT_22 3222
|
#define IDS_ELEMENT_22 3222
|
||||||
#define IDS_ELEMENT_23 3223
|
#define IDS_ELEMENT_23 3223
|
||||||
|
|
||||||
|
#define IDS_MULTIPLEMONITORS 3300
|
||||||
|
#define IDS_UNKNOWNMONITOR 3301
|
||||||
|
#define IDS_ADVANCEDTITLEFMT 3302
|
||||||
|
|
||||||
#endif /* __CPL_DESK_RESOURCE_H__ */
|
#endif /* __CPL_DESK_RESOURCE_H__ */
|
||||||
|
|
||||||
|
|
|
@ -10,37 +10,6 @@
|
||||||
|
|
||||||
#include "desk.h"
|
#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
|
typedef struct _GLOBAL_DATA
|
||||||
{
|
{
|
||||||
PDISPLAY_DEVICE_ENTRY DisplayDeviceList;
|
PDISPLAY_DEVICE_ENTRY DisplayDeviceList;
|
||||||
|
@ -76,7 +45,7 @@ UpdateDisplay(IN HWND hwndDlg, PGLOBAL_DATA pGlobalData, IN BOOL bUpdateThumb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PSETTINGS_ENTRY
|
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;
|
DEVMODE devmode;
|
||||||
DWORD NbSettings = 0;
|
DWORD NbSettings = 0;
|
||||||
|
@ -168,13 +137,14 @@ GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTIN
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
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;
|
PDISPLAY_DEVICE_ENTRY newEntry = NULL;
|
||||||
LPTSTR description = NULL;
|
LPTSTR description = NULL;
|
||||||
LPTSTR name = NULL;
|
LPTSTR name = NULL;
|
||||||
DWORD descriptionSize;
|
LPTSTR key = NULL;
|
||||||
DWORD nameSize;
|
LPTSTR devid = NULL;
|
||||||
|
DWORD descriptionSize, nameSize, keySize, devidSize;
|
||||||
PSETTINGS_ENTRY Current;
|
PSETTINGS_ENTRY Current;
|
||||||
DWORD ResolutionsCount = 1;
|
DWORD ResolutionsCount = 1;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
@ -183,7 +153,7 @@ AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR D
|
||||||
memset(newEntry, 0, sizeof(DISPLAY_DEVICE_ENTRY));
|
memset(newEntry, 0, sizeof(DISPLAY_DEVICE_ENTRY));
|
||||||
if (!newEntry) goto ByeBye;
|
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;
|
if (!newEntry->Settings) goto ByeBye;
|
||||||
|
|
||||||
newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
|
newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
|
||||||
|
@ -219,18 +189,31 @@ AddDisplayDevice(IN PGLOBAL_DATA pGlobalData, IN LPTSTR Description, IN LPTSTR D
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
descriptionSize = (_tcslen(Description) + 1) * sizeof(TCHAR);
|
descriptionSize = (_tcslen(DisplayDevice->DeviceString) + 1) * sizeof(TCHAR);
|
||||||
description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
|
description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
|
||||||
if (!description) goto ByeBye;
|
if (!description) goto ByeBye;
|
||||||
|
|
||||||
nameSize = (_tcslen(DeviceName) + 1) * sizeof(TCHAR);
|
nameSize = (_tcslen(DisplayDevice->DeviceName) + 1) * sizeof(TCHAR);
|
||||||
name = HeapAlloc(GetProcessHeap(), 0, nameSize);
|
name = HeapAlloc(GetProcessHeap(), 0, nameSize);
|
||||||
if (!name) goto ByeBye;
|
if (!name) goto ByeBye;
|
||||||
|
|
||||||
memcpy(description, Description, descriptionSize);
|
keySize = (_tcslen(DisplayDevice->DeviceKey) + 1) * sizeof(TCHAR);
|
||||||
memcpy(name, DeviceName, nameSize);
|
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->DeviceDescription = description;
|
||||||
newEntry->DeviceName = name;
|
newEntry->DeviceName = name;
|
||||||
|
newEntry->DeviceKey = key;
|
||||||
|
newEntry->DeviceID = devid;
|
||||||
|
newEntry->DeviceStateFlags = DisplayDevice->StateFlags;
|
||||||
newEntry->Flink = pGlobalData->DisplayDeviceList;
|
newEntry->Flink = pGlobalData->DisplayDeviceList;
|
||||||
pGlobalData->DisplayDeviceList = newEntry;
|
pGlobalData->DisplayDeviceList = newEntry;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -256,6 +239,10 @@ ByeBye:
|
||||||
HeapFree(GetProcessHeap(), 0, description);
|
HeapFree(GetProcessHeap(), 0, description);
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
HeapFree(GetProcessHeap(), 0, name);
|
HeapFree(GetProcessHeap(), 0, name);
|
||||||
|
if (key != NULL)
|
||||||
|
HeapFree(GetProcessHeap(), 0, key);
|
||||||
|
if (devid != NULL)
|
||||||
|
HeapFree(GetProcessHeap(), 0, devid);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,11 +294,11 @@ OnInitDialog(IN HWND hwndDlg)
|
||||||
|
|
||||||
/* Get video cards list */
|
/* Get video cards list */
|
||||||
displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
|
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 ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0)
|
||||||
{
|
{
|
||||||
if (AddDisplayDevice(pGlobalData, displayDevice.DeviceString, displayDevice.DeviceName))
|
if (AddDisplayDevice(pGlobalData, &displayDevice))
|
||||||
Result++;
|
Result++;
|
||||||
}
|
}
|
||||||
iDevNum++;
|
iDevNum++;
|
||||||
|
@ -518,12 +505,6 @@ OnResolutionChanged(IN HWND hwndDlg, IN PGLOBAL_DATA pGlobalData, IN DWORD NewPo
|
||||||
/* we shouldn't go there */
|
/* 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 */
|
/* Property page dialog callback */
|
||||||
INT_PTR CALLBACK
|
INT_PTR CALLBACK
|
||||||
SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
|
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);
|
DWORD command = HIWORD(wParam);
|
||||||
|
|
||||||
if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
|
if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
|
||||||
OnAdvancedButton();
|
DisplayAdvancedSettings(hwndDlg, pGlobalData->CurrentDisplayDevice);
|
||||||
else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
|
else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
|
||||||
OnBPPChanged(hwndDlg, pGlobalData);
|
OnBPPChanged(hwndDlg, pGlobalData);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue