您的位置:首页 > 编程语言 > C#

C# 模拟鼠标事件

2010-12-21 16:44 633 查看
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using System.Runtime.CompilerServices;

namespace Capture
{

[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}

[StructLayout(LayoutKind.Sequential)]
public class MouseLLHookStruct
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public int dwExtraInfo;
}

public class MouseHook
{
[Flags]
public enum MouseEventFlags : uint
{
Move = 1,
LeftDown = 2,
LeftUp = 4,
RightDown = 8,
RightUp = 0x10,
MiddleDown = 0x20,
MiddleUp = 0x40,
h = 0x80,
i = 0x100,
Wheel = 0x800,
k = 0x4000,
Absolute = 0x8000
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void MyRemove(MouseEventHandler A_0)
{
this.OnMouseActivity = (MouseEventHandler)Delegate.Remove(this.OnMouseActivity, A_0);
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void MyCombine(MouseEventHandler A_0)
{
this.OnMouseActivity = (MouseEventHandler)Delegate.Combine(this.OnMouseActivity, A_0);
}

[DllImport("user32.dll")]
private static extern void mouse_event(MouseEventFlags A_0, int A_1, int A_2, uint A_3, UIntPtr A_4);

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;
private const int WM_MOUSEWHEEL = 0x800;

private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
HookProc MouseHookProcedure; //声明鼠标钩子事件类型.
public event MouseEventHandler OnMouseActivity; //全局事件
static int hMouseHook = 0; //鼠标钩子句柄

//首先倒入所需要的windows函数,主要有三个,SetWindowsHookEX用来安装钩子,UnhookWindowsHookEX用来卸载钩子以及CallNextHookEX用来将hook信息传递到链表中下一个hook处理过程。
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern int SetWindowsHookEx(
int idHook,
HookProc lpfn,
IntPtr hMod,
int dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern int UnhookWindowsHookEx(int idHook);

[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(
int idHook,
int nCode,
int wParam,
IntPtr lParam);

//下面是有关这两个low-level hook在Winuser.h中的定义:
/// <summary>
/// Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events.
/// </summary>
private const int WH_MOUSE_LL = 14;
/// <summary>
/// Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard input events.
/// </summary>
private const int WH_KEYBOARD_LL = 13;

//在安装全局钩子的时候,我们就要做替换了,将WH_MOUSE和WH_KEYBORAD分别换成WH_MOUSE_LL和WH_KEYBORAD_LL:

//install hook
/// <summary>
/// 加载鼠标钩子
/// </summary>
public void InstallHook()
{
try
{
MouseHookProcedure = new HookProc(MouseHookProc);//生成一个HookProc的实例.
}
catch (Exception ex)
{
ErrorLog.ConnError("生成一个HookProc的实例出错:" + ex.Message);
}

hMouseHook = SetWindowsHookEx(
WH_MOUSE_LL, //原来是WH_MOUSE
MouseHookProcedure,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]),
0);

OnMouseActivity += new MouseEventHandler(mouseHook_MouseEvent);
}
/// <summary>
/// 卸载一个鼠标钩子
/// </summary>
public void UnInstallHook()
{
OnMouseActivity -= new MouseEventHandler(mouseHook_MouseEvent);
UnhookWindowsHookEx(hMouseHook);
}

/// <summary>
/// 模拟鼠标双击
/// </summary>
/// <param name="send"></param>
/// <param name="e"></param>
DateTime time;
private void mouseHook_MouseEvent(object send, MouseEventArgs e)
{

if (e.Button == MouseButtons.Left)
{
try
{
MyRemove(this.mouseHook_MouseEvent);
if (DateTime.Now.Subtract(time).TotalMilliseconds < 300.0)
{
mouse_event(MouseEventFlags.LeftDown, 0, 0, 0, UIntPtr.Zero);
mouse_event(MouseEventFlags.LeftUp, 0, 0, 0, UIntPtr.Zero);
//MessageBox.Show("双击!");
}
time = DateTime.Now;
MyCombine(this.mouseHook_MouseEvent);
}
catch (Exception ex)
{
ErrorLog.ConnError("模拟鼠标双击出错:" + ex.Message);
}
}
}

//这样替换了之后,我们就可以实现全局钩子了,而且,不需要写DLL。看一下程序运行情况:
/// <summary>
/// 返回 MouseHookProcedure 对象
/// </summary>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{

try
{
// if ok and someone listens to our events

if ((nCode >= 0) && (OnMouseActivity != null))
{

//Marshall the data from callback.

MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));

//detect button clicked

MouseButtons button = MouseButtons.None;

short mouseDelta = 0;

switch (wParam)
{

case WM_LBUTTONDOWN:

//case WM_LBUTTONUP:

//case WM_LBUTTONDBLCLK:

button = MouseButtons.Left;

break;

case WM_RBUTTONDOWN:

//case WM_RBUTTONUP:

//case WM_RBUTTONDBLCLK:

button = MouseButtons.Right;

break;

case WM_MOUSEWHEEL:

//If the message is WM_MOUSEWHEEL, the high-order word of mouseData member is the wheel delta.

//One wheel click is defined as WHEEL_DELTA, which is 120.

//(value >> 16) & 0xffff; retrieves the high-order word from the given 32-bit value

mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);

//TODO: X BUTTONS (I havent them so was unable to test)

//If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP,

//or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released,

//and the low-order word is reserved. This value can be one or more of the following values.

//Otherwise, mouseData is not used.

break;

}

//double clicks

int clickCount = 0;

if (button != MouseButtons.None)

if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;

else clickCount = 1;

//generate event

MouseEventArgs e = new MouseEventArgs(

button,

clickCount,

mouseHookStruct.pt.x,

mouseHookStruct.pt.y,

mouseDelta);

//raise it

OnMouseActivity(this, e);

}
}
catch (Exception e)
{

ErrorLog.ConnError("MouseHookPro函数出错:" + e.Message);
}

//call next hook

return CallNextHookEx(hMouseHook, nCode, wParam, lParam);

}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: