namespace WindowsHookForm { using System; using System.Diagnostics; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct Point { public int X; public int Y; } [StructLayout(LayoutKind.Sequential)] public struct MouseLowLevelHookStruct { public Point MousePoint; public int MouseData; public int Flags; public int TimeStamp; public UIntPtr ExtraInfo; } public enum MouseMessageId { LeftButtonDown = 0x0201, LeftButtonUp = 0x0202, MouseMove = 0x0200, MouseWheel = 0x020A, MouseHorizWheel = 0x020E, RightButtonDown = 0x0204, RightButtonUp = 0x0205 } public delegate void MouseEventHandler( object sender, MouseLowLevelHookEventArgs e); public class MouseHookManager : IDisposable { private const int WhMouseLowLevel = 14; private readonly HookProc _mouseHookProcDelegate; private readonly IntPtr _mouseHook = IntPtr.Zero; private bool _disposed; private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam); public event MouseEventHandler MouseEvent; public MouseHookManager() { this._mouseHookProcDelegate = MouseCallbackFunction; this._mouseHook = SetHook(this._mouseHookProcDelegate); } private static IntPtr SetHook(HookProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx( WhMouseLowLevel, proc, GetModuleHandle(curModule.ModuleName), 0); } } private IntPtr MouseCallbackFunction(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } if (MouseEvent != null) { var mouseLowLevelHookStruct = (MouseLowLevelHookStruct)Marshal.PtrToStructure( lParam, typeof(MouseLowLevelHookStruct)); var eventArgs = new MouseLowLevelHookEventArgs( (MouseMessageId)wParam, mouseLowLevelHookStruct); MouseEvent(this, eventArgs); } return CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("user32.dll")] private static extern IntPtr CallNextHookEx( IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetWindowsHookEx( int hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); #region IDisposable members public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // Dispose managed resources. } // Dispose unmanaged resources. if (this._mouseHook != IntPtr.Zero) { UnhookWindowsHookEx(this._mouseHook); } _disposed = true; } } #endregion } public class MouseLowLevelHookEventArgs : EventArgs { private readonly MouseMessageId _mouseMessage; private readonly MouseLowLevelHookStruct _mouseLowLevelHookStruct; private readonly System.Drawing.Color _pixelColor; public MouseLowLevelHookStruct MouseLowLevelHookStruct { get { return this._mouseLowLevelHookStruct; } } public MouseMessageId MouseMessage { get { return this._mouseMessage; } } public System.Drawing.Color PixelColor { get { return this._pixelColor; } } public MouseLowLevelHookEventArgs( MouseMessageId mouseMessage, MouseLowLevelHookStruct mouseLowLevelHookStruct) { this._mouseMessage = mouseMessage; this._mouseLowLevelHookStruct = mouseLowLevelHookStruct; var windowHandle = GetDesktopWindow(); if (windowHandle != IntPtr.Zero) { var hdc = GetWindowDC(windowHandle); _pixelColor = DrawingColorFromInt((int)GetPixel( hdc, _mouseLowLevelHookStruct.MousePoint.X, _mouseLowLevelHookStruct.MousePoint.Y)); ReleaseDC(windowHandle, hdc); } } private static System.Drawing.Color DrawingColorFromInt(int intColor) { var drawingColor = System.Drawing.Color.FromArgb( (intColor & 0x000000FF), (intColor & 0x0000FF00) >> 8, (intColor & 0x00FF0000) >> 16); return drawingColor; } [DllImport("gdi32.dll")] private static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos); [DllImport("user32.dll")] private static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hdc); [DllImport("user32.dll", SetLastError = false)] private static extern IntPtr GetDesktopWindow(); } }Below is an implementation for client.
using System.Windows.Forms; namespace WindowsHookForm { public partial class Form1 : Form { private readonly MouseHookManager _mouseHookManager; public Form1() { InitializeComponent(); _mouseHookManager = new MouseHookManager(); this.Closing += delegate { if (_mouseHookManager != null) { _mouseHookManager.MouseEvent -= this.OnMouseLowLevelHookEvent; _mouseHookManager.Dispose(); } }; _mouseHookManager.MouseEvent += this.OnMouseLowLevelHookEvent; } private void OnMouseLowLevelHookEvent( object sender, MouseLowLevelHookEventArgs e) { switch (e.MouseMessage) { case MouseMessageId.LeftButtonDown: labelMouseKey.Text = "Left"; break; case MouseMessageId.LeftButtonUp: labelMouseKey.Text = string.Empty; break; case MouseMessageId.MouseMove: labelMouseX.Text = string.Format("X={0}", e.MouseLowLevelHookStruct.MousePoint.X); labelMouseY.Text = string.Format("Y={0}", e.MouseLowLevelHookStruct.MousePoint.Y); labelPixelColor.Text = e.PixelColor.ToArgb().ToString(); labelPixelColor.Text = string.Format( "R={0}, G={1}, B={2}", e.PixelColor.R, e.PixelColor.G, e.PixelColor.B); panel1.BackColor = e.PixelColor; break; case MouseMessageId.MouseWheel: break; case MouseMessageId.MouseHorizWheel: break; case MouseMessageId.RightButtonDown: labelMouseKey.Text = "Right"; break; case MouseMessageId.RightButtonUp: labelMouseKey.Text = string.Empty; break; } } } }