- 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 EXPORTS
CPlApplet CPlApplet
DisplayClassInstaller DisplayClassInstaller
DisplaySaveSettings
; EOF ; EOF

View file

@ -7,6 +7,8 @@
#include "desk.h" #include "desk.h"
#include <cfgmgr32.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -23,7 +25,6 @@ typedef struct _CDevSettings
CLIPFORMAT cfDisplayId; /* "Display ID" */ CLIPFORMAT cfDisplayId; /* "Display ID" */
CLIPFORMAT cfMonitorName; /* "Monitor Name" */ CLIPFORMAT cfMonitorName; /* "Monitor Name" */
CLIPFORMAT cfMonitorDevice; /* "Monitor Device" */ CLIPFORMAT cfMonitorDevice; /* "Monitor Device" */
CLIPFORMAT cfMonitorId; /* "Monitor ID" */
CLIPFORMAT cfDisplayKey; /* "Display Key" */ CLIPFORMAT cfDisplayKey; /* "Display Key" */
CLIPFORMAT cfDisplayStateFlags; /* "Display State Flags" */ CLIPFORMAT cfDisplayStateFlags; /* "Display State Flags" */
CLIPFORMAT cfPruningMode; /* "Pruning Mode" */ CLIPFORMAT cfPruningMode; /* "Pruning Mode" */
@ -34,7 +35,6 @@ typedef struct _CDevSettings
PWSTR pDisplayId; PWSTR pDisplayId;
PWSTR pMonitorName; PWSTR pMonitorName;
PWSTR pMonitorDevice; PWSTR pMonitorDevice;
PWSTR pMonitorId;
DESK_EXT_INTERFACE ExtInterface; DESK_EXT_INTERFACE ExtInterface;
@ -171,9 +171,47 @@ pCDevSettings_GetMonitorDevice(const WCHAR *pszDisplayDevice)
static PWSTR static PWSTR
pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice) pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice)
{ {
/* FIXME: Implement */ DEVINST DevInst;
CONFIGRET cr;
ULONG BufLen;
LPWSTR lpDevInstId = NULL;
DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice); 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->cfDisplayStateFlags = RegisterClipboardFormat(DESK_EXT_DISPLAYSTATEFLAGS);
This->cfMonitorName = RegisterClipboardFormat(DESK_EXT_MONITORNAME); This->cfMonitorName = RegisterClipboardFormat(DESK_EXT_MONITORNAME);
This->cfMonitorDevice = RegisterClipboardFormat(DESK_EXT_MONITORDEVICE); This->cfMonitorDevice = RegisterClipboardFormat(DESK_EXT_MONITORDEVICE);
This->cfMonitorId = RegisterClipboardFormat(DESK_EXT_MONITORID);
This->cfPruningMode = RegisterClipboardFormat(DESK_EXT_PRUNINGMODE); This->cfPruningMode = RegisterClipboardFormat(DESK_EXT_PRUNINGMODE);
/* Copy the device name */ /* Copy the device name */
@ -411,14 +448,12 @@ pCDevSettings_Initialize(PCDevSettings This,
DPRINT1("This->pDisplayName: %ws\n", This->pDisplayName); DPRINT1("This->pDisplayName: %ws\n", This->pDisplayName);
This->pDisplayKey = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceKey); This->pDisplayKey = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceKey);
DPRINT1("This->pDisplayKey: %ws\n", This->pDisplayKey); 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); DPRINT1("This->pDisplayId: %ws\n", This->pDisplayId);
This->pMonitorName = pCDevSettings_GetMonitorName(This->pDisplayDevice); This->pMonitorName = pCDevSettings_GetMonitorName(This->pDisplayDevice);
DPRINT1("This->pMonitorName: %ws\n", This->pMonitorName); DPRINT1("This->pMonitorName: %ws\n", This->pMonitorName);
This->pMonitorDevice = pCDevSettings_GetMonitorDevice(This->pDisplayDevice); This->pMonitorDevice = pCDevSettings_GetMonitorDevice(This->pDisplayDevice);
DPRINT1("This->pMonitorDevice: %ws\n", This->pMonitorDevice); DPRINT1("This->pMonitorDevice: %ws\n", This->pMonitorDevice);
This->pMonitorId = pCDevSettings_GetDeviceInstanceId( This->pMonitorDevice);
DPRINT1("This->pMonitorId: %ws\n", This->pMonitorId);
/* Check pruning mode */ /* Check pruning mode */
This->bModesPruned = ((DisplayDeviceInfo->DeviceStateFlags & DISPLAY_DEVICE_MODESPRUNED) != 0); This->bModesPruned = ((DisplayDeviceInfo->DeviceStateFlags & DISPLAY_DEVICE_MODESPRUNED) != 0);
@ -465,7 +500,6 @@ pCDevSettings_Free(PCDevSettings This)
pCDevSettings_FreeString(&This->pDisplayId); pCDevSettings_FreeString(&This->pDisplayId);
pCDevSettings_FreeString(&This->pMonitorName); pCDevSettings_FreeString(&This->pMonitorName);
pCDevSettings_FreeString(&This->pMonitorDevice); pCDevSettings_FreeString(&This->pMonitorDevice);
pCDevSettings_FreeString(&This->pMonitorId);
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
@ -562,11 +596,6 @@ CDevSettings_GetData(IDataObject* iface,
pszRet = This->pMonitorDevice; pszRet = This->pMonitorDevice;
DPRINT1("CDevSettings::GetData returns monitor device %ws\n", pszRet); 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) else if (pformatetcIn->cfFormat == This->cfExtInterface)
{ {
PDESK_EXT_INTERFACE pIface; PDESK_EXT_INTERFACE pIface;
@ -688,7 +717,6 @@ CDevSettings_QueryGetData(IDataObject* iface,
pformatetc->cfFormat == This->cfDisplayStateFlags || pformatetc->cfFormat == This->cfDisplayStateFlags ||
pformatetc->cfFormat == This->cfMonitorDevice || pformatetc->cfFormat == This->cfMonitorDevice ||
pformatetc->cfFormat == This->cfMonitorName || pformatetc->cfFormat == This->cfMonitorName ||
pformatetc->cfFormat == This->cfMonitorId ||
pformatetc->cfFormat == This->cfPruningMode) pformatetc->cfFormat == This->cfPruningMode)
{ {
return S_OK; return S_OK;
@ -774,7 +802,7 @@ CDevSettings_EnumFormatEtc(IDataObject* iface,
IEnumFORMATETC** ppenumFormatEtc) IEnumFORMATETC** ppenumFormatEtc)
{ {
HRESULT hr; HRESULT hr;
FORMATETC fetc[10]; FORMATETC fetc[9];
PCDevSettings This = impl_from_IDataObject(iface); PCDevSettings This = impl_from_IDataObject(iface);
*ppenumFormatEtc = NULL; *ppenumFormatEtc = NULL;
@ -798,8 +826,6 @@ CDevSettings_EnumFormatEtc(IDataObject* iface,
pCDevSettings_FillFormatEtc(&fetc[7], pCDevSettings_FillFormatEtc(&fetc[7],
This->cfMonitorDevice); This->cfMonitorDevice);
pCDevSettings_FillFormatEtc(&fetc[8], pCDevSettings_FillFormatEtc(&fetc[8],
This->cfMonitorId);
pCDevSettings_FillFormatEtc(&fetc[9],
This->cfPruningMode); This->cfPruningMode);
hr = SHCreateStdEnumFmtEtc(sizeof(fetc) / sizeof(fetc[0]), hr = SHCreateStdEnumFmtEtc(sizeof(fetc) / sizeof(fetc[0]),
@ -877,3 +903,12 @@ CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo)
return NULL; 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 static INT_PTR CALLBACK
ListAllModesDlgProc(HWND hwndDlg, ListAllModesDlgProc(HWND hwndDlg,
UINT uMsg, UINT uMsg,
@ -183,7 +215,14 @@ ListAllModesDlgProc(HWND hwndDlg,
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDOK: case IDOK:
if (ChangeSelectedMode(This,
hwndDlg))
{
EndDialog(hwndDlg,
IDOK);
}
break; break;
case IDCANCEL: case IDCANCEL:
EndDialog(hwndDlg, EndDialog(hwndDlg,
IDCANCEL); IDCANCEL);
@ -203,11 +242,25 @@ ListAllModesDlgProc(HWND hwndDlg,
static VOID static VOID
ShowListAllModes(PDESKDISPLAYADAPTER This) ShowListAllModes(PDESKDISPLAYADAPTER This)
{ {
DialogBoxParam(hInstance, PDEVMODEW lpPrevSel;
MAKEINTRESOURCE(IDD_LISTALLMODES),
This->hwndDlg, lpPrevSel = This->lpSelDevMode;
ListAllModesDlgProc,
(LPARAM)This); 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 static VOID
@ -271,6 +324,49 @@ InitDisplayAdapterDialog(PDESKDISPLAYADAPTER This)
SetDlgItemTextW(This->hwndDlg, SetDlgItemTextW(This->hwndDlg,
IDC_BIOSINFORMATION, IDC_BIOSINFORMATION,
This->DeskExtInterface->BiosString); 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; 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; return Ret;

View file

@ -12,6 +12,8 @@ typedef struct _DESKDISPLAYADAPTER
PDESK_EXT_INTERFACE DeskExtInterface; PDESK_EXT_INTERFACE DeskExtInterface;
IDataObject *pdtobj; IDataObject *pdtobj;
LPTSTR lpDeviceId; LPTSTR lpDeviceId;
PDEVMODEW lpSelDevMode;
PDEVMODEW lpDevModeOnInit;
} DESKDISPLAYADAPTER, *PDESKDISPLAYADAPTER; } DESKDISPLAYADAPTER, *PDESKDISPLAYADAPTER;
extern LONG dll_refs; extern LONG dll_refs;
@ -54,7 +56,7 @@ IDeskDisplayAdapter_ReplacePage(PDESKDISPLAYADAPTER This,
LPFNADDPROPSHEETPAGE pfnReplacePage, LPFNADDPROPSHEETPAGE pfnReplacePage,
LPARAM lParam); 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,...); 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" CAPTION "List All Modes"
FONT 8, "MS Shell Dlg", 0, 0, 0x0 FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN BEGIN
DEFPUSHBUTTON "OK", IDOK, 112, 115, 50, 15, WS_DISABLED DEFPUSHBUTTON "OK", IDOK, 112, 115, 50, 15
PUSHBUTTON "Cancel", IDCANCEL, 167, 115, 50, 15 PUSHBUTTON "Cancel", IDCANCEL, 167, 115, 50, 15
GROUPBOX "List of valid modes", -1, 6, 7, 212, 98 GROUPBOX "List of valid modes", -1, 6, 7, 212, 98
LISTBOX IDC_ALLVALIDMODES, 10, 20, 204, 87, LBS_NOTIFY | WS_VSCROLL 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_DISPLAYSTATEFLAGS TEXT("Display State Flags")
#define DESK_EXT_MONITORNAME TEXT("Monitor Name") #define DESK_EXT_MONITORNAME TEXT("Monitor Name")
#define DESK_EXT_MONITORDEVICE TEXT("Monitor Device") #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_ENUMALLMODES)(PVOID Context, DWORD Index);
typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_GETCURRENTMODE)(PVOID Context); typedef PDEVMODEW (DESK_EXT_CALLBACK *PDESK_EXT_GETCURRENTMODE)(PVOID Context);
@ -43,6 +42,8 @@ typedef struct _DESK_EXT_INTERFACE
WCHAR BiosString[128]; WCHAR BiosString[128];
} DESK_EXT_INTERFACE, *PDESK_EXT_INTERFACE; } DESK_EXT_INTERFACE, *PDESK_EXT_INTERFACE;
LONG WINAPI DisplaySaveSettings(PVOID pContext, HWND hwndPropSheet);
static PDESK_EXT_INTERFACE __inline static PDESK_EXT_INTERFACE __inline
QueryDeskCplExtInterface(IDataObject *pdo) QueryDeskCplExtInterface(IDataObject *pdo)
{ {
@ -117,4 +118,32 @@ QueryDeskCplString(IDataObject *pdo, UINT cfFormat)
return lpStr; 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 */ #endif /* __DESKCPLX__H */