前言
这里全局的键盘钩子和全局鼠标钩子是为了定义快捷键。
获取鼠标坐标
代码语言:javascript复制using System.Runtime.InteropServices;
namespace ColorPicker.Utils
{
internal class ZPoint
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetCursorPos(out POINT pt);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
}
}
调用方式
代码语言:javascript复制ZPoint.POINT point;
ZPoint.GetCursorPos(out point);
获取坐标颜色
代码语言:javascript复制using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace ColorPicker.Utils
{
internal class ScreenColor
{
public static Color GetPixelColor(int x, int y)
{
IntPtr hdc = GetDC(IntPtr.Zero);
uint pixel = GetPixel(hdc, x, y);
ReleaseDC(IntPtr.Zero, hdc);
Color color = Color.FromArgb((int)(pixel & 0x000000FF),
(int)(pixel & 0x0000FF00) >> 8,
(int)(pixel & 0x00FF0000) >> 16);
return color;
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("gdi32.dll")]
private static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
[DllImport("user32.dll")]
private static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);
}
}
调用方式
代码语言:javascript复制private static bool isStart = false;
/// <summary>
/// 上次的坐标点
/// </summary>
private ZPoint.POINT lastPoint;
/// <summary>
/// 取色
/// </summary>
private async void startTakeColor()
{
if (!isStart)
{
isStart = true;
while (isStart)
{
ZPoint.POINT point;
ZPoint.GetCursorPos(out point);
if (lastPoint.X != point.X || lastPoint.Y != point.Y)
{
lastPoint = point;
System.Drawing.Color c = ScreenColor.GetPixelColor(point.X, point.Y);
string html_color = System.Drawing.ColorTranslator.ToHtml(c);
html_color_tb.Text = html_color;
rgb_color_tb.Text = "RGB(" c.R "," c.G "," c.B ")";
color_tb.Background = (Brush)new BrushConverter().ConvertFrom(html_color);
Clipboard.SetText(html_color);
}
await Task.Run(() => { Thread.Sleep(300); });
}
}
}
/// <summary>
/// 停止取色
/// </summary>
private void stopTakeColor()
{
isStart = false;
}
全局键盘钩子
代码语言:javascript复制using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ColorPicker.Utils
{
/// <summary>
/// 键盘全局钩子
/// </summary>
public class KeyboardHook
{
#region 常数和结构
#region wParam对应的按钮事件
public const int WM_KEYDOWN = 0x100; // 键盘被按下
public const int WM_KEYUP = 0x101; // 键盘被松开
public const int WM_SYSKEYDOWN = 0x104; // 键盘被按下,这个是系统键被按下,例如Alt、Ctrl等键
public const int WM_SYSKEYUP = 0x105; // 键盘被松开,这个是系统键被松开,例如Alt、Ctrl等键
#endregion wParam对应的按钮事件
public const int WH_KEYBOARD_LL = 13;
[StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型
public class KeyboardHookStruct
{
public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;
}
#endregion 常数和结构
#region 成员变量、委托、事件
private static int hHook;
private static HookProc KeyboardHookDelegate;
// 锁
private readonly object lockObject = new object();
// 当前状态,是否已经启动
private volatile bool isStart = false;
// 键盘回调委托
public delegate void KeyboardHandler(Int32 wParam, KeyboardHookStruct keyboardHookStruct);
// 键盘回调事件
private static event KeyboardHandler Handlers;
#endregion 成员变量、委托、事件
#region Win32的Api
private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
//下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention =
CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
//安装钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
#endregion Win32的Api
#region 单例模式
private static readonly object createLock = new object();
private static volatile KeyboardHook MyKeyboard;
private KeyboardHook()
{ }
public static KeyboardHook GetKeyboardHook()
{
if (MyKeyboard == null)
{
lock (createLock)
{
if (MyKeyboard == null)
{
MyKeyboard = new KeyboardHook();
}
}
}
return MyKeyboard;
}
#endregion 单例模式
/// <summary>
/// 添加按键的回调函数
/// </summary>
/// <param name="handler">
/// </param>
public void AddKeyboardHandler(KeyboardHandler handler)
{
Handlers = handler;
}
/// <summary>
/// 删除指定按键的回调函数
/// </summary>
/// <param name="handler">
/// </param>
public void RemoveKeyboardHandler(KeyboardHandler handler)
{
if (Handlers != null)
{
Handlers -= handler;
}
}
/// <summary>
/// 安装钩子
/// </summary>
public void Start()
{
if (isStart)
{
return;
}
lock (lockObject)
{
if (isStart)
{
return;
}
if (Handlers == null)
{
throw new Exception("Please set handler first!Then run Start");
}
KeyboardHookDelegate = new HookProc(KeyboardHookProc);
Process cProcess = Process.GetCurrentProcess();
ProcessModule cModule = cProcess.MainModule;
var mh = GetModuleHandle(cModule.ModuleName);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
isStart = true;
}
}
/// <summary>
/// 卸载钩子
/// </summary>
public void Stop()
{
if (!isStart)
{
return;
}
lock (lockObject)
{
if (!isStart)
{
return;
}
UnhookWindowsHookEx(hHook);
// 清除所有事件
Handlers = null;
isStart = false;
}
}
/// <summary>
/// 键盘的系统回调函数
/// </summary>
/// <param name="nCode">
/// </param>
/// <param name="wParam">
/// </param>
/// <param name="lParam">
/// </param>
/// <returns>
/// </returns>
private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//如果该消息被丢弃(nCode<0)或者没有事件绑定处理程序则不会触发事件
if ((nCode >= 0) && Handlers != null)
{
KeyboardHookStruct KeyDataFromHook = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
Handlers(wParam, KeyDataFromHook);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
调用方式
代码语言:javascript复制private static MainWindow mainWindow = null;
private KeyboardHook k_hook = KeyboardHook.GetKeyboardHook();
public void StartKeyboardHook()
{
k_hook.AddKeyboardHandler(new KeyboardHook.KeyboardHandler(hookKeyboardEvent));
k_hook.Start();
}
public void StopKeyboardHook()
{
k_hook.Stop();
}
private static void hookKeyboardEvent(int wParam, KeyboardHook.KeyboardHookStruct keyboardHookStruct)
{
if (keyboardHookStruct.vkCode == 164 && wParam == 0x101)
{
if (isStart)
{
mainWindow.stopTakeColor();
}
else
{
mainWindow.startTakeColor();
}
}
}
全局鼠标钩子
代码语言:javascript复制using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ColorPicker.Utils
{
/// <summary>
/// 鼠标全局钩子
/// </summary>
public class MouseHook
{
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_LBUTTONUP = 0x202;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONUP = 0x208;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209;
/// <summary>
/// 点
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
/// <summary>
/// 钩子结构体
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
}
public const int WH_MOUSE_LL = 14; // mouse hook constant
// 装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
// 卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
// 下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
// 键盘回调委托
public delegate void MouseHandler(object sender, MouseEventArgs e, int downup);
// 键盘回调事件
private static event MouseHandler Handlers;
// 钩子回调函数
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
// 声明鼠标钩子事件类型
private HookProc _mouseHookProcedure;
private static int _hMouseHook = 0; // 鼠标钩子句柄
/// <summary>
/// 构造函数
/// </summary>
public MouseHook()
{
}
/// <summary>
/// 析构函数
/// </summary>
~MouseHook()
{
Stop();
}
/// <summary>
/// 启动全局钩子
/// </summary>
public void Start()
{
// 安装鼠标钩子
if (_hMouseHook == 0)
{
if (Handlers == null)
{
throw new Exception("Please set handler first!Then run Start");
}
// 生成一个HookProc的实例.
_mouseHookProcedure = new HookProc(MouseHookProc);
_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
//假设装置失败停止钩子
if (_hMouseHook == 0)
{
Stop();
throw new Exception("SetWindowsHookEx failed.");
}
}
}
/// <summary>
/// 停止全局钩子
/// </summary>
public void Stop()
{
bool retMouse = true;
if (_hMouseHook != 0)
{
retMouse = UnhookWindowsHookEx(_hMouseHook);
_hMouseHook = 0;
}
// 假设卸下钩子失败
if (!(retMouse))
throw new Exception("UnhookWindowsHookEx failed.");
}
/// <summary>
/// 添加按键的回调函数
/// </summary>
/// <param name="handler">
/// </param>
public void AddMouseHandler(MouseHandler handler)
{
Handlers = handler;
}
/// <summary>
/// 鼠标钩子回调函数
/// </summary>
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// 假设正常执行而且用户要监听鼠标的消息
if ((nCode >= 0) && (Handlers != null))
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
int downup = 0;//0 down 1 up
switch (wParam)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = 1;
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = 1;
downup = 1;
break;
case WM_LBUTTONDBLCLK:
button = MouseButtons.Left;
clickCount = 2;
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = 1;
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = 1;
downup = 1;
break;
case WM_RBUTTONDBLCLK:
button = MouseButtons.Right;
clickCount = 2;
break;
}
// 从回调函数中得到鼠标的信息
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
Handlers(this, e, downup);
}
// 启动下一次钩子
return CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
}
}
}
调用方式
代码语言:javascript复制private static MainWindow mainWindow = null;
private MouseHook m_hook = new MouseHook();
public void StartMouseHook()
{
m_hook.AddMouseHandler(new MouseHook.MouseHandler(hookMouseEvent));
m_hook.Start();
}
public void StopMouseHook()
{
m_hook.Stop();
}
private static void hookMouseEvent(object sender, System.Windows.Forms.MouseEventArgs e, int downup)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left && downup == 1)
{
mainWindow.stopTakeColor();
}
}