【发布时间】:2012-01-31 19:10:08
【问题描述】:
我想捕捉一个在桌面上绘制一个矩形的桌面区域。
为了实现这一点,我开发了一个名为 MouseHooker 的类,它安装了一个全局鼠标钩子,处理鼠标消息并通过回调与委托将其公开。
钩子代码没问题,我也认为外部“回调”但有一个奇怪的错误。
它勾住了鼠标,但是矩形只有在鼠标左键移动后才绘制。
我不知道为什么。你能帮助我吗 ? 谢谢
MouseHooker 内部回调
private static IntPtr MyCallbackFunction(int code, UIntPtr wParam, IntPtr lParam)
{
// messsage not processed
if ( code < 0 )
SafeNativeMethods.CallNextHookEx(IntPtr.Zero,code,wParam,lParam);
// check outside callback subscribed to delegate (NOT IMPORTANT )
if ( state != HookState.CallBackError )
{
MSLLHOOKSTRUCT hk = (MSLLHOOKSTRUCT)Marshal.PtrToStructure((IntPtr)lParam, typeof(MSLLHOOKSTRUCT));
MouseHookArgs m; // this struct only contains mouse coordinates and button
m.x = hk.pt.x; // clicked information
m.y = hk.pt.y;
// process mouse messages
switch ((MouseMessages)wParam)
{
case MouseMessages.WM_MOUSEMOVE:
m.button = MouseButtons.M_MOVE;
mc(m); // call outside "callback" mc its a delegate
break;
case MouseMessages.WM_LBUTTONUP:
m.button = MouseButtons.LB_UP;
mc(m);
break;
case MouseMessages.WM_LBUTTONDOWN:
m.button = MouseButtons.LB_DOWN;
mc(m);
break;
// more mouse message processing
}
// CallNextHookEx
return SafeNativeMethods.CallNextHookEx(IntPtr.Zero,code,wParam,lParam);
}
表单中的“回调”(这里是bug,为什么?)
void callbackrect( MouseHookArgs args )
{
switch (args.button)
{
case ppk.Hooks.MouseButtons.LB_UP:
clean = true;
ok = true;
dest.X = args.x; // this struct its a Point
dest.Y = args.y;
// put destination mouse coordinate in form label
capt.Text = string.Format("X: {0} , Y: {1}", dest.X, dest.Y);
break;
case ppk.Hooks.MouseButtons.LB_DOWN:
if ( clean )
{
clean = false;
ok = false;
}
origin.X = args.x; // get origin mouse coordinate (to draw rectangle )
origin.Y = args.y;
// put origin mouse coordinate in form label
rat.Text = string.Format("X: {0} , Y: {1}", origin.X, origin.Y);
break;
}
// Invalidate & Update Desktop RECT Unmanaged because it's a efficient
SafeNativeMethods.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
SafeNativeMethods.UpdateWindow(IntPtr.Zero);
if (ok && clean) // Graphics g it's static and created in another location.
// Managed because creating a Pen, get DC, etc it's a pain
// and need more unmanaged code. So, why not use graphics ?
g.DrawRectangle(Pens.Red, origin.X, origin.Y, dest.X - origin.X, dest.Y - origin.Y);
}
【问题讨论】:
-
“MouseHooker”...不错 ;)
-
callbackrect在哪里使用以及如何使用?
-
@Tigran 主窗体包含一个带有此原型的 MouseHooker 委托 public delegate void MouseCallBack(MouseHookArgs mas);这个委托绑定到 callbackrect 函数,所以当它安装钩子时,“原始”鼠标消息由 MyCallBackFunction 处理,回调函数通过 mc 委托调用。
-
delegate = typesafe "pointer" to funcion
标签: c# system.drawing