diff --git a/reactos/dll/cpl/desk/desk.def b/reactos/dll/cpl/desk/desk.def index fdbb8869cfc..e34ffeaba4e 100644 --- a/reactos/dll/cpl/desk/desk.def +++ b/reactos/dll/cpl/desk/desk.def @@ -3,5 +3,6 @@ LIBRARY desk.cpl EXPORTS CPlApplet DisplayClassInstaller +DisplaySaveSettings ; EOF diff --git a/reactos/dll/cpl/desk/devsett.c b/reactos/dll/cpl/desk/devsett.c index eaed2db9871..a124826e72c 100644 --- a/reactos/dll/cpl/desk/devsett.c +++ b/reactos/dll/cpl/desk/devsett.c @@ -7,6 +7,8 @@ #include "desk.h" +#include + #define NDEBUG #include @@ -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; +} diff --git a/reactos/dll/win32/shellext/deskadp/deskadp.c b/reactos/dll/win32/shellext/deskadp/deskadp.c index ff696bbd815..013fe233919 100644 --- a/reactos/dll/win32/shellext/deskadp/deskadp.c +++ b/reactos/dll/win32/shellext/deskadp/deskadp.c @@ -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; diff --git a/reactos/dll/win32/shellext/deskadp/deskadp.h b/reactos/dll/win32/shellext/deskadp/deskadp.h index 601c4674a0a..e7b76f268bb 100644 --- a/reactos/dll/win32/shellext/deskadp/deskadp.h +++ b/reactos/dll/win32/shellext/deskadp/deskadp.h @@ -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,...); diff --git a/reactos/dll/win32/shellext/deskadp/lang/en-US.rc b/reactos/dll/win32/shellext/deskadp/lang/en-US.rc index 3731c639524..f20e91b9eb1 100644 --- a/reactos/dll/win32/shellext/deskadp/lang/en-US.rc +++ b/reactos/dll/win32/shellext/deskadp/lang/en-US.rc @@ -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 diff --git a/reactos/include/reactos/dll/desk/deskcplx.h b/reactos/include/reactos/dll/desk/deskcplx.h index 746664593b7..ed4d8f8880c 100644 --- a/reactos/include/reactos/dll/desk/deskcplx.h +++ b/reactos/include/reactos/dll/desk/deskcplx.h @@ -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 */