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 */