using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.IO; using System.Net.Sockets; using System.Collections.Generic; namespace BigEyes.Server { public class UserCapture { [DllImport("user32.dll")] private static extern uint MapVirtualKey(uint uCode, uint uMapType); [DllImport("user32.dll")] private static extern IntPtr GetDesktopWindow(); [DllImport("gdi32.dll")] private static extern bool BitBlt(IntPtr hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,IntPtr hdcSrc,int nXSrc,int nYSrc,int dwRop); [DllImport("user32.dll")] private static extern int GetSystemMetrics(int nIndex); [DllImport("user32.dll")] private static extern uint SendInput(uint nInputs,ref INPUT input,int cbSize); [DllImport("user32.dll")] private static extern void SetCursorPos(int x, int y); private const int SM_CXSCREEN = 0; private const int SM_CYSCREEN = 1; private const uint MOUSEEVENTF_MOVE = 0x0001; private const uint MOUSEEVENTF_LEFTDOWN = 0x0002; private const uint MOUSEEVENTF_LEFTUP = 0x0004; private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; private const uint MOUSEEVENTF_RIGHTUP = 0x0010; private const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020; private const uint MOUSEEVENTF_MIDDLEUP = 0x0040; private const uint MOUSEEVENTF_WHEEL = 0x0800; private const uint MOUSEEVENTF_ABSOLUTE = 0x8000; private const uint KEYEVENTF_EXTENDEDKEY = 0x0001; private const uint KEYEVENTF_KEYUP = 0x0002; private const uint INPUT_MOUSE = 0; private const uint INPUT_KEYBOARD = 1; private const int SRCCOPY = 0xCC0020; struct MOUSE_INPUT { public uint dx; public uint dy; public uint mouseData; public uint dwFlags; public uint time; public uint dwExtraInfo; } struct KEYBD_INPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public uint dwExtraInfo; } [StructLayout(LayoutKind.Explicit)] struct INPUT { [FieldOffset(0)] public uint type; [FieldOffset(4)] public MOUSE_INPUT mi; [FieldOffset(4)] public KEYBD_INPUT ki; } private static byte[] _previousBitmapBytes = null; private int _scaleSize; public UserCapture(int scalesize) { _scaleSize = scalesize; } public void PressOrReleaseMouseButton(bool press, bool left, int x, int y) { INPUT input = new INPUT(); input.type = INPUT_MOUSE; input.mi.dx = (uint) x; input.mi.dy = (uint) y; input.mi.mouseData = 0; input.mi.dwFlags = 0; input.mi.time = 0; input.mi.dwExtraInfo = 0; if (left) { input.mi.dwFlags = press ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; } else { input.mi.dwFlags = press ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; } SendInput(1, ref input, Marshal.SizeOf(input)); } public void MoveMouse(int x, int y) { double w = GetSystemMetrics(SM_CXSCREEN); double h = GetSystemMetrics(SM_CYSCREEN); SetCursorPos((int)Math.Round((w/(double)_scaleSize) * (double)x,0),(int)Math.Round((h/((h * (double)_scaleSize) / w)) * (double)y,0)); } public void SendKeystroke(byte virtualKeyCode, bool keyDown, bool extendedKey) { INPUT input = new INPUT(); input.type = INPUT_KEYBOARD; input.ki.wVk = virtualKeyCode; input.ki.wScan = (byte)MapVirtualKey((uint) virtualKeyCode, 0); input.ki.dwExtraInfo = 0; input.ki.time = 0; if (!keyDown) { input.ki.dwFlags |= KEYEVENTF_KEYUP; } if (extendedKey) { input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; } SendInput(1, ref input, Marshal.SizeOf(input)); } private Bitmap GetDesktopBitmap() { Size desktopBitmapSize = new Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); Graphics graphic = Graphics.FromHwnd(GetDesktopWindow()); Bitmap memImage = new Bitmap(desktopBitmapSize.Width, desktopBitmapSize.Height, graphic); Graphics memGraphic = Graphics.FromImage(memImage); IntPtr dc1 = graphic.GetHdc(); IntPtr dc2 = memGraphic.GetHdc(); BitBlt(dc2, 0, 0, desktopBitmapSize.Width, desktopBitmapSize.Height, dc1, 0, 0, SRCCOPY); graphic.ReleaseHdc(dc1); memGraphic.ReleaseHdc(dc2); graphic.Dispose(); memGraphic.Dispose(); return memImage; } public byte[] GetDesktopBitmapBytes() { Bitmap currentBitmap = GetDesktopBitmap(); currentBitmap = new Bitmap(currentBitmap.GetThumbnailImage(_scaleSize,currentBitmap.Height * _scaleSize / currentBitmap.Width,null,IntPtr.Zero)); MemoryStream ms = new MemoryStream(); currentBitmap.Save(ms,ImageFormat.Jpeg); byte[] currentBitmapBytes = ms.ToArray(); ms.Close(); byte[] b = compBytes(_previousBitmapBytes, currentBitmapBytes); _previousBitmapBytes = currentBitmapBytes; return b; } private byte[] compBytes(byte[] old, byte[] now) { if (old == null) { byte[] b = new byte[now.Length + 1]; b[0] = 0; Array.Copy(now, 0, b, 1, now.Length); return b; } MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bool equality = true; int min = Math.Min(old.Length, now.Length); for (int i = 0; i < min; i++) { if (old[i] != now[i]) { bw.Write(i); bw.Write(now[i]); equality = false; } } if (equality) { return new byte[0]; } for (int i = min + 1; i < now.Length; i++) { bw.Write(i); bw.Write(now[i]); } if (ms.Length >= now.Length) { byte[] b = new byte[now.Length + 1]; b[0] = 0; Array.Copy(now, 0, b, 1, now.Length); return b; } else { System.Diagnostics.Debug.WriteLine("Partial image."); byte[] r = ms.ToArray(); byte[] b = new byte[r.Length + 1]; b[0] = 1; Array.Copy(r, 0, b, 1, r.Length); return b; } } } }