Author: weiden
Date: Sat Sep 29 06:32:14 2007
New Revision: 29289
URL:
http://svn.reactos.org/svn/reactos?rev=29289&view=rev
Log:
Add a (not yet functional) control to allow the user to arrange the monitors
Added:
trunk/reactos/dll/cpl/desk/monslctl.c (with props)
trunk/reactos/dll/cpl/desk/monslctl.h (with props)
Modified:
trunk/reactos/dll/cpl/desk/desk.c
trunk/reactos/dll/cpl/desk/desk.rbuild
trunk/reactos/dll/cpl/desk/lang/en-US.rc
trunk/reactos/dll/cpl/desk/resource.h
trunk/reactos/dll/cpl/desk/settings.c
Modified: trunk/reactos/dll/cpl/desk/desk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/desk.c?rev=29…
==============================================================================
--- trunk/reactos/dll/cpl/desk/desk.c (original)
+++ trunk/reactos/dll/cpl/desk/desk.c Sat Sep 29 06:32:14 2007
@@ -15,10 +15,11 @@
static LONG APIENTRY DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK BackgroundPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
-extern INT_PTR CALLBACK ScreenSaverPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
-extern INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
-extern INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+INT_PTR CALLBACK BackgroundPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+INT_PTR CALLBACK ScreenSaverPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+UINT CALLBACK SettingsPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
HINSTANCE hApplet = 0;
@@ -47,7 +48,7 @@
}
static BOOL
-InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc)
+InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc, LPFNPSPCALLBACK
pfnCallback)
{
HPROPSHEETPAGE hPage;
PROPSHEETPAGE psp;
@@ -57,9 +58,12 @@
ZeroMemory(&psp, sizeof(psp));
psp.dwSize = sizeof(psp);
psp.dwFlags = PSP_DEFAULT;
+ if (pfnCallback != NULL)
+ psp.dwFlags |= PSP_USECALLBACK;
psp.hInstance = hApplet;
psp.pszTemplate = MAKEINTRESOURCE(idDlg);
psp.pfnDlgProc = DlgProc;
+ psp.pfnCallback = pfnCallback;
hPage = CreatePropertySheetPage(&psp);
if (hPage != NULL)
@@ -75,12 +79,13 @@
{
WORD idDlg;
DLGPROC DlgProc;
+ LPFNPSPCALLBACK Callback;
} PropPages[] =
{
- { IDD_BACKGROUND, BackgroundPageProc },
- { IDD_SCREENSAVER, ScreenSaverPageProc },
- { IDD_APPEARANCE, AppearancePageProc },
- { IDD_SETTINGS, SettingsPageProc },
+ { IDD_BACKGROUND, BackgroundPageProc, NULL },
+ { IDD_SCREENSAVER, ScreenSaverPageProc, NULL },
+ { IDD_APPEARANCE, AppearancePageProc, NULL },
+ { IDD_SETTINGS, SettingsPageProc, SettingsPageCallbackProc },
};
/* Display Applet */
@@ -126,7 +131,7 @@
continue;
}
- InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc);
+ InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc,
PropPages[i].Callback);
}
/* NOTE: Don;t call SHAddFromPropSheetExtArray here because this applet only allows
Modified: trunk/reactos/dll/cpl/desk/desk.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/desk.rbuild?r…
==============================================================================
--- trunk/reactos/dll/cpl/desk/desk.rbuild (original)
+++ trunk/reactos/dll/cpl/desk/desk.rbuild Sat Sep 29 06:32:14 2007
@@ -34,5 +34,6 @@
<file>screensaver.c</file>
<file>advappdlg.c</file>
<file>settings.c</file>
+ <file>monslctl.c</file>
<file>desk.rc</file>
</module>
Modified: trunk/reactos/dll/cpl/desk/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/lang/en-US.rc…
==============================================================================
--- trunk/reactos/dll/cpl/desk/lang/en-US.rc (original)
+++ trunk/reactos/dll/cpl/desk/lang/en-US.rc Sat Sep 29 06:32:14 2007
@@ -101,6 +101,8 @@
CAPTION "Settings"
FONT 8, "MS Shell Dlg"
BEGIN
+ LTEXT "Drag the monitor icons to mach the physical arrangement of your
monitors.",-1,3,3,240,10
+ CONTROL
"",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,16,240,82,WS_EX_CLIENTEDGE
LTEXT "&Display:",1820,3,100,30,8
LTEXT "<none>",IDC_SETTINGS_DEVICE,9,109,224,8
GROUPBOX "&Screen area",1818,3,120,115,43
Added: trunk/reactos/dll/cpl/desk/monslctl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/monslctl.c?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/monslctl.c (added)
+++ trunk/reactos/dll/cpl/desk/monslctl.c Sat Sep 29 06:32:14 2007
@@ -1,0 +1,790 @@
+#include <windows.h>
+#include "monslctl.h"
+
+static const TCHAR szMonitorSelWndClass[] = TEXT("MONITORSELWNDCLASS");
+
+typedef struct _MONSL_MON
+{
+ RECT rc;
+} MONSL_MON, *PMONSL_MON;
+
+typedef struct _MONITORSELWND
+{
+ HWND hSelf;
+ HWND hNotify;
+ HFONT hFont;
+ SIZE ClientSize;
+ DWORD UIState;
+ union
+ {
+ DWORD dwFlags;
+ struct
+ {
+ UINT Enabled : 1;
+ UINT HasFocus : 1;
+ UINT CanDisplay : 1;
+ };
+ };
+ DWORD MonitorsCount;
+ INT SelectedMonitor;
+ PMONSL_MONINFO MonitorInfo;
+ PMONSL_MON Monitors;
+ RECT rcExtent;
+ RECT rcMonitors;
+ POINT ScrollPos;
+ SIZE Margin;
+ SIZE SelectionFrame;
+} MONITORSELWND, *PMONITORSELWND;
+
+static HFONT
+MonSelChangeFont(IN OUT PMONITORSELWND infoPtr,
+ IN HFONT hFont,
+ IN BOOL Redraw)
+{
+ HFONT hOldFont = infoPtr->hFont;
+ infoPtr->hFont = hFont;
+
+ if (Redraw)
+ {
+ InvalidateRect(infoPtr->hSelf,
+ NULL,
+ TRUE);
+ }
+
+ return hOldFont;
+}
+
+static VOID
+MonSelRectToScreen(IN PMONITORSELWND infoPtr,
+ IN const RECT *prc,
+ OUT PRECT prcOnScreen)
+{
+ *prcOnScreen = *prc;
+ OffsetRect(prcOnScreen,
+ -infoPtr->ScrollPos.x,
+ -infoPtr->ScrollPos.y);
+}
+
+static VOID
+MonSelScreenToPt(IN PMONITORSELWND infoPtr,
+ IN const POINT *pptOnScreen,
+ OUT PPOINT ppt)
+{
+ ppt->x = pptOnScreen->x + infoPtr->ScrollPos.x;
+ ppt->y = pptOnScreen->y + infoPtr->ScrollPos.y;
+}
+
+static VOID
+MonSelMonInfoToRect(IN const MONSL_MONINFO *pMonInfo,
+ OUT PRECT prc)
+{
+ prc->left = pMonInfo->Position.x;
+ prc->top = pMonInfo->Position.y;
+ prc->right = pMonInfo->Position.x + pMonInfo->Size.cx;
+ prc->bottom = pMonInfo->Position.y + pMonInfo->Size.cy;
+}
+
+static INT
+MonSelHitTest(IN PMONITORSELWND infoPtr,
+ IN const POINT *ppt)
+{
+ POINT pt;
+ INT Index, Ret = -1;
+
+ if (infoPtr->CanDisplay)
+ {
+ MonSelScreenToPt(infoPtr,
+ ppt,
+ &pt);
+
+ for (Index = 0; Index < (INT)infoPtr->MonitorsCount; Index++)
+ {
+ if (PtInRect(&infoPtr->Monitors[Index].rc,
+ pt))
+ {
+ Ret = Index;
+ break;
+ }
+ }
+ }
+
+ return Ret;
+}
+
+static VOID
+MonSelUpdateExtent(IN OUT PMONITORSELWND infoPtr)
+{
+ DWORD Index;
+ RECT rcMonitor;
+
+ /* NOTE: This routine calculates the extent of all monitor coordinates.
+ These are not control coordinates! */
+ if (infoPtr->MonitorsCount > 0)
+ {
+ MonSelMonInfoToRect(&infoPtr->MonitorInfo[0],
+ &infoPtr->rcExtent);
+
+ for (Index = 1; Index < infoPtr->MonitorsCount; Index++)
+ {
+ MonSelMonInfoToRect(&infoPtr->MonitorInfo[Index],
+ &rcMonitor);
+
+ UnionRect(&infoPtr->rcExtent,
+ &infoPtr->rcExtent,
+ &rcMonitor);
+ }
+ }
+ else
+ {
+ ZeroMemory(&infoPtr->rcExtent,
+ sizeof(infoPtr->rcExtent));
+ }
+}
+
+static VOID
+MonSelScaleRectRelative(IN const RECT *prcBaseFrom,
+ IN const RECT *prcFrom,
+ IN const RECT *prcBaseTo,
+ OUT PRECT prcTo)
+{
+ SIZE BaseFrom, BaseTo, From;
+
+ BaseFrom.cx = prcBaseFrom->right - prcBaseFrom->left;
+ BaseFrom.cy = prcBaseFrom->bottom - prcBaseFrom->top;
+ BaseTo.cx = prcBaseTo->right - prcBaseTo->left;
+ BaseTo.cy = prcBaseTo->bottom - prcBaseTo->top;
+ From.cx = prcFrom->right - prcFrom->left;
+ From.cy = prcFrom->bottom - prcFrom->top;
+
+ prcTo->left = prcBaseTo->left + (((prcFrom->left - prcBaseFrom->left) *
BaseTo.cx) / BaseFrom.cx);
+ prcTo->top = prcBaseTo->top + (((prcFrom->top - prcBaseFrom->top) *
BaseTo.cy) / BaseFrom.cy);
+ prcTo->right = prcTo->left + ((From.cx * BaseTo.cx) / BaseFrom.cx);
+ prcTo->bottom = prcTo->top + ((From.cy * BaseTo.cy) / BaseFrom.cy);
+}
+
+static VOID
+ScaleRectSizeFit(IN const RECT *prcContainerRect,
+ IN OUT PRECT prcRectToScale)
+{
+ SIZE ContainerSize, RectSize;
+
+ ContainerSize.cx = prcContainerRect->right - prcContainerRect->left;
+ ContainerSize.cy = prcContainerRect->bottom - prcContainerRect->top;
+ RectSize.cx = prcRectToScale->right - prcRectToScale->left;
+ RectSize.cy = prcRectToScale->bottom - prcRectToScale->top;
+
+ if (((RectSize.cx * 0xFFF) / RectSize.cy) < ((ContainerSize.cx * 0xFFF) /
ContainerSize.cy))
+ {
+ RectSize.cx = (RectSize.cx * ((ContainerSize.cy * 0xFFF) / RectSize.cy)) /
0xFFF;
+ RectSize.cy = ContainerSize.cy;
+ }
+ else
+ {
+ RectSize.cy = (RectSize.cy * ((ContainerSize.cx * 0xFFF) / RectSize.cx)) /
0xFFF;
+ RectSize.cx = ContainerSize.cx;
+ }
+
+ prcRectToScale->right = prcRectToScale->left + RectSize.cx;
+ prcRectToScale->bottom = prcRectToScale->top + RectSize.cy;
+
+ OffsetRect(prcRectToScale,
+ prcContainerRect->left + ((ContainerSize.cx - RectSize.cx) / 2),
+ prcContainerRect->top + ((ContainerSize.cy - RectSize.cy) / 2));
+}
+
+static VOID
+MonSelRepaint(IN PMONITORSELWND infoPtr)
+{
+ RECT rc;
+
+ MonSelRectToScreen(infoPtr,
+ &infoPtr->rcMonitors,
+ &rc);
+ InvalidateRect(infoPtr->hSelf,
+ &rc,
+ TRUE);
+}
+
+static VOID
+MonSelRepaintMonitor(IN PMONITORSELWND infoPtr,
+ IN DWORD Index)
+{
+ RECT rc;
+
+ if (Index < infoPtr->MonitorsCount)
+ {
+ MonSelRectToScreen(infoPtr,
+ &infoPtr->Monitors[Index].rc,
+ &rc);
+ InvalidateRect(infoPtr->hSelf,
+ &rc,
+ TRUE);
+ }
+}
+
+static VOID
+MonSelRepaintSelected(IN PMONITORSELWND infoPtr)
+{
+ if (infoPtr->SelectedMonitor >= 0)
+ {
+ MonSelRepaintMonitor(infoPtr,
+ (DWORD)infoPtr->SelectedMonitor);
+ }
+}
+
+static VOID
+MonSelUpdateMonitorsInfo(IN OUT PMONITORSELWND infoPtr,
+ IN BOOL bRepaint)
+{
+ RECT rcExtSurface, rcExtDisplay;
+ DWORD Index;
+
+ /* Recalculate rcExtent */
+ MonSelUpdateExtent(infoPtr);
+
+ infoPtr-> CanDisplay = infoPtr->MonitorsCount != 0 &&
+ (infoPtr->ClientSize.cx > (2 * (infoPtr->Margin.cx +
infoPtr->SelectionFrame.cx))) &&
+ (infoPtr->ClientSize.cy > (2 * (infoPtr->Margin.cy +
infoPtr->SelectionFrame.cy)));
+
+ if (infoPtr->CanDisplay)
+ {
+ /* Calculate the rectangle on the control in which may be painted */
+ rcExtSurface.left = infoPtr->Margin.cx;
+ rcExtSurface.top = infoPtr->Margin.cy;
+ rcExtSurface.right = rcExtSurface.left + infoPtr->ClientSize.cx - (2 *
infoPtr->Margin.cx);
+ rcExtSurface.bottom = rcExtSurface.top + infoPtr->ClientSize.cy - (2 *
infoPtr->Margin.cy);
+
+ /* Calculate the rectangle on the control that is actually painted on */
+ rcExtDisplay.left = rcExtDisplay.top = 0;
+ rcExtDisplay.right = infoPtr->rcExtent.right - infoPtr->rcExtent.left;
+ rcExtDisplay.bottom = infoPtr->rcExtent.bottom - infoPtr->rcExtent.top;
+
+ ScaleRectSizeFit(&rcExtSurface,
+ &rcExtDisplay);
+
+ infoPtr->rcMonitors = rcExtDisplay;
+
+ /* Now that we know in which area all monitors are located,
+ calculate the monitors selection rectangles on the screen */
+
+ for (Index = 0; Index < infoPtr->MonitorsCount; Index++)
+ {
+ MonSelMonInfoToRect(&infoPtr->MonitorInfo[Index],
+ &rcExtDisplay);
+
+ MonSelScaleRectRelative(&infoPtr->rcExtent,
+ &rcExtDisplay,
+ &infoPtr->rcMonitors,
+ &infoPtr->Monitors[Index].rc);
+ }
+
+ if (bRepaint)
+ MonSelRepaint(infoPtr);
+ }
+ else if (bRepaint)
+ {
+ InvalidateRect(infoPtr->hSelf,
+ NULL,
+ TRUE);
+ }
+}
+
+static BOOL
+MonSelSetMonitorInfo(IN OUT PMONITORSELWND infoPtr,
+ IN DWORD dwMonitors,
+ IN const MONSL_MONINFO *MonitorsInfo)
+{
+ DWORD dwOldCount;
+ BOOL Ret = TRUE;
+
+ dwOldCount = infoPtr->MonitorsCount;
+
+ if (infoPtr->MonitorInfo != NULL)
+ {
+ LocalFree((HLOCAL)infoPtr->MonitorInfo);
+ infoPtr->MonitorInfo = NULL;
+
+ LocalFree((HLOCAL)infoPtr->Monitors);
+ infoPtr->Monitors = NULL;
+
+ infoPtr->MonitorsCount = 0;
+ }
+
+ if (dwMonitors != 0)
+ {
+ infoPtr->MonitorInfo = (PMONSL_MONINFO)LocalAlloc(LMEM_FIXED,
+ dwMonitors *
sizeof(MONSL_MONINFO));
+ if (infoPtr->MonitorInfo != NULL)
+ {
+ infoPtr->Monitors = (PMONSL_MON)LocalAlloc(LMEM_FIXED,
+ dwMonitors * sizeof(MONSL_MON));
+ if (infoPtr->Monitors != NULL)
+ {
+ CopyMemory(infoPtr->MonitorInfo,
+ MonitorsInfo,
+ dwMonitors * sizeof(MONSL_MONINFO));
+ ZeroMemory(infoPtr->Monitors,
+ dwMonitors * sizeof(MONSL_MON));
+
+ infoPtr->MonitorsCount = dwMonitors;
+
+ if (infoPtr->SelectedMonitor >= (INT)infoPtr->MonitorsCount)
+ infoPtr->SelectedMonitor = -1;
+ infoPtr->SelectedMonitor = 0;
+
+ MonSelUpdateMonitorsInfo(infoPtr,
+ TRUE);
+ }
+ else
+ {
+ LocalFree((HLOCAL)infoPtr->MonitorInfo);
+ infoPtr->MonitorInfo = NULL;
+
+ Ret = FALSE;
+ }
+ }
+ else
+ Ret = FALSE;
+ }
+
+ if (!Ret)
+ infoPtr->SelectedMonitor = -1;
+
+ if (!Ret || dwMonitors == 0)
+ {
+ InvalidateRect(infoPtr->hSelf,
+ NULL,
+ TRUE);
+ }
+
+ return Ret;
+}
+
+static DWORD
+MonSelGetMonitorInfo(IN PMONITORSELWND infoPtr,
+ IN DWORD dwMonitors,
+ IN OUT PMONSL_MONINFO MonitorsInfo)
+{
+ if (dwMonitors != 0)
+ {
+ if (dwMonitors > infoPtr->MonitorsCount)
+ dwMonitors = infoPtr->MonitorsCount;
+
+ CopyMemory(MonitorsInfo,
+ infoPtr->MonitorInfo,
+ dwMonitors * sizeof(MONSL_MONINFO));
+ return dwMonitors;
+ }
+ else
+ return infoPtr->MonitorsCount;
+}
+
+static BOOL
+MonSelSetCurSelMonitor(IN OUT PMONITORSELWND infoPtr,
+ IN INT Index)
+{
+ INT PrevSel;
+ BOOL Ret = FALSE;
+
+ if (Index == -1 || Index < (INT)infoPtr->MonitorsCount)
+ {
+ if (Index != infoPtr->SelectedMonitor)
+ {
+ PrevSel = infoPtr->SelectedMonitor;
+ infoPtr->SelectedMonitor = Index;
+
+ if (PrevSel >= 0)
+ {
+ MonSelRepaintMonitor(infoPtr,
+ PrevSel);
+ }
+
+ if (infoPtr->SelectedMonitor >= 0)
+ MonSelRepaintSelected(infoPtr);
+ }
+
+ Ret = TRUE;
+ }
+
+ return Ret;
+}
+
+static VOID
+MonSelCreate(IN OUT PMONITORSELWND infoPtr)
+{
+ infoPtr->SelectionFrame.cx = infoPtr->SelectionFrame.cy = 4;
+ infoPtr->Margin.cx = infoPtr->Margin.cy = 20;
+ infoPtr->SelectedMonitor = -1;
+ return;
+}
+
+static VOID
+MonSelDestroy(IN OUT PMONITORSELWND infoPtr)
+{
+ /* Free all monitors */
+ MonSelSetMonitorInfo(infoPtr,
+ 0,
+ NULL);
+}
+
+static VOID
+MonSelPaint(IN PMONITORSELWND infoPtr,
+ IN HDC hDC,
+ IN LPRECT prcUpdate)
+{
+ HBRUSH hbBk, hbOldBk;
+ HPEN hpFg, hpOldFg;
+ DWORD Index;
+ RECT rc;
+
+ hbBk = GetSysColorBrush(COLOR_BACKGROUND);
+ hpFg = CreatePen(PS_SOLID,
+ 0,
+ GetSysColor(COLOR_WINDOW));
+
+ hbOldBk = SelectObject(hDC,
+ hbBk);
+ hpOldFg = SelectObject(hDC,
+ hpFg);
+
+ for (Index = 0; Index < infoPtr->MonitorsCount; Index++)
+ {
+ MonSelRectToScreen(infoPtr,
+ &infoPtr->Monitors[Index].rc,
+ &rc);
+
+ if ((INT)Index == infoPtr->SelectedMonitor)
+ {
+ FillRect(hDC,
+ &rc,
+ (HBRUSH)(COLOR_HIGHLIGHT + 1));
+
+ if (infoPtr->HasFocus && !(infoPtr->UIState &
UISF_HIDEFOCUS))
+ {
+ DrawFocusRect(hDC,
+ &rc);
+ }
+ }
+
+ InflateRect(&rc,
+ -infoPtr->SelectionFrame.cx,
+ -infoPtr->SelectionFrame.cy);
+
+ Rectangle(hDC,
+ rc.left,
+ rc.top,
+ rc.right,
+ rc.bottom);
+ }
+
+ SelectObject(hDC,
+ hpOldFg);
+ SelectObject(hDC,
+ hbOldBk);
+}
+
+static LRESULT CALLBACK
+MonitorSelWndProc(IN HWND hwnd,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PMONITORSELWND infoPtr;
+ LRESULT Ret = 0;
+
+ infoPtr = (PMONITORSELWND)GetWindowLongPtrW(hwnd,
+ 0);
+
+ if (infoPtr == NULL && uMsg != WM_CREATE)
+ {
+ goto HandleDefaultMessage;
+ }
+
+ switch (uMsg)
+ {
+ case WM_PAINT:
+ case WM_PRINTCLIENT:
+ {
+ PAINTSTRUCT ps;
+ HDC hDC;
+
+ if (wParam != 0)
+ {
+ if (!GetUpdateRect(hwnd,
+ &ps.rcPaint,
+ TRUE))
+ {
+ break;
+ }
+ hDC = (HDC)wParam;
+ }
+ else
+ {
+ hDC = BeginPaint(hwnd,
+ &ps);
+ if (hDC == NULL)
+ {
+ break;
+ }
+ }
+
+ if (infoPtr->CanDisplay)
+ {
+ MonSelPaint(infoPtr,
+ hDC,
+ &ps.rcPaint);
+ }
+
+ if (wParam == 0)
+ {
+ EndPaint(hwnd,
+ &ps);
+ }
+ break;
+ }
+
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ {
+ INT Index;
+ POINT pt;
+
+ pt.x = (LONG)LOWORD(lParam);
+ pt.y = (LONG)HIWORD(lParam);
+
+ Index = MonSelHitTest(infoPtr,
+ &pt);
+ if (Index >= 0)
+ {
+ MonSelSetCurSelMonitor(infoPtr,
+ Index);
+ }
+
+ /* fall through */
+ }
+
+ case WM_MBUTTONDOWN:
+ {
+ if (!infoPtr->HasFocus)
+ SetFocus(hwnd);
+ break;
+ }
+
+ case WM_GETDLGCODE:
+ {
+ INT virtKey;
+
+ virtKey = (lParam != 0 ? (INT)((LPMSG)lParam)->wParam : 0);
+ switch (virtKey)
+ {
+ case VK_TAB:
+ {
+ /* change the UI status */
+ SendMessage(GetAncestor(hwnd,
+ GA_PARENT),
+ WM_CHANGEUISTATE,
+ MAKEWPARAM(UIS_INITIALIZE,
+ 0),
+ 0);
+ break;
+ }
+ }
+
+ Ret |= DLGC_WANTARROWS;
+ break;
+ }
+
+ case WM_SETFOCUS:
+ {
+ infoPtr->HasFocus = TRUE;
+ MonSelRepaintSelected(infoPtr);
+ break;
+ }
+
+ case WM_KILLFOCUS:
+ {
+ infoPtr->HasFocus = FALSE;
+ MonSelRepaintSelected(infoPtr);
+ break;
+ }
+
+ case WM_UPDATEUISTATE:
+ {
+ DWORD OldUIState = infoPtr->UIState;
+ switch (LOWORD(wParam))
+ {
+ case UIS_SET:
+ infoPtr->UIState |= HIWORD(wParam);
+ break;
+
+ case UIS_CLEAR:
+ infoPtr->UIState &= ~HIWORD(wParam);
+ break;
+ }
+
+ if (infoPtr->UIState != OldUIState)
+ MonSelRepaintSelected(infoPtr);
+ break;
+ }
+
+ case WM_SETFONT:
+ {
+ Ret = (LRESULT)MonSelChangeFont(infoPtr,
+ (HFONT)wParam,
+ (BOOL)LOWORD(lParam));
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ infoPtr->ClientSize.cx = LOWORD(lParam);
+ infoPtr->ClientSize.cy = HIWORD(lParam);
+
+ /* Don't let MonSelUpdateMonitorsInfo repaint the control
+ because this won't work properly in case the control
+ was sized down! */
+ MonSelUpdateMonitorsInfo(infoPtr,
+ FALSE);
+ InvalidateRect(infoPtr->hSelf,
+ NULL,
+ TRUE);
+ break;
+ }
+
+ case WM_GETFONT:
+ {
+ Ret = (LRESULT)infoPtr->hFont;
+ break;
+ }
+
+ case WM_ENABLE:
+ {
+ infoPtr->Enabled = ((BOOL)wParam != FALSE);
+ /* FIXME */
+ break;
+ }
+
+ case WM_STYLECHANGED:
+ {
+ if (wParam == GWL_STYLE)
+ {
+ unsigned int OldEnabled = infoPtr->Enabled;
+ infoPtr->Enabled = !(((LPSTYLESTRUCT)lParam)->styleNew &
WS_DISABLED);
+
+ if (OldEnabled != infoPtr->Enabled)
+ {
+ /* FIXME */
+ }
+ }
+ break;
+ }
+
+ case MSLM_SETMONITORINFO:
+ {
+ Ret = MonSelSetMonitorInfo(infoPtr,
+ (DWORD)wParam,
+ (const MONSL_MONINFO *)lParam);
+ break;
+ }
+
+ case MSLM_GETMONITORINFO:
+ {
+ Ret = MonSelGetMonitorInfo(infoPtr,
+ (DWORD)wParam,
+ (PMONSL_MONINFO)lParam);
+ break;
+ }
+
+ case MSLM_GETMONITORINFOCOUNT:
+ {
+ Ret = infoPtr->MonitorsCount;
+ break;
+ }
+
+ case MSLM_HITTEST:
+ {
+ Ret = MonSelHitTest(infoPtr,
+ (const POINT *)wParam);
+ break;
+ }
+
+ case WM_CREATE:
+ {
+ infoPtr = (PMONITORSELWND) HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(MONITORSELWND));
+ if (infoPtr == NULL)
+ {
+ Ret = (LRESULT)-1;
+ break;
+ }
+
+ ZeroMemory(infoPtr,
+ sizeof(MONITORSELWND));
+ infoPtr->hSelf = hwnd;
+ infoPtr->hNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
+ infoPtr->Enabled = !(((LPCREATESTRUCTW)lParam)->style &
WS_DISABLED);
+ infoPtr->UIState = SendMessage(hwnd,
+ WM_QUERYUISTATE,
+ 0,
+ 0);
+
+ SetWindowLongPtrW(hwnd,
+ 0,
+ (LONG_PTR)infoPtr);
+
+ MonSelCreate(infoPtr);
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ MonSelDestroy(infoPtr);
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ infoPtr);
+ SetWindowLongPtrW(hwnd,
+ 0,
+ (DWORD_PTR)NULL);
+ break;
+ }
+
+ default:
+ {
+HandleDefaultMessage:
+ Ret = DefWindowProcW(hwnd,
+ uMsg,
+ wParam,
+ lParam);
+ break;
+ }
+ }
+
+ return Ret;
+}
+
+BOOL
+RegisterMonitorSelectionControl(IN HINSTANCE hInstance)
+{
+ WNDCLASS wc = {0};
+
+ wc.style = CS_DBLCLKS;
+ wc.lpfnWndProc = MonitorSelWndProc;
+ wc.cbWndExtra = sizeof(PMONITORSELWND);
+ wc.hInstance = hInstance;
+ wc.hCursor = LoadCursorW(NULL,
+ (LPWSTR)IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
+ wc.lpszClassName = szMonitorSelWndClass;
+
+ return RegisterClass(&wc) != 0;
+}
+
+VOID
+UnregisterMonitorSelectionControl(IN HINSTANCE hInstance)
+{
+ UnregisterClassW(szMonitorSelWndClass,
+ hInstance);
+}
Propchange: trunk/reactos/dll/cpl/desk/monslctl.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/cpl/desk/monslctl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/monslctl.h?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/monslctl.h (added)
+++ trunk/reactos/dll/cpl/desk/monslctl.h Sat Sep 29 06:32:14 2007
@@ -1,0 +1,60 @@
+#ifndef __MONSLCTL__H
+#define __MONSLCTL__H
+
+/* MONSL_MONINFO Flags */
+#define MSL_MIF_DISABLED 0x1
+
+typedef struct _MONSL_MONINFO
+{
+ POINT Position;
+ SIZE Size;
+ DWORD Flags; /* MSL_MIF_* */
+ LPARAM lParam;
+} MONSL_MONINFO, *PMONSL_MONINFO;
+
+/*
+ * MSLM_SETMONITORINFO
+ * wParam: DWORD
+ * Count of MONSL_MONINFO structures provided as lParam.
+ * lParam: PMONSL_MONINFO
+ * Array of wParam MONSL_MONINFO structures.
+ *
+ * Returns non-zero value if successful.
+ */
+#define MSLM_SETMONITORINFO (WM_USER + 0x10)
+
+/*
+ * MSLM_GETMONITORINFO
+ * wParam: DWORD
+ * Length of MONSL_MONINFO array buffer provided in lParam.
+ * lParam: PMONSL_MONINFO
+ * Array of wParam MONSL_MONINFO structures
+ *
+ * Returns number of structures copied.
+ */
+#define MSLM_GETMONITORINFO (WM_USER + 0x11)
+
+/*
+ * MSLM_GETMONITORINFOCOUNT
+ * wParam: Ignored.
+ * lParam: Ignored.
+ *
+ * Returns number of monitors.
+ */
+#define MSLM_GETMONITORINFOCOUNT (WM_USER + 0x12)
+
+/*
+ * MSLM_HITTEST
+ * wParam: PPOINT
+ * Pointer to a POINT structure specifying the coordinates
+ * relative to the client area of the control.
+ * lParam: Ignored.
+ *
+ * Returns the index of the monitor at this point, or -1.
+ */
+#define MSLM_HITTEST (WM_USER + 0x13)
+
+BOOL RegisterMonitorSelectionControl(IN HINSTANCE hInstance);
+VOID UnregisterMonitorSelectionControl(IN HINSTANCE hInstance);
+
+#endif /* __MONSLCTL__H */
Propchange: trunk/reactos/dll/cpl/desk/monslctl.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/cpl/desk/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/resource.h?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/resource.h (original)
+++ trunk/reactos/dll/cpl/desk/resource.h Sat Sep 29 06:32:14 2007
@@ -64,6 +64,7 @@
#define IDC_SETTINGS_RESOLUTION 203
#define IDC_SETTINGS_RESOLUTION_TEXT 204
#define IDC_SETTINGS_ADVANCED 205
+#define IDC_SETTINGS_MONSEL 206
#define IDR_PREVIEW_MENU 2100
#define ID_MENU_NORMAL 2101
Modified: trunk/reactos/dll/cpl/desk/settings.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/desk/settings.c?re…
==============================================================================
--- trunk/reactos/dll/cpl/desk/settings.c (original)
+++ trunk/reactos/dll/cpl/desk/settings.c Sat Sep 29 06:32:14 2007
@@ -9,6 +9,7 @@
*/
#include "desk.h"
+#include "monslctl.h"
typedef struct _GLOBAL_DATA
{
@@ -503,6 +504,26 @@
}
/* we shouldn't go there */
+}
+
+/* Property sheet page callback */
+UINT CALLBACK
+SettingsPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
+{
+ UINT Ret = 0;
+
+ switch (uMsg)
+ {
+ case PSPCB_CREATE:
+ Ret = RegisterMonitorSelectionControl(hApplet);
+ break;
+
+ case PSPCB_RELEASE:
+ UnregisterMonitorSelectionControl(hApplet);
+ break;
+ }
+
+ return Ret;
}
/* Property page dialog callback */