C#键盘消息监听

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

说明:

SetWindowsHookEx()设置钩子函数

UnhookWindowsHookEx()取消钩子函数

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

 

截取键盘消息实例:

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

KeyboardHook.cs代码

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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。

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
// 声明  
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程序截获的键盘消息。

 

转载于:https://www.cnblogs.com/zhongxg/archive/2010/05/14/1735690.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值