- Allow changing the screen resolution in the advanced adapter settings through desk.cpl

- desk.cpl doesn't publish a monitor id

svn path=/trunk/; revision=29234
This commit is contained in:
Thomas Bluemel 2007-09-27 05:23:58 +00:00
parent 54ceb2a1f2
commit 81f8891b9b
6 changed files with 210 additions and 26 deletions

View file

@ -3,5 +3,6 @@ LIBRARY desk.cpl
EXPORTS
CPlApplet
DisplayClassInstaller
DisplaySaveSettings
; EOF

View file

@ -7,6 +7,8 @@
#include "desk.h"
#include <cfgmgr32.h>
#define NDEBUG
#include <debug.h>
@ -23,7 +25,6 @@ typedef struct _CDevSettings
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" */
@ -34,7 +35,6 @@ typedef struct _CDevSettings
PWSTR pDisplayId;
PWSTR pMonitorName;
PWSTR pMonitorDevice;
PWSTR pMonitorId;
DESK_EXT_INTERFACE ExtInterface;
@ -171,9 +171,47 @@ pCDevSettings_GetMonitorDevice(const WCHAR *pszDisplayDevice)
static PWSTR
pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice)
{
/* FIXME: Implement */
DEVINST DevInst;
CONFIGRET cr;
ULONG BufLen;
LPWSTR lpDevInstId = NULL;
DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice);
return NULL;
cr = CM_Locate_DevNodeW(&DevInst,
(DEVINSTID_W)pszDevice,
CM_LOCATE_DEVNODE_NORMAL);
if (cr == CR_SUCCESS)
{
DbgPrint("Success1\n");
cr = CM_Get_Device_ID_Size(&BufLen,
DevInst,
0);
if (cr == CR_SUCCESS)
{
DbgPrint("Success2\n");
lpDevInstId = LocalAlloc(LMEM_FIXED,
(BufLen + 1) * sizeof(WCHAR));
if (lpDevInstId != NULL)
{
DbgPrint("Success3\n");
cr = CM_Get_Device_IDW(DevInst,
lpDevInstId,
BufLen,
0);
if (cr != CR_SUCCESS)
{
LocalFree((HLOCAL)lpDevInstId);
lpDevInstId = NULL;
}
DbgPrint("instance id: %ws\n", lpDevInstId);
}
}
}
return lpDevInstId;
}
@ -401,7 +439,6 @@ pCDevSettings_Initialize(PCDevSettings This,
This->cfDisplayStateFlags = RegisterClipboardFormat(DESK_EXT_DISPLAYSTATEFLAGS);
This->cfMonitorName = RegisterClipboardFormat(DESK_EXT_MONITORNAME);
This->cfMonitorDevice = RegisterClipboardFormat(DESK_EXT_MONITORDEVICE);
This->cfMonitorId = RegisterClipboardFormat(DESK_EXT_MONITORID);
This->cfPruningMode = RegisterClipboardFormat(DESK_EXT_PRUNINGMODE);
/* Copy the device name */
@ -411,14 +448,12 @@ pCDevSettings_Initialize(PCDevSettings This,
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);
This->pDisplayId = pCDevSettings_GetDeviceInstanceId(DisplayDeviceInfo->DeviceID);
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);
@ -465,7 +500,6 @@ pCDevSettings_Free(PCDevSettings This)
pCDevSettings_FreeString(&This->pDisplayId);
pCDevSettings_FreeString(&This->pMonitorName);
pCDevSettings_FreeString(&This->pMonitorDevice);
pCDevSettings_FreeString(&This->pMonitorId);
}
static HRESULT STDMETHODCALLTYPE
@ -562,11 +596,6 @@ CDevSettings_GetData(IDataObject* iface,
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;
@ -688,7 +717,6 @@ CDevSettings_QueryGetData(IDataObject* iface,
pformatetc->cfFormat == This->cfDisplayStateFlags ||
pformatetc->cfFormat == This->cfMonitorDevice ||
pformatetc->cfFormat == This->cfMonitorName ||
pformatetc->cfFormat == This->cfMonitorId ||
pformatetc->cfFormat == This->cfPruningMode)
{
return S_OK;
@ -774,7 +802,7 @@ CDevSettings_EnumFormatEtc(IDataObject* iface,
IEnumFORMATETC** ppenumFormatEtc)
{
HRESULT hr;
FORMATETC fetc[10];
FORMATETC fetc[9];
PCDevSettings This = impl_from_IDataObject(iface);
*ppenumFormatEtc = NULL;
@ -798,8 +826,6 @@ CDevSettings_EnumFormatEtc(IDataObject* iface,
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]),
@ -877,3 +903,12 @@ CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo)
return NULL;
}
LONG WINAPI
DisplaySaveSettings(PVOID pContext,
HWND hwndPropSheet)
{
//PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
DPRINT("DisplaySaveSettings() UNIMPLEMENTED!\n");
return DISP_CHANGE_BADPARAM;
}

View file

@ -151,6 +151,38 @@ InitListAllModesDialog(PDESKDISPLAYADAPTER This,
}
}
static BOOL
ChangeSelectedMode(PDESKDISPLAYADAPTER This,
HWND hwndListAllModesDlg)
{
INT i;
PDEVMODEW lpSelDevMode = NULL;
BOOL bRet = FALSE;
i = (INT)SendDlgItemMessage(hwndListAllModesDlg,
IDC_ALLVALIDMODES,
LB_GETCURSEL,
0,
0);
if (i >= 0)
{
lpSelDevMode = (PDEVMODEW)SendDlgItemMessage(hwndListAllModesDlg,
IDC_ALLVALIDMODES,
LB_GETITEMDATA,
(WPARAM)i,
0);
}
if (lpSelDevMode != NULL)
{
This->lpSelDevMode = lpSelDevMode;
bRet = TRUE;
}
return bRet;
}
static INT_PTR CALLBACK
ListAllModesDlgProc(HWND hwndDlg,
UINT uMsg,
@ -183,7 +215,14 @@ ListAllModesDlgProc(HWND hwndDlg,
switch (LOWORD(wParam))
{
case IDOK:
if (ChangeSelectedMode(This,
hwndDlg))
{
EndDialog(hwndDlg,
IDOK);
}
break;
case IDCANCEL:
EndDialog(hwndDlg,
IDCANCEL);
@ -203,11 +242,25 @@ ListAllModesDlgProc(HWND hwndDlg,
static VOID
ShowListAllModes(PDESKDISPLAYADAPTER This)
{
DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_LISTALLMODES),
This->hwndDlg,
ListAllModesDlgProc,
(LPARAM)This);
PDEVMODEW lpPrevSel;
lpPrevSel = This->lpSelDevMode;
if (This->DeskExtInterface != NULL &&
DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_LISTALLMODES),
This->hwndDlg,
ListAllModesDlgProc,
(LPARAM)This) == IDOK)
{
if (lpPrevSel != This->lpSelDevMode)
{
(void)PropSheet_Changed(GetParent(This->hwndDlg),
This->hwndDlg);
This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
This->lpSelDevMode);
}
}
}
static VOID
@ -271,6 +324,49 @@ InitDisplayAdapterDialog(PDESKDISPLAYADAPTER This)
SetDlgItemTextW(This->hwndDlg,
IDC_BIOSINFORMATION,
This->DeskExtInterface->BiosString);
This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
}
else
This->lpDevModeOnInit = NULL;
This->lpSelDevMode = This->lpDevModeOnInit;
}
static LONG
ApplyDisplayAdapterChanges(PDESKDISPLAYADAPTER This)
{
LONG lChangeRet;
if (This->DeskExtInterface != NULL)
{
/* Change the display settings through desk.cpl */
lChangeRet = DeskCplExtDisplaySaveSettings(This->DeskExtInterface,
This->hwndDlg);
if (lChangeRet == DISP_CHANGE_SUCCESSFUL)
{
/* Save the new mode */
This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context);
return PSNRET_NOERROR;
}
else if (lChangeRet == DISP_CHANGE_RESTART)
{
/* Notify desk.cpl that the user needs to reboot */
PropSheet_RestartWindows(GetParent(This->hwndDlg));
return PSNRET_NOERROR;
}
}
return PSNRET_INVALID_NOCHANGEPAGE;
}
static VOID
ResetDisplayAdapterChanges(PDESKDISPLAYADAPTER This)
{
if (This->DeskExtInterface != NULL && This->lpDevModeOnInit != NULL)
{
This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context,
This->lpDevModeOnInit);
}
}
@ -315,6 +411,27 @@ DisplayAdapterDlgProc(HWND hwndDlg,
}
break;
case WM_NOTIFY:
{
NMHDR *nmh = (NMHDR *)lParam;
switch (nmh->code)
{
case PSN_APPLY:
{
SetWindowLong(hwndDlg,
DWL_MSGRESULT,
ApplyDisplayAdapterChanges(This));
break;
}
case PSN_RESET:
ResetDisplayAdapterChanges(This);
break;
}
break;
}
}
return Ret;

View file

@ -12,6 +12,8 @@ typedef struct _DESKDISPLAYADAPTER
PDESK_EXT_INTERFACE DeskExtInterface;
IDataObject *pdtobj;
LPTSTR lpDeviceId;
PDEVMODEW lpSelDevMode;
PDEVMODEW lpDevModeOnInit;
} DESKDISPLAYADAPTER, *PDESKDISPLAYADAPTER;
extern LONG dll_refs;
@ -54,7 +56,7 @@ IDeskDisplayAdapter_ReplacePage(PDESKDISPLAYADAPTER This,
LPFNADDPROPSHEETPAGE pfnReplacePage,
LPARAM lParam);
static const GUID CLSID_IDeskDisplayAdapter = {0x42071712,0x76d4,0x11d1,{0x8b,0x24,0x00,0xa0,0xc9,0x06,0x8f,0xf3}};
static const GUID CLSID_IDeskDisplayAdapter = {0x42071712,0x76d4,0x11d1,{0x8b,0x24,0x00,0xa0,0xc9,0x06,0x8f,0xf9}};
ULONG __cdecl DbgPrint(PCCH Format,...);

View file

@ -27,7 +27,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUPWINDOW | WS_VISIBLE | W
CAPTION "List All Modes"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK", IDOK, 112, 115, 50, 15, WS_DISABLED
DEFPUSHBUTTON "OK", IDOK, 112, 115, 50, 15
PUSHBUTTON "Cancel", IDCANCEL, 167, 115, 50, 15
GROUPBOX "List of valid modes", -1, 6, 7, 212, 98
LISTBOX IDC_ALLVALIDMODES, 10, 20, 204, 87, LBS_NOTIFY | WS_VSCROLL

View file

@ -12,7 +12,6 @@
#define DESK_EXT_DISPLAYSTATEFLAGS TEXT("Display State Flags")
#define DESK_EXT_MONITORNAME TEXT("Monitor Name")
#define DESK_EXT_MONITORDEVICE TEXT("Monitor Device")
#define DESK_EXT_MONITORID TEXT("Monitor ID")
typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_ENUMALLMODES)(PVOID Context, DWORD Index);
typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_GETCURRENTMODE)(PVOID Context);
@ -43,6 +42,8 @@ typedef struct _DESK_EXT_INTERFACE
WCHAR BiosString[128];
} DESK_EXT_INTERFACE, *PDESK_EXT_INTERFACE;
LONG WINAPI DisplaySaveSettings(PVOID pContext, HWND hwndPropSheet);
static PDESK_EXT_INTERFACE __inline
QueryDeskCplExtInterface(IDataObject *pdo)
{
@ -117,4 +118,32 @@ QueryDeskCplString(IDataObject *pdo, UINT cfFormat)
return lpStr;
}
static LONG __inline
DeskCplExtDisplaySaveSettings(PDESK_EXT_INTERFACE DeskExtInterface,
HWND hwndDlg)
{
typedef LONG (WINAPI *PDISPLAYSAVESETTINGS)(PVOID, HWND);
HMODULE hModDeskCpl;
PDISPLAYSAVESETTINGS pDisplaySaveSettings;
LONG lRet = DISP_CHANGE_BADPARAM;
/* We could use GetModuleHandle() instead, but then this routine
wouldn't work if some other application hosts the shell extension */
hModDeskCpl = LoadLibrary(TEXT("desk.cpl"));
if (hModDeskCpl != NULL)
{
pDisplaySaveSettings = (PDISPLAYSAVESETTINGS)GetProcAddress(hModDeskCpl,
"DisplaySaveSettings");
if (pDisplaySaveSettings != NULL)
{
lRet = pDisplaySaveSettings(DeskExtInterface->Context,
hwndDlg);
}
FreeLibrary(hModDeskCpl);
}
return lRet;
}
#endif /* __DESKCPLX__H */