Author: weiden Date: Thu Sep 27 21:53:14 2007 New Revision: 29252
URL: http://svn.reactos.org/svn/reactos?rev=29252&view=rev Log: - Display a list of monitors if there's more than one monitor - Display a list of available refresh rates for the current mode
Modified: trunk/reactos/dll/win32/shellext/deskmon/deskmon.c trunk/reactos/dll/win32/shellext/deskmon/deskmon.h trunk/reactos/dll/win32/shellext/deskmon/lang/en-US.rc trunk/reactos/dll/win32/shellext/deskmon/resource.h
Modified: trunk/reactos/dll/win32/shellext/deskmon/deskmon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shellext/deskmon/... ============================================================================== --- trunk/reactos/dll/win32/shellext/deskmon/deskmon.c (original) +++ trunk/reactos/dll/win32/shellext/deskmon/deskmon.c Thu Sep 27 21:53:14 2007 @@ -5,26 +5,341 @@
static HINSTANCE hInstance;
+#if 0 +#ifdef UNICODE +typedef INT_PTR (WINAPI *PDEVICEPROPERTIES)(HWND,LPCWSTR,LPCWSTR,BOOL); +#define FUNC_DEVICEPROPERTIES "DevicePropertiesW" +#else +typedef INT_PTR (WINAPI *PDEVICEPROPERTIES)(HWND,LPCWSTR,LPCSTR,BOOL); +#define FUNC_DEVICEPROPERTIES "DevicePropertiesA" +#endif + +static VOID +ShowMonitorProperties(PDESKMONITOR This, + LPCTSTR lpDevice) +{ + HMODULE hDevMgr; + PDEVICEPROPERTIES pDeviceProperties; + + hDevMgr = LoadLibrary(TEXT("devmgr.dll")); + if (hDevMgr != NULL) + { + pDeviceProperties = (PDEVICEPROPERTIESW)GetProcAddress(hDevMgr, + FUNC_DEVICEPROPERTIES); + if (pDeviceProperties != NULL) + { + pDeviceProperties(This->hwndDlg, + NULL, + lpDevice, + FALSE); + } + + FreeLibrary(hDevMgr); + } +} +#endif + +static VOID +UpdateMonitorDialogControls(PDESKMONITOR This) +{ + PDEVMODEW lpCurrentMode, lpMode; + DWORD dwIndex = 0; + TCHAR szBuffer[64]; + BOOL bHasDef = FALSE; + INT i; + + /* Fill the refresh rate combo box */ + SendDlgItemMessage(This->hwndDlg, + IDC_REFRESHRATE, + CB_RESETCONTENT, + 0, + 0); + + lpCurrentMode = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context); + + do + { + lpMode = This->DeskExtInterface->EnumAllModes(This->DeskExtInterface->Context, + dwIndex++); + if (lpMode != NULL && + lpMode->dmBitsPerPel == lpCurrentMode->dmBitsPerPel && + lpMode->dmPelsWidth == lpCurrentMode->dmPelsWidth && + lpMode->dmPelsHeight == lpCurrentMode->dmPelsHeight) + { + /* We're only interested in refresh rates for the current resolution and color depth */ + + if (lpMode->dmDisplayFrequency <= 1) + { + /* Default hardware frequency */ + if (bHasDef) + continue; + + bHasDef = TRUE; + + if (!LoadString(hInstance, + IDS_USEDEFFRQUENCY, + szBuffer, + sizeof(szBuffer) / sizeof(szBuffer[0]))) + { + szBuffer[0] = TEXT('\0'); + } + } + else + { + TCHAR szFmt[64]; + + if (!LoadString(hInstance, + IDS_FREQFMT, + szFmt, + sizeof(szFmt) / sizeof(szFmt[0]))) + { + szFmt[0] = TEXT('\0'); + } + + _sntprintf(szBuffer, + sizeof(szBuffer) / sizeof(szBuffer[0]), + szFmt, + lpMode->dmDisplayFrequency); + } + + i = (INT)SendDlgItemMessage(This->hwndDlg, + IDC_REFRESHRATE, + CB_ADDSTRING, + 0, + (LPARAM)szBuffer); + if (i >= 0) + { + SendDlgItemMessage(This->hwndDlg, + IDC_REFRESHRATE, + CB_SETITEMDATA, + (WPARAM)lpMode, + 0); + + if (lpMode->dmDisplayFrequency == lpCurrentMode->dmDisplayFrequency) + { + SendDlgItemMessage(This->hwndDlg, + IDC_REFRESHRATE, + CB_SETCURSEL, + (WPARAM)i, + 0); + } + } + } + + } while (lpMode != NULL); + + /* FIXME: Update pruning mode controls */ + + /* FIXME: Enable/Disable properties button */ + EnableWindow(GetDlgItem(This->hwndDlg, + IDC_MONITORPROPERTIES), + FALSE); +} + static VOID InitMonitorDialog(PDESKMONITOR This) { - LPTSTR lpMonitorName; - - lpMonitorName = QueryDeskCplString(This->pdtobj, - RegisterClipboardFormat(DESK_EXT_MONITORNAME)); - if (lpMonitorName != NULL) - { + PDESKMONINFO pmi, pminext, *pmilink; + DISPLAY_DEVICE dd; + BOOL bRet; + INT i; + DWORD dwIndex = 0; + + /* Free all allocated monitors */ + pmi = This->Monitors; + This->Monitors = NULL; + while (pmi != NULL) + { + pminext = pmi->Next; + LocalFree((HLOCAL)pmi); + pmi = pminext; + } + + This->SelMonitor = NULL; + This->dwMonitorCount = 0; + + if (This->lpDisplayDevice != NULL) + LocalFree((HLOCAL)This->lpDisplayDevice); + + This->lpDisplayDevice = QueryDeskCplString(This->pdtobj, + RegisterClipboardFormat(DESK_EXT_DISPLAYDEVICE)); + + if (This->DeskExtInterface != NULL) + { + if (This->lpDisplayDevice != NULL) + { + /* Enumerate all monitors */ + pmilink = &This->Monitors; + + do + { + dd.cb = sizeof(dd); + bRet = EnumDisplayDevices(This->lpDisplayDevice, + dwIndex++, + &dd, + 0); + if (bRet) + { + pmi = LocalAlloc(LMEM_FIXED, + sizeof(*pmi)); + if (pmi != NULL) + { + CopyMemory(&pmi->dd, + &dd, + sizeof(dd)); + pmi->Next = NULL; + *pmilink = pmi; + pmilink = &pmi->Next; + + This->dwMonitorCount++; + } + } + } while (bRet); + } + + This->lpDevModeOnInit = This->DeskExtInterface->GetCurrentMode(This->DeskExtInterface->Context); + } + else + This->lpDevModeOnInit = NULL; + + /* Setup the UI depending on how many monitors are attached */ + if (This->dwMonitorCount == 0) + { + LPTSTR lpMonitorName; + + /* This is a fallback, let's hope that desk.cpl can provide us with a monitor name */ + lpMonitorName = QueryDeskCplString(This->pdtobj, + RegisterClipboardFormat(DESK_EXT_MONITORNAME)); + SetDlgItemText(This->hwndDlg, IDC_MONITORNAME, lpMonitorName);
- LocalFree((HLOCAL)lpMonitorName); - } + if (lpMonitorName != NULL) + LocalFree((HLOCAL)lpMonitorName); + } + else if (This->dwMonitorCount == 1) + { + This->SelMonitor = This->Monitors; + SetDlgItemText(This->hwndDlg, + IDC_MONITORNAME, + This->Monitors->dd.DeviceString); + } + else + { + SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_RESETCONTENT, + 0, + 0); + + pmi = This->Monitors; + while (pmi != NULL) + { + i = (INT)SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_ADDSTRING, + 0, + (LPARAM)pmi->dd.DeviceString); + if (i >= 0) + { + SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_SETITEMDATA, + (WPARAM)i, + (LPARAM)pmi); + + if (This->SelMonitor == NULL) + { + SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_SETCURSEL, + (WPARAM)i, + 0); + + This->SelMonitor = pmi; + } + } + + pmi = pmi->Next; + } + } + + /* Show/Hide controls */ + ShowWindow(GetDlgItem(This->hwndDlg, + IDC_MONITORNAME), + (This->dwMonitorCount <= 1 ? SW_SHOW : SW_HIDE)); + ShowWindow(GetDlgItem(This->hwndDlg, + IDC_MONITORLIST), + (This->dwMonitorCount > 1 ? SW_SHOW : SW_HIDE)); + + UpdateMonitorDialogControls(This); +} + +static LONG +ApplyMonitorChanges(PDESKMONITOR This) +{ + LONG lChangeRet;
if (This->DeskExtInterface != NULL) { - /* FIXME */ - } + /* 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; + } + } + + InitMonitorDialog(This); + + return PSNRET_INVALID_NOCHANGEPAGE; +} + +static VOID +ResetMonitorChanges(PDESKMONITOR This) +{ + if (This->DeskExtInterface != NULL && This->lpDevModeOnInit != NULL) + { + This->DeskExtInterface->SetCurrentMode(This->DeskExtInterface->Context, + This->lpDevModeOnInit); + } +} + +static BOOL +UpdateMonitorSelection(PDESKMONITOR This) +{ + INT i; + + if (This->dwMonitorCount <= 1) + return FALSE; + + i = (INT)SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_GETCURSEL, + 0, + 0); + if (i >= 0) + { + This->SelMonitor = (PDESKMONINFO)SendDlgItemMessage(This->hwndDlg, + IDC_MONITORLIST, + LB_GETITEMDATA, + (WPARAM)i, + 0); + } + else + This->SelMonitor = NULL; + + return TRUE; }
static INT_PTR CALLBACK @@ -60,9 +375,37 @@ { case IDC_MONITORPROPERTIES: break; + + case IDC_MONITORLIST: + if (HIWORD(wParam) == LBN_SELCHANGE) + { + if (UpdateMonitorSelection(This)) + UpdateMonitorDialogControls(This); + } + break; } - break; + + case WM_NOTIFY: + { + NMHDR *nmh = (NMHDR *)lParam; + + switch (nmh->code) + { + case PSN_APPLY: + { + SetWindowLong(hwndDlg, + DWL_MSGRESULT, + ApplyMonitorChanges(This)); + break; + } + + case PSN_RESET: + ResetMonitorChanges(This); + break; + } + break; + } }
return Ret; @@ -71,6 +414,8 @@ static VOID IDeskMonitor_Destroy(PDESKMONITOR This) { + PDESKMONINFO pmi, pminext; + if (This->pdtobj != NULL) { IDataObject_Release(This->pdtobj); @@ -81,6 +426,22 @@ { LocalFree((HLOCAL)This->DeskExtInterface); This->DeskExtInterface = NULL; + } + + if (This->lpDisplayDevice != NULL) + { + LocalFree((HLOCAL)This->lpDisplayDevice); + This->lpDisplayDevice = NULL; + } + + /* Free all monitors */ + pmi = This->Monitors; + This->Monitors = NULL; + while (pmi != NULL) + { + pminext = pmi->Next; + LocalFree((HLOCAL)pmi); + pmi = pminext; } }
Modified: trunk/reactos/dll/win32/shellext/deskmon/deskmon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shellext/deskmon/... ============================================================================== --- trunk/reactos/dll/win32/shellext/deskmon/deskmon.h (original) +++ trunk/reactos/dll/win32/shellext/deskmon/deskmon.h Thu Sep 27 21:53:14 2007 @@ -1,5 +1,11 @@ #ifndef __DESKMON__H #define __DESKMON__H + +typedef struct _DESKMONINFO +{ + DISPLAY_DEVICE dd; + struct _DESKMONINFO *Next; +} DESKMONINFO, *PDESKMONINFO;
typedef struct _DESKMONITOR { @@ -11,6 +17,11 @@ HWND hwndDlg; PDESK_EXT_INTERFACE DeskExtInterface; IDataObject *pdtobj; + LPTSTR lpDisplayDevice; + DWORD dwMonitorCount; + PDESKMONINFO Monitors; + PDESKMONINFO SelMonitor; + PDEVMODEW lpDevModeOnInit; } DESKMONITOR, *PDESKMONITOR;
extern LONG dll_refs;
Modified: trunk/reactos/dll/win32/shellext/deskmon/lang/en-US.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shellext/deskmon/... ============================================================================== --- trunk/reactos/dll/win32/shellext/deskmon/lang/en-US.rc (original) +++ trunk/reactos/dll/win32/shellext/deskmon/lang/en-US.rc Thu Sep 27 21:53:14 2007 @@ -7,6 +7,16 @@ BEGIN GROUPBOX "Monitor type", -1, 7, 3, 237, 52 LTEXT "", IDC_MONITORNAME, 40, 17, 190, 20, SS_NOPREFIX + LISTBOX IDC_MONITORLIST, 40, 13, 196, 30, WS_VSCROLL PUSHBUTTON "&Properties", IDC_MONITORPROPERTIES, 177, 35, 59, 14, WS_DISABLED + GROUPBOX "Monitor settings", IDS_MONITORSETTINGSGROUP, 7, 58, 237, 47 + LTEXT "&Screen refresh rate:", IDS_REFRESHRATELABEL, 13, 73, 225, 8 + COMBOBOX IDC_REFRESHRATE, 13, 85, 225, 200, WS_VSCROLL | CBS_DROPDOWNLIST | CBS_SORT END
+STRINGTABLE +BEGIN + IDS_USEDEFFRQUENCY "Use hardware default setting" + IDS_FREQFMT "%u Hertz" +END +
Modified: trunk/reactos/dll/win32/shellext/deskmon/resource.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shellext/deskmon/... ============================================================================== --- trunk/reactos/dll/win32/shellext/deskmon/resource.h (original) +++ trunk/reactos/dll/win32/shellext/deskmon/resource.h Thu Sep 27 21:53:14 2007 @@ -4,6 +4,13 @@ #define IDD_MONITOR 100
#define IDC_MONITORNAME 201 -#define IDC_MONITORPROPERTIES 202 +#define IDC_MONITORLIST 202 +#define IDC_MONITORPROPERTIES 203 +#define IDS_MONITORSETTINGSGROUP 204 +#define IDS_REFRESHRATELABEL 205 +#define IDC_REFRESHRATE 206 + +#define IDS_USEDEFFRQUENCY 101 +#define IDS_FREQFMT 102
#endif /* __RESOURCE__H */