using System; using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace RemoteView.PageHandlers { class ClickPageHandler : PageHandler { private Screen[] screens = Screen.AllScreens; /// /// Act upon clicks received from application. /// Input parsing is robust, trying to work even if problems are present in requesting string. /// /// server response /// tokenized URI /// public override byte[] handleRequest(HttpListenerResponse response, string[] uri) { // must have 5 tokens if (uri.Length != 6) { response.Redirect("/"); return Encoding.UTF8.GetBytes("Error..."); } int x, y; try { y = Convert.ToInt16(uri[4]); x = Convert.ToInt16(uri[5]); } catch { // parameter error, redirect to home response.Redirect("/"); return Encoding.UTF8.GetBytes("Error..."); } int screen = getRequestedScreenDevice(uri, screens); // check bounds Screen device = screens[screen]; if (x < 0 || x >= device.Bounds.Width || y < 0 || y >= device.Bounds.Height) { response.Redirect("/"); return Encoding.UTF8.GetBytes("Error..."); } // grab the first character switch (uri[3][0]) { case 'l': // left click ClickLeftMouseButton(x, y); break; case 'd': break; case 'r': ClickRightMouseButton(x, y); break; default: // error, redirect to home response.Redirect("/"); return Encoding.UTF8.GetBytes("Error..."); } // request a refresh by redirecting to the homepage response.Redirect("/home/" + screen); return Encoding.UTF8.GetBytes("Redirecting..."); } enum SystemMetric { SM_CXSCREEN = 0, SM_CYSCREEN = 1, } #region http://stackoverflow.com/questions/8021954/sendinput-doesnt-perform-click-mouse-button-unless-i-move-cursor [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)] struct HARDWAREINPUT { public int uMsg; public short wParamL; public short wParamH; } [StructLayout(LayoutKind.Sequential)] struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Explicit)] struct MouseKeybdhardwareInputUnion { [FieldOffset(0)] public MouseInputData mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] struct INPUT { public SendInputEventType type; public MouseKeybdhardwareInputUnion mkhi; } [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 } struct MouseInputData { public int dx; public int dy; public uint mouseData; public MouseEventFlags dwFlags; public uint time; public IntPtr dwExtraInfo; } int CalculateAbsoluteCoordinateX(int x) { return (x * 65536) / GetSystemMetrics(SystemMetric.SM_CXSCREEN); } int CalculateAbsoluteCoordinateY(int y) { return (y * 65536) / GetSystemMetrics(SystemMetric.SM_CYSCREEN); } public void ClickLeftMouseButton(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_LEFTDOWN; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; 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())); } #endregion } }