| |
| using System; |
| using System.Net; |
| using System.Runtime.InteropServices; |
| using System.Windows.Forms; |
| |
| namespace RemoteView.PageHandlers |
| { |
| |
| /// <summary> |
| /// This class is heavily based on source code presented as an answer at |
| /// http://stackoverflow.com/questions/8021954/sendinput-doesnt-perform-click-mouse-button-unless-i-move-cursor |
| /// </summary> |
| abstract class AbstractClickPageHandler : AbstractPageHandler |
| { |
| enum SystemMetric |
| { |
| SM_CXSCREEN = 0, |
| SM_CYSCREEN = 1, |
| } |
| |
| [DllImport("user32.dll")] |
| static extern int GetSystemMetrics(SystemMetric smIndex); |
| |
| [DllImport("user32.dll", SetLastError = true)] |
| static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); |
| |
| [StructLayout(LayoutKind.Sequential)] |
| public struct HARDWAREINPUT |
| { |
| public int uMsg; |
| public short wParamL; |
| public short wParamH; |
| } |
| |
| [StructLayout(LayoutKind.Sequential)] |
| public struct KEYBDINPUT |
| { |
| public ushort wVk; |
| public ushort wScan; |
| public uint dwFlags; |
| public uint time; |
| public IntPtr dwExtraInfo; |
| } |
| |
| [StructLayout(LayoutKind.Explicit)] |
| public struct MouseKeybdhardwareInputUnion |
| { |
| [FieldOffset(0)] |
| public MouseInputData mi; |
| |
| [FieldOffset(0)] |
| public KEYBDINPUT ki; |
| |
| [FieldOffset(0)] |
| public HARDWAREINPUT hi; |
| } |
| |
| [StructLayout(LayoutKind.Sequential)] |
| public struct INPUT |
| { |
| public SendInputEventType type; |
| public MouseKeybdhardwareInputUnion mkhi; |
| } |
| |
| [Flags] |
| public 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 |
| } |
| |
| public enum SendInputEventType : int |
| { |
| InputMouse, |
| InputKeyboard, |
| InputHardware |
| } |
| |
| public struct MouseInputData |
| { |
| public int dx; |
| public int dy; |
| public uint mouseData; |
| public MouseEventFlags dwFlags; |
| public uint time; |
| public IntPtr dwExtraInfo; |
| } |
| |
| public int CalculateAbsoluteCoordinateX(int x) |
| { |
| return (x * 65536) / GetSystemMetrics(SystemMetric.SM_CXSCREEN); |
| } |
| |
| public int CalculateAbsoluteCoordinateY(int y) |
| { |
| return (y * 65536) / GetSystemMetrics(SystemMetric.SM_CYSCREEN); |
| } |
| |
| public void LeftMouseButton(MouseEventFlags mouseEventFlags, int x, int y) |
| { |
| INPUT mouseInput = new INPUT(); |
| mouseInput.type = SendInputEventType.InputMouse; |
| mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x); |
| mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y); |
| mouseInput.mkhi.mi.mouseData = 0; |
| |
| mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE | MouseEventFlags.MOUSEEVENTF_ABSOLUTE; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| |
| mouseInput.mkhi.mi.dwFlags = mouseEventFlags; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| } |
| |
| public void ClickRightMouseButton(int x, int y) |
| { |
| INPUT mouseInput = new INPUT(); |
| mouseInput.type = SendInputEventType.InputMouse; |
| mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x); |
| mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y); |
| mouseInput.mkhi.mi.mouseData = 0; |
| |
| mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE | MouseEventFlags.MOUSEEVENTF_ABSOLUTE; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| |
| mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| |
| mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| } |
| |
| public void MoveMouse(int x, int y) |
| { |
| INPUT mouseInput = new INPUT(); |
| mouseInput.type = SendInputEventType.InputMouse; |
| mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x); |
| mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y); |
| mouseInput.mkhi.mi.mouseData = 0; |
| |
| mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE | MouseEventFlags.MOUSEEVENTF_ABSOLUTE; |
| SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); |
| |
| } |
| } |
| } |