C#键盘消息监听

windows是基于消息处理的。比如用户按下了键盘,该消息首先由操作系统接收,再将其发送到当前的应用程序处理。事实上,在操作系统把消息发送到当前的应用程序前,你可以截取该消息,这就是我们通常所说的钩子程序。

说明:

SetWindowsHookEx()设置钩子函数

UnhookWindowsHookEx()取消钩子函数

CallNextHookEx()把消息传递给下一个钩子,如果是最后一个钩子,则把消息返回给操作系统

 

截取键盘消息实例:

1 vs新建一个项目WindowsMessageHook,类型为Class Library,把KeyboardHook.cs加入工程,编译后,生成WindowsMessageHook.dll

KeyboardHook.cs代码

 

代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;

namespace WindowsMessageHook
{
public delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);

public enum HookType //枚举,钩子的类型 WindowsMessageHook
{
MsgFilter
= -1,
JournalRecord
= 0,
JournalPlayback
= 1,
Keyboard
= 2,
GetMessage
= 3,
CallWndProc
= 4,
CBT
= 5,
SysMsgFilter
= 6,
Mouse
= 7,
Hardware
= 8,
Debug
= 9,
Shell
= 10,
ForegroundIdle
= 11,
CallWndProcRet
= 12,
KeyboardLL
= 13,
MouseLL
= 14
}

[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;
}

public class KeyboardHook
{
private const int WM_KEYDOWN = 0x100;
private const int WM_KEYUP = 0x101;

private IntPtr nextHookPtr; //记录Hook编号
private HookProc hookProc;

[DllImport(
"User32.dll")]
public static extern void UnhookWindowsHookEx(IntPtr handle);
[DllImport(
"User32.dll")]
public static extern IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID);
[DllImport(
"User32.dll")]
public static extern IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam);

public KeyboardHook()
{
nextHookPtr
= IntPtr.Zero;
}

public void SetKeyboardHook()
{
if (nextHookPtr != IntPtr.Zero)
return;
hookProc
= new HookProc(KeyboardhookProc); //键盘事件消息处理函数
nextHookPtr = SetWindowsHookEx((int)HookType.KeyboardLL,
hookProc,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[
0]),
0);
}

public void UnKeyboardHook()
{

if (nextHookPtr != IntPtr.Zero)
{
UnhookWindowsHookEx(nextHookPtr);
//从Hook链中取消
nextHookPtr = IntPtr.Zero;
}
}

private IntPtr KeyboardhookProc(int code, IntPtr wparam, IntPtr lparam)
{
if (code >= 0)
{
KeyboardHookStruct myKeyboardHookStruct
= (KeyboardHookStruct)Marshal.PtrToStructure(lparam, typeof(KeyboardHookStruct));
switch (wparam.ToInt32())
{
case WM_KEYDOWN:
Console.Write(
string.Format("WM_KEYDOWN:{0}", Convert.ToChar(myKeyboardHookStruct.vkCode)));
break;
case WM_KEYUP:
Console.Write(
string.Format("WM_KEYUP:{0:0}", Convert.ToChar(myKeyboardHookStruct.vkCode)));
break;
default:
break;
}
}
return CallNextHookEx(nextHookPtr, code, wparam, lparam); //返回,让后面的程序处理该消息
}
}
}

 

 

2 创建一个winform程序,测试上面的dll。

代码
//声明  
private KeyboardHook keyhook = new KeyboardHook();


private void Form1_Load(object sender, EventArgs e)
{
//设置hook
keyhook.SetKeyboardHook();
}


private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//关闭hook
keyhook.UnKeyboardHook();
}

 

  编译运行,在vs的output窗口中可以看到hook程序截获的键盘消息。

 

posted on 2010-05-14 17:53  钟湘光  阅读(5247)  评论(4编辑  收藏  举报

导航