C#用windows Api Hooks 控制鼠标键盘在一个窗体内

作者&投稿:牢衬 (若有异议请与网页底部的电邮联系)
C#用windows Api Hooks 控制鼠标键盘在一个窗体内~

直接通过C#调用window api来实现HOOK,说下思路吧,实现自己琢磨下吧,如你所说其实很简单,关键逻辑想通了就OK
1. 获取窗体句柄,可以通过findwindow函数很enumwindow两个函数结合使用获取,如果知道了类名或者窗体的名称也可以直接调用窗体操作相关API来获取窗体句柄
2.HOOK部分,这里我建议你用全局钩子,通过 setwindowhookex函数来安装钩子,钩子的类型就是键盘钩子和鼠标钩子了,要是你觉得普通的键盘鼠标钩子不能满足,那么就像QQ那样用低级的键盘钩子和鼠标钩子,这个在msdn文档都有描述或者百度下就知道了,然后 处理的话直接在钩子的回调函数,这个我想你也知道,这个处理可能需要点技巧了
3.要控制ctrl-alt-delete那么就用低级键盘钩子的,以前用C#写过,不过是用C++写库,C#调用的,所以要控制这个我推荐用低级键盘钩子,不过据我所知好像C#直接用钩子还是有些限制很不足的,比如低级的钩子就不好整了

==
以上就是一些简单的思路了
PS:有个C#做的HOOK类库很强大,你可以百度下,名字我忘记了

有api可以模拟键盘与鼠标事件,但只能针对活动窗口。
如果你向指定的窗口模拟事件,可以发窗口消息。

主要是第一个窗体类.其他的2个类是我封装的WINDOWS API

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace HookDemo
{
public partial class Form1 : Form
{
private System.Windows.Forms.Timer monitorTimer = null;
private Kits.Hook.WinHook mouseHook = null;
private IntPtr HWND = IntPtr.Zero;

public Form1()
{
InitializeComponent();
this.monitorTimer = new Timer();
this.monitorTimer.Tick += new EventHandler(this.TimeProc);
this.monitorTimer.Interval = 1000;
mouseHook = new Kits.Hook.WinHook(Kits.Win32API.HookType.WH_MOUSE_LL);
}

private void Form1_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
this.monitorTimer.Enabled = true;
}

private void TimeProc(object sender, EventArgs e)
{
HWND = Kits.Win32API.WinAPI.FindWindow("Notepad", null);
if (HWND != IntPtr.Zero)
{
//Kits.Win32API.CSharpRect rect = new Kits.Win32API.CSharpRect();
//Kits.Win32API.WinAPI.GetWindowRect(HWND, ref rect);
//this.Text = string.Format("{0},{1},{2},{3}",rect.top,rect.left,rect.width,rect.height);
if (HWND == Kits.Win32API.WinAPI.GetForegroundWindow())
{
mouseHook.SetWindowsHookEx(new Kits.Win32API.HookProc(this.MouseHookProc));
}
else
{
if (mouseHook.HHook != 0)
{
mouseHook.UnhookWindowsHookEx();
}
}
}
}

private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (wParam == new IntPtr((int)Kits.Win32API.WindowsMessages.WM_MOUSEMOVE))
{
bool isOut = false;
Kits.Win32API.MouseHookStruct MyMouseHookStruct = (Kits.Win32API.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Kits.Win32API.MouseHookStruct));
Kits.Win32API.CSharpRect rect = new Kits.Win32API.CSharpRect();
Kits.Win32API.WinAPI.GetWindowRect(HWND, ref rect);
if (MyMouseHookStruct.pt.x >= rect.right)
isOut = true;
if (MyMouseHookStruct.pt.x <= rect.left)
isOut = true;
if (MyMouseHookStruct.pt.y <= rect.top)
isOut = true;
if (MyMouseHookStruct.pt.y >= rect.bottom)
isOut = true;

//Cursor.Position = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
if (isOut)
return -1;
}
return Kits.Win32API.WinAPI.CallNextHookEx(mouseHook.HHook, nCode, wParam, lParam);
}
}
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Kits.Win32API
{
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

public class WinAPI
{
[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, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("User32.dll")]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);

[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("User32.dll")]
public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);

[DllImport("user32")]
public static extern IntPtr GetActiveWindow();

[DllImport("user32")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32")]
public static extern int GetWindowRect(IntPtr hwnd, ref CSharpRect lpRect);

[DllImport("user32")]
public static extern int SetCaretPos(int x, int y);

[DllImport("user32")]
public static extern int ScreenToClient(IntPtr hwnd, ref POINTAPI lpPoint);

[DllImport("user32")]
public static extern int ClientToScreen(IntPtr hwnd, ref POINTAPI lpPoint);

[DllImport("user32")]
public static extern int SetCursorPos(int x, int y);
}

public struct POINTAPI
{
public int x;
public int y;
}

public struct RECT
{
public long left;
public long top;
public long right;
public long bottom;
}

public struct CSharpRect
{
public int top;
public int left;
public int right;
public int bottom;
}

public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}

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

[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int wHitTestCode;
public int dwExtraInfo;
}

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

[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}

public enum WindowsMessages:int
{
WM_ACTIVATE = 0x6,
WM_ACTIVATEAPP = 0x1C,
WM_AFXFIRST = 0x360,
WM_AFXLAST = 0x37F,
WM_APP = 0x8000,
WM_ASKCBFORMATNAME = 0x30C,
WM_CANCELJOURNAL = 0x4B,
WM_CANCELMODE = 0x1F,
WM_CAPTURECHANGED = 0x215,
WM_CHANGECBCHAIN = 0x30D,
WM_CHAR = 0x102,
WM_CHARTOITEM = 0x2F,
WM_CHILDACTIVATE = 0x22,
WM_CLEAR = 0x303,
WM_CLOSE = 0x10,
WM_COMMAND = 0x111,
WM_COMPACTING = 0x41,
WM_COMPAREITEM = 0x39,
WM_CONTEXTMENU = 0x7B,
WM_COPY = 0x301,
WM_COPYDATA = 0x4A,
WM_CREATE = 0x1,
WM_CTLCOLORBTN = 0x135,
WM_CTLCOLORDLG = 0x136,
WM_CTLCOLOREDIT = 0x133,
WM_CTLCOLORLISTBOX = 0x134,
WM_CTLCOLORMSGBOX = 0x132,
WM_CTLCOLORSCROLLBAR = 0x137,
WM_CTLCOLORSTATIC = 0x138,
WM_CUT = 0x300,
WM_DEADCHAR = 0x103,
WM_DELETEITEM = 0x2D,
WM_DESTROY = 0x2,
WM_DESTROYCLIPBOARD = 0x307,
WM_DEVICECHANGE = 0x219,
WM_DEVMODECHANGE = 0x1B,
WM_DISPLAYCHANGE = 0x7E,
WM_DRAWCLIPBOARD = 0x308,
WM_DRAWITEM = 0x2B,
WM_DROPFILES = 0x233,
WM_ENABLE = 0xA,
WM_ENDSESSION = 0x16,
WM_ENTERIDLE = 0x121,
WM_ENTERMENULOOP = 0x211,
WM_ENTERSIZEMOVE = 0x231,
WM_ERASEBKGND = 0x14,
WM_EXITMENULOOP = 0x212,
WM_EXITSIZEMOVE = 0x232,
WM_FONTCHANGE = 0x1D,
WM_GETDLGCODE = 0x87,
WM_GETFONT = 0x31,
WM_GETHOTKEY = 0x33,
WM_GETICON = 0x7F,
WM_GETMINMAXINFO = 0x24,
WM_GETOBJECT = 0x3D,
WM_GETTEXT = 0xD,
WM_GETTEXTLENGTH = 0xE,
WM_HANDHELDFIRST = 0x358,
WM_HANDHELDLAST = 0x35F,
WM_HELP = 0x53,
WM_HOTKEY = 0x312,
WM_HSCROLL = 0x114,
WM_HSCROLLCLIPBOARD = 0x30E,
WM_ICONERASEBKGND = 0x27,
WM_IME_CHAR = 0x286,
WM_IME_COMPOSITION = 0x10F,
WM_IME_COMPOSITIONFULL = 0x284,
WM_IME_CONTROL = 0x283,
WM_IME_ENDCOMPOSITION = 0x10E,
WM_IME_KEYDOWN = 0x290,
WM_IME_KEYLAST = 0x10F,
WM_IME_KEYUP = 0x291,
WM_IME_NOTIFY = 0x282,
WM_IME_REQUEST = 0x288,
WM_IME_SELECT = 0x285,
WM_IME_SETCONTEXT = 0x281,
WM_IME_STARTCOMPOSITION = 0x10D,
WM_INITDIALOG = 0x110,
WM_INITMENU = 0x116,
WM_INITMENUPOPUP = 0x117,
WM_INPUTLANGCHANGE = 0x51,
WM_INPUTLANGCHANGEREQUEST = 0x50,
WM_KEYDOWN = 0x100,
WM_KEYFIRST = 0x100,
WM_KEYLAST = 0x108,
WM_KEYUP = 0x101,
WM_KILLFOCUS = 0x8,
WM_LBUTTONDBLCLK = 0x203,
WM_LBUTTONDOWN = 0x201,
WM_LBUTTONUP = 0x202,
WM_MBUTTONDBLCLK = 0x209,
WM_MBUTTONDOWN = 0x207,
WM_MBUTTONUP = 0x208,
WM_MDIACTIVATE = 0x222,
WM_MDICASCADE = 0x227,
WM_MDICREATE = 0x220,
WM_MDIDESTROY = 0x221,
WM_MDIGETACTIVE = 0x229,
WM_MDIICONARRANGE = 0x228,
WM_MDIMAXIMIZE = 0x225,
WM_MDINEXT = 0x224,
WM_MDIREFRESHMENU = 0x234,
WM_MDIRESTORE = 0x223,
WM_MDISETMENU = 0x230,
WM_MDITILE = 0x226,
WM_MEASUREITEM = 0x2C,
WM_MENUCHAR = 0x120,
WM_MENUCOMMAND = 0x126,
WM_MENUDRAG = 0x123,
WM_MENUGETOBJECT = 0x124,
WM_MENURBUTTONUP = 0x122,
WM_MENUSELECT = 0x11F,
WM_MOUSEACTIVATE = 0x21,
WM_MOUSEFIRST = 0x200,
WM_MOUSEHOVER = 0x2A1,
WM_MOUSELAST = 0x20A,
WM_MOUSELEAVE = 0x2A3,
WM_MOUSEMOVE = 0x200,
WM_MOUSEWHEEL = 0x20A,
WM_MOVE = 0x3,
WM_MOVING = 0x216,
WM_NCACTIVATE = 0x86,
WM_NCCALCSIZE = 0x83,
WM_NCCREATE = 0x81,
WM_NCDESTROY = 0x82,
WM_NCHITTEST = 0x84,
WM_NCLBUTTONDBLCLK = 0xA3,
WM_NCLBUTTONDOWN = 0xA1,
WM_NCLBUTTONUP = 0xA2,
WM_NCMBUTTONDBLCLK = 0xA9,
WM_NCMBUTTONDOWN = 0xA7,
WM_NCMBUTTONUP = 0xA8,
WM_NCMOUSEHOVER = 0x2A0,
WM_NCMOUSELEAVE = 0x2A2,
WM_NCMOUSEMOVE = 0xA0,
WM_NCPAINT = 0x85,
WM_NCRBUTTONDBLCLK = 0xA6,
WM_NCRBUTTONDOWN = 0xA4,
WM_NCRBUTTONUP = 0xA5,
WM_NEXTDLGCTL = 0x28,
WM_NEXTMENU = 0x213,
WM_NOTIFY = 0x4E,
WM_NOTIFYFORMAT = 0x55,
WM_NULL = 0x0,
WM_PAINT = 0xF,
WM_PAINTCLIPBOARD = 0x309,
WM_PAINTICON = 0x26,
WM_PALETTECHANGED = 0x311,
WM_PALETTEISCHANGING = 0x310,
WM_PARENTNOTIFY = 0x210,
WM_PASTE = 0x302,
WM_PENWINFIRST = 0x380,
WM_PENWINLAST = 0x38F,
WM_POWER = 0x48,
WM_PRINT = 0x317,
WM_PRINTCLIENT = 0x318,
WM_QUERYDRAGICON = 0x37,
WM_QUERYENDSESSION = 0x11,
WM_QUERYNEWPALETTE = 0x30F,
WM_QUERYOPEN = 0x13,
WM_QUEUESYNC = 0x23,
WM_QUIT = 0x12,
WM_RBUTTONDBLCLK = 0x206,
WM_RBUTTONDOWN = 0x204,
WM_RBUTTONUP = 0x205,
WM_RENDERALLFORMATS = 0x306,
WM_RENDERFORMAT = 0x305,
WM_SETCURSOR = 0x20,
WM_SETFOCUS = 0x7,
WM_SETFONT = 0x30,
WM_SETHOTKEY = 0x32,
WM_SETICON = 0x80,
WM_SETREDRAW = 0xB,
WM_SETTEXT = 0xC,
WM_SETTINGCHANGE = 0x1A,
WM_SHOWWINDOW = 0x18,
WM_SIZE = 0x5,
WM_SIZECLIPBOARD = 0x30B,
WM_SIZING = 0x214,
WM_SPOOLERSTATUS = 0x2A,
WM_STYLECHANGED = 0x7D,
WM_STYLECHANGING = 0x7C,
WM_SYNCPAINT = 0x88,
WM_SYSCHAR = 0x106,
WM_SYSCOLORCHANGE = 0x15,
WM_SYSCOMMAND = 0x112,
WM_SYSDEADCHAR = 0x107,
WM_SYSKEYDOWN = 0x104,
WM_SYSKEYUP = 0x105,
WM_TCARD = 0x52,
WM_TIMECHANGE = 0x1E,
WM_TIMER = 0x113,
WM_UNDO = 0x304,
WM_UNINITMENUPOPUP = 0x125,
WM_USER = 0x400,
WM_USERCHANGED = 0x54,
WM_VKEYTOITEM = 0x2E,
WM_VSCROLL = 0x115,
WM_VSCROLLCLIPBOARD = 0x30A,
WM_WINDOWPOSCHANGED = 0x47,
WM_WINDOWPOSCHANGING = 0x46,
WM_WININICHANGE = 0x1A
}
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Kits.Win32API;

namespace Kits.Hook
{
public class WinHook
{
private int _hookType = 0;
public int HookType { get { return this._hookType; } }

private HookProc _hookProc = null;
public HookProc HookProc { get { return this._hookProc; } }

private int _hHook = 0;
public int HHook { get { return this._hHook; } }

public WinHook(HookType type) {
this._hookType = (int)type;
}

public bool SetWindowsHookEx(HookProc Proc) {
bool Success = false;
if (this._hHook == 0) {
this._hookProc = Proc;
_hHook = WinAPI.SetWindowsHookEx(this._hookType, this._hookProc, Process.GetCurrentProcess().MainModule.BaseAddress, 0);
if (this._hHook != 0)
Success = true;
}
return Success;
}

public bool UnhookWindowsHookEx() {
bool Success = false;
if (this._hHook != 0)
{
Success = WinAPI.UnhookWindowsHookEx(this._hHook);
}
return Success;
}
}
}

关注


迪庆藏族自治州19761312406: 如何使用c#hook一个windows api 函数 -
郑软赛斯: hook api有几种方式1、导入表hook,枚举导入表,找到位置,替换函数指针即可,api加算法即可完成,因此c#也可以调用api来完成2、inline hook,找到函数地址,开头写入跳转指令跳转到新位置,新位置执行后可以选择调用原函数,原函数之前可以先执行被覆盖的指令在跳转到剩余函数指令上.api加算法即可完成,因此c#也可以调用api来完成

迪庆藏族自治州19761312406: 在C#中如何使用WINDOWS API函数?
郑软赛斯: 使用DLLImport . http://www.cnblogs.com/xumingming/archive/2008/10/10/1308248.html 这里有详细的例子. 希望对你有所帮助.

迪庆藏族自治州19761312406: C#能直接调用windows api吗 -
郑软赛斯: 你说的没错,java调用windows api很困难,vc++只是一个工具,你可以转向c#或者c++,直接操作windows api很容易的.

迪庆藏族自治州19761312406: C#编程中如何调用WIN32 API函数 -
郑软赛斯: visual c#和其它开发工具一样也能够调用动态链接库的api函数..net框架本身提供了这样一种服务,允许受管辖的代码调用动态链接库中实现的非受管辖函数, 包括操作系统提供的windows api函数.它能够定位和调用输出函数,根据需要,组...

迪庆藏族自治州19761312406: c#怎样调用windows api 最好附有代码. -
郑软赛斯: #region 调用API函数显示窗体 [DllImportAttribute("user32.dll")]private static extern Boolean ShowWindow(IntPtr hwnd, Int32 cmdShow); //该方法用来显示窗体#endregion user32.dll 是其中一个有API的文件,根据要调用的API不同,可以换不同的dll文件.下面的函数就是windows API里的函数,要声明才能用.声明每个API函数前都要加[DllImportAttribute("....")] ,不能只有一个[]

迪庆藏族自治州19761312406: windows api可以用于c#吗? -
郑软赛斯: C#是微软的...API可以在C#上调用

迪庆藏族自治州19761312406: C#用windows Api Hooks 控制鼠标键盘在一个窗体内
郑软赛斯: 直接通过C#调用window api来实现HOOK,说下思路吧,实现自己琢磨下吧,如你所说其实很简单,关键逻辑想通了就OK 1. 获取窗体句柄,可以通过findwindow函数很enumwindow两个函数结合使用获取,如果知道了类名或者窗体的名称也可...

迪庆藏族自治州19761312406: c#种怎么直接调用win32 api啊?? -
郑软赛斯: 使用DIIImport特性可以指示CLR从哪个DLL导出想要调用的函数.GDI32.dll、Kernel32.dll和User32.dll是最常用的三个DLL.如果不确定哪个DLL定义了需要使用的WindowsAPI函数,可以参考PlateformSDK文档. 例子:(需要引入命名空间...

迪庆藏族自治州19761312406: C# 怎么用WINDOW API -
郑软赛斯: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;namespace ...

迪庆藏族自治州19761312406: 如何在c#中引用c++中的window.h 文件? -
郑软赛斯: C#和Window.h没有任何牵扯了 它可以用相对简单的方式调用WindowsAPI 请参照: http://msdn.microsoft.com/zh-cn/library/26thfadc.aspx 比如: MessageBox这个API就可以这样声明下: [DllImport("user32.dll", CharSet=CharSet.Auto)] public ...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网