Display a context menu for the selected monitor

svn path=/trunk/; revision=29517
This commit is contained in:
Thomas Bluemel 2007-10-11 20:23:26 +00:00
parent 4ae5d0691a
commit 6f9c72878c
23 changed files with 494 additions and 17 deletions

View file

@ -34,6 +34,33 @@ APPLET Applets[NUM_APPLETS] =
}
};
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCTSTR lpMenuName)
{
HMENU hMenu, hSubMenu = NULL;
hMenu = LoadMenu(hInstance,
lpMenuName);
if (hMenu != NULL)
{
hSubMenu = GetSubMenu(hMenu,
0);
if (hSubMenu != NULL &&
!RemoveMenu(hMenu,
0,
MF_BYPOSITION))
{
hSubMenu = NULL;
}
DestroyMenu(hMenu);
}
return hSubMenu;
}
static BOOL CALLBACK
PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
{

View file

@ -35,6 +35,10 @@ typedef struct _DIBITMAP
extern HINSTANCE hApplet;
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCTSTR lpMenuName);
PDIBITMAP DibLoadImage(LPTSTR lpFilename);
VOID DibFreeImage(PDIBITMAP lpBitmap);

View file

@ -135,6 +135,18 @@ BEGIN
MENUITEM "Èçáðàíî", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -132,6 +132,18 @@ BEGIN
MENUITEM "Vybráno", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_CPLNAME "Obrazovka"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Ausgewählt", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Mehrere Monitore)"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -133,6 +133,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -138,6 +138,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -134,6 +134,18 @@ BEGIN
MENUITEM "Sélectionné", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Moniteurs multiples)"

View file

@ -132,6 +132,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Dipilih", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -133,6 +133,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -137,6 +137,18 @@ BEGIN
MENUITEM "Wybrany", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -131,6 +131,18 @@ BEGIN
MENUITEM "Âûáðàííàÿ", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -140,6 +140,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Viacero monitorov)"

View file

@ -134,6 +134,18 @@ BEGIN
MENUITEM "Selected", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Multiple Monitors)"

View file

@ -139,6 +139,18 @@ BEGIN
MENUITEM "Âèáðàíå", ID_MENU_SELECTED
END
IDM_MONITOR_MENU MENU
BEGIN
POPUP ""
BEGIN
MENUITEM "&Attached", ID_MENU_ATTACHED
MENUITEM "&Primary", ID_MENU_PRIMARY
MENUITEM SEPARATOR
MENUITEM "&Identify", ID_MENU_IDENTIFY
MENUITEM "P&roperties", ID_MENU_PROPERTIES
END
END
STRINGTABLE
BEGIN
IDS_MULTIPLEMONITORS "(Äåê³ëüêà ìîí³òîð³â)"

View file

@ -496,6 +496,32 @@ MonSelGetMonitorInfo(IN PMONITORSELWND infoPtr,
return FALSE;
}
static INT
MonSelGetMonitorRect(IN OUT PMONITORSELWND infoPtr,
IN INT Index,
OUT PRECT prc)
{
RECT rc, rcClient;
if (Index < 0 || Index >= infoPtr->MonitorsCount)
return -1;
if (!infoPtr->CanDisplay)
return 0;
MonSelRectToScreen(infoPtr,
&infoPtr->Monitors[Index].rc,
prc);
rcClient.left = rcClient.top = 0;
rcClient.right = infoPtr->ClientSize.cx;
rcClient.bottom = infoPtr->ClientSize.cy;
return IntersectRect(&rc,
&rcClient,
prc) != FALSE;
}
static BOOL
MonSelSetCurSelMonitor(IN OUT PMONITORSELWND infoPtr,
IN INT Index,
@ -568,7 +594,8 @@ MonSelCreate(IN OUT PMONITORSELWND infoPtr)
infoPtr->SelectionFrame.cx = infoPtr->SelectionFrame.cy = 4;
infoPtr->Margin.cx = infoPtr->Margin.cy = 20;
infoPtr->SelectedMonitor = -1;
infoPtr->ControlExStyle = MSLM_EX_ALLOWSELECTDISABLED;
infoPtr->ControlExStyle = MSLM_EX_ALLOWSELECTDISABLED | MSLM_EX_HIDENUMBERONSINGLE |
MSLM_EX_SELECTONRIGHTCLICK;
return;
}
@ -709,6 +736,10 @@ MonSelPaint(IN OUT PMONITORSELWND infoPtr,
DWORD Index;
RECT rc, rctmp;
INT iPrevBkMode;
BOOL bHideNumber;
bHideNumber = (infoPtr->ControlExStyle & MSLM_EX_HIDENUMBERS) ||
((infoPtr->MonitorsCount == 1) && (infoPtr->ControlExStyle & MSLM_EX_HIDENUMBERONSINGLE));
hbBk = GetSysColorBrush(COLOR_BACKGROUND);
hpFg = CreatePen(PS_SOLID,
@ -773,22 +804,25 @@ MonSelPaint(IN OUT PMONITORSELWND infoPtr,
-1,
-1);
hFont = MonSelGetMonitorFont(infoPtr,
hDC,
Index);
if (hFont != NULL)
if (!bHideNumber)
{
hPrevFont = SelectObject(hDC,
hFont);
hFont = MonSelGetMonitorFont(infoPtr,
hDC,
Index);
if (hFont != NULL)
{
hPrevFont = SelectObject(hDC,
hFont);
DrawText(hDC,
infoPtr->Monitors[Index].szCaption,
-1,
&rc,
DT_VCENTER | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);
DrawText(hDC,
infoPtr->Monitors[Index].szCaption,
-1,
&rc,
DT_VCENTER | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);
SelectObject(hDC,
hPrevFont);
SelectObject(hDC,
hPrevFont);
}
}
if (infoPtr->MonitorInfo[Index].Flags & MSL_MIF_DISABLED)
@ -813,6 +847,41 @@ MonSelPaint(IN OUT PMONITORSELWND infoPtr,
hbOldBk);
}
static VOID
MonSelContextMenu(IN OUT PMONITORSELWND infoPtr,
IN SHORT x,
IN SHORT y)
{
MONSL_MONNMBUTTONCLICKED nm;
INT Index;
if (!infoPtr->HasFocus)
SetFocus(infoPtr->hSelf);
nm.pt.x = x;
nm.pt.y = y;
Index = MonSelHitTest(infoPtr,
&nm.pt);
MonSelNotifyMonitor(infoPtr,
MSLN_RBUTTONUP,
Index,
(PMONSL_MONNMHDR)&nm);
/* Send a WM_CONTEXTMENU notification */
MapWindowPoints(infoPtr->hSelf,
NULL,
&nm.pt,
1);
SendMessage(infoPtr->hSelf,
WM_CONTEXTMENU,
(WPARAM)infoPtr->hSelf,
MAKELPARAM(nm.pt.x,
nm.pt.y));
}
static LRESULT CALLBACK
MonitorSelWndProc(IN HWND hwnd,
IN UINT uMsg,
@ -873,9 +942,16 @@ MonitorSelWndProc(IN HWND hwnd,
break;
}
case WM_RBUTTONDOWN:
{
if (!(infoPtr->ControlExStyle & MSLM_EX_SELECTONRIGHTCLICK))
break;
/* fall through */
}
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
{
INT Index;
POINT pt;
@ -902,6 +978,14 @@ MonitorSelWndProc(IN HWND hwnd,
break;
}
case WM_RBUTTONUP:
{
MonSelContextMenu(infoPtr,
(SHORT)LOWORD(lParam),
(SHORT)HIWORD(lParam));
break;
}
case WM_GETDLGCODE:
{
INT virtKey;
@ -1081,6 +1165,14 @@ MonitorSelWndProc(IN HWND hwnd,
break;
}
case MSLM_GETMONITORRECT:
{
Ret = (LRESULT)MonSelGetMonitorRect(infoPtr,
(INT)wParam,
(PRECT)lParam);
break;
}
case WM_CREATE:
{
infoPtr = (PMONITORSELWND) HeapAlloc(GetProcessHeap(),

View file

@ -4,6 +4,9 @@
/* Control extended styles */
#define MSLM_EX_ALLOWSELECTNONE 0x1
#define MSLM_EX_ALLOWSELECTDISABLED 0x2
#define MSLM_EX_HIDENUMBERONSINGLE 0x4
#define MSLM_EX_HIDENUMBERS 0x8
#define MSLM_EX_SELECTONRIGHTCLICK 0x10
/* MONSL_MONINFO Flags */
#define MSL_MIF_DISABLED 0x1
@ -24,6 +27,13 @@ typedef struct _MONSL_MONNMHDR
MONSL_MONINFO MonitorInfo;
} MONSL_MONNMHDR, *PMONSL_MONNMHDR;
typedef struct _MONSL_MONNMBUTTONCLICKED
{
/* Used with MSLN_MONITORCHANGING */
MONSL_MONNMHDR hdr;
POINT pt;
} MONSL_MONNMBUTTONCLICKED, *PMONSL_MONNMBUTTONCLICKED;
typedef struct _MONSL_MONNMMONITORCHANGING
{
/* Used with MSLN_MONITORCHANGING */
@ -52,7 +62,19 @@ typedef struct _MONSL_MONNMMONITORCHANGING
*
* lParam: PMONSL_MONNMHDR
*/
#define MSLN_MONITORCHANGED 101
#define MSLN_MONITORCHANGED 102
/*
* MSLN_RBUTTONUP
* This notification code is sent through WM_NOTIFY after the user did a
* right click on the control. If the control's extended style
* MSLM_EX_SELECTONRIGHTCLICK is set and the user clicked on a monitor,
* that monitor is selected and relevant notifications are sent before
* this notification is sent.
*
* lParam: PMONSL_MONNMBUTTONCLICKED
*/
#define MSLN_RBUTTONUP 103
/*
* MSLM_SETMONITORSINFO
@ -146,7 +168,15 @@ typedef struct _MONSL_MONNMMONITORCHANGING
* Allow deselecting a monitor by clicking into
* unused areas of the control.
* * MSLM_EX_ALLOWSELECTDISABLED
* Allow selecting disabled monitors
* Allow selecting disabled monitors.
* * MSLM_EX_HIDENUMBERONSINGLE
* Hides the monitor number if the control only
* displays one monitor.
* * MSLM_EX_HIDENUMBERS
* Does not show monitor numbers.
* * MSLM_EX_SELECTONRIGHTCLICK
* Selects a monitor when the user right clicks
* on it.
*
* Returns non-zero value if successful.
*/
@ -161,6 +191,20 @@ typedef struct _MONSL_MONNMMONITORCHANGING
*/
#define MSLM_GETEXSTYLE (WM_USER + 0x19)
/*
* MSLM_GETMONITORRECT
* wParam: INT
* Index of the monitor whose display rectangle is queried.
* lParam: PRECT
* Pointer to a RECT structure that receives the rectangle
* in coordinates relative to the control's client area.
*
* Returns a positive value if the rectangle is visible.
* Returns zero if the rectangle is invisible.
* Returns a negative value if the index is not valid.
*/
#define MSLM_GETMONITORRECT (WM_USER + 0x20)
BOOL RegisterMonitorSelectionControl(IN HINSTANCE hInstance);
VOID UnregisterMonitorSelectionControl(IN HINSTANCE hInstance);

View file

@ -71,6 +71,12 @@
#define ID_MENU_DISABLED 2102
#define ID_MENU_SELECTED 2103
#define IDM_MONITOR_MENU 2110
#define ID_MENU_ATTACHED 2111
#define ID_MENU_PRIMARY 2112
#define ID_MENU_IDENTIFY 2113
#define ID_MENU_PROPERTIES 2114
/* Settings Page */
#define IDS_PIXEL 2301

View file

@ -644,6 +644,106 @@ SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lPar
break;
}
case WM_CONTEXTMENU:
{
HWND hwndMonSel;
HMENU hPopup;
UINT uiCmd;
POINT pt, ptClient;
INT Index;
pt.x = (SHORT)LOWORD(lParam);
pt.y = (SHORT)HIWORD(lParam);
hwndMonSel = GetDlgItem(hwndDlg,
IDC_SETTINGS_MONSEL);
if ((HWND)wParam == hwndMonSel)
{
if (pt.x == -1 && pt.y == -1)
{
RECT rcMon;
Index = (INT)SendMessage(hwndMonSel,
MSLM_GETCURSEL,
0,
0);
if (Index >= 0 &&
(INT)SendMessage(hwndMonSel,
MSLM_GETMONITORRECT,
Index,
(LPARAM)&rcMon) > 0)
{
pt.x = rcMon.left + ((rcMon.right - rcMon.left) / 2);
pt.y = rcMon.top + ((rcMon.bottom - rcMon.top) / 2);
}
else
pt.x = pt.y = 0;
MapWindowPoints(hwndMonSel,
NULL,
&pt,
1);
}
else
{
ptClient = pt;
MapWindowPoints(NULL,
hwndMonSel,
&ptClient,
1);
Index = (INT)SendMessage(hwndMonSel,
MSLM_HITTEST,
(WPARAM)&ptClient,
0);
}
if (Index >= 0)
{
hPopup = LoadPopupMenu(hApplet,
MAKEINTRESOURCE(IDM_MONITOR_MENU));
if (hPopup != NULL)
{
/* FIXME: Enable/Disable menu items */
EnableMenuItem(hPopup,
ID_MENU_ATTACHED,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
EnableMenuItem(hPopup,
ID_MENU_PRIMARY,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
EnableMenuItem(hPopup,
ID_MENU_IDENTIFY,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
EnableMenuItem(hPopup,
ID_MENU_PROPERTIES,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
uiCmd = (UINT)TrackPopupMenu(hPopup,
TPM_RETURNCMD | TPM_RIGHTBUTTON,
pt.x,
pt.y,
0,
hwndDlg,
NULL);
switch (uiCmd)
{
case ID_MENU_ATTACHED:
case ID_MENU_PRIMARY:
case ID_MENU_IDENTIFY:
case ID_MENU_PROPERTIES:
/* FIXME: Implement */
break;
}
DestroyMenu(hPopup);
}
}
}
break;
}
case WM_DESTROY:
{
PDISPLAY_DEVICE_ENTRY Current = pGlobalData->DisplayDeviceList;