更新
上传的小样本项目展示效果。
http://www.mediafire.com/?du2jr18khx8ooy9
我想这一堆不同的方法,我发现这是由1对文本菜单来抵消HorizontalOffset最接近。这可以在ContextMenu打开时进行右键双击。由于ScrollViewer只收到第一次点击,所以当ContextMenu未打开时它仍然不起作用。
您可以通过使用您的计时代码进行第一次右键单击来解决此问题,并且如果在线程用完之前发生另一次右键单击,则可以使用SendInput模拟另一个鼠标右键单击。虽然可能不那么漂亮,但我可以完成这项工作。
<Canvas ...>
<Canvas.ContextMenu>
<ContextMenu Placement="RelativePoint" HorizontalOffset="1">
<MenuItem Header="MenuItem 1"/>
</ContextMenu>
</Canvas.ContextMenu>
代码背后
private bool m_waitingForRightMouseDoubleClick = false;
private void scrollViewer_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Right)
{
if (m_waitingForRightMouseDoubleClick == false)
{
m_waitingForRightMouseDoubleClick = true;
Thread thread = new Thread(new System.Threading.ThreadStart(delegate()
{
Thread.Sleep(System.Windows.Forms.SystemInformation.DoubleClickTime);
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(delegate()
{
m_waitingForRightMouseDoubleClick = false;
}
));
}));
thread.Start();
}
else
{
MouseSimulator.ClickRightMouseButton();
}
}
}
MouseSimulator.cs
public class MouseSimulator
{
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
public SendInputEventType type;
public MouseKeybdhardwareInputUnion mkhi;
}
[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdhardwareInputUnion
{
[FieldOffset(0)]
public MouseInputData mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
struct MouseInputData
{
public int dx;
public int dy;
public uint mouseData;
public MouseEventFlags dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[Flags]
enum MouseEventFlags : uint
{
MOUSEEVENTF_MOVE = 0x0001,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_MIDDLEUP = 0x0040,
MOUSEEVENTF_XDOWN = 0x0080,
MOUSEEVENTF_XUP = 0x0100,
MOUSEEVENTF_WHEEL = 0x0800,
MOUSEEVENTF_VIRTUALDESK = 0x4000,
MOUSEEVENTF_ABSOLUTE = 0x8000
}
enum SendInputEventType : int
{
InputMouse,
InputKeyboard,
InputHardware
}
public static void ClickRightMouseButton()
{
INPUT mouseDownInput = new INPUT();
mouseDownInput.type = SendInputEventType.InputMouse;
mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
INPUT mouseUpInput = new INPUT();
mouseUpInput.type = SendInputEventType.InputMouse;
mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
}
}
你为什么不忽略上下文菜单,使用弹出打造你想要的确切功能? – 2010-12-16 20:57:36
@Aaron:这没什么变化。问题依旧,上下文菜单或弹出... – serhio 2010-12-20 10:25:29