当前位置导航:炫浪网>>网络学院>>编程开发>>Visual C#教程

C# 实现屏幕键盘 (ScreenKeyboard)

要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就
是系统范围的钩子。

什么是钩子(Hook)

    钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先
    启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通
    过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获
    该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不
    作处理而继续传递该消息,还可以强制结束消息的传递。注意:安装钩子函数将会影响系统的性
    能。监测“系统范围事件”的系统钩子特别明显。因为系统在处理所有的相关事件时都将调用您的
    钩子函数,这样您的系统将会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可
    以预先截获其它进程的消息,所以一旦您的钩子函数出了问题的话必将影响其它的进程。

钩子的作用范围
    一共有两种范围(类型)的钩子,局部的和远程的。局部钩子仅钩挂自己进程的事件。远程的钩
    子还可以将钩挂其它进程发生的事件。远程的钩子又有两种: 基于线程的钩子将捕获其它进程中
    某一特定线程的事件。简言之,就是可以用来观察其它进程中的某一特定线程将发生的事件。 系
    统范围的钩子将捕捉系统中所有进程将发生的事件消息。 

Hook 类型
    Windows共有14种Hooks,每一种类型的Hook可以使应用程序能够监视不同类型的系统消息处理机
    制。下面描述所有可以利用的Hook类型的发生时机。详细内容可以查阅MSDN,这里只介绍我们将要
    用到的两种类型的钩子。
    
    (1)WH_KEYBOARD_LL Hook
        WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。

    (2)WH_MOUSE_LL Hook
        WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。

下面的 class 把 API 调用封装起来以便调用。
 

 1 //  NativeMethods.cs
 2 using  System;
 3 using  System.Runtime.InteropServices;
 4 using  System.Drawing;
 5
 6 namespace  CnBlogs.Youzai.ScreenKeyboard  {
 7     [StructLayout(LayoutKind.Sequential)]
 8      internal   struct  MOUSEINPUT  {
 9          public   int  dx;
10          public   int  dy;
11          public   int  mouseData;
12          public   int  dwFlags;
13          public   int  time;
14          public  IntPtr dwExtraInfo;
15     }

16
17     [StructLayout(LayoutKind.Sequential)]
18      internal   struct  KEYBDINPUT  {
19          public   short  wVk;
20          public   short  wScan;
21          public   int  dwFlags;
22          public   int  time;
23          public  IntPtr dwExtraInfo;
24     }

25
26     [StructLayout(LayoutKind.Explicit)]
27      internal   struct  Input  {
28         [FieldOffset( 0 )]
29          public   int  type;
30         [FieldOffset( 4 )]
31          public  MOUSEINPUT mi;
32         [FieldOffset( 4 )]
33          public  KEYBDINPUT ki;
34         [FieldOffset( 4 )]
35          public  HARDWAREINPUT hi;
36     }

37
38     [StructLayout(LayoutKind.Sequential)]
39      internal   struct  HARDWAREINPUT  {
40          public   int  uMsg;
41          public   short  wParamL;
42          public   short  wParamH;
43     }

44
45      internal   class  INPUT  {
46          public   const   int  MOUSE  =   0 ;
47          public   const   int  KEYBOARD  =   1 ;
48          public   const   int  HARDWARE  =   2 ;
49     }

50
51      internal   static   class  NativeMethods  {
52         [DllImport( " User32.dll " , CharSet  =  CharSet.Auto, SetLastError  =   false )]
53          internal   static   extern  IntPtr GetWindowLong(IntPtr hWnd,  int  nIndex);
54
55         [DllImport( " User32.dll " , CharSet  =  CharSet.Auto, SetLastError  =   false )]
56          internal   static   extern  IntPtr SetWindowLong(IntPtr hWnd,  int  nIndex,  int  dwNewLong);
57
58         [DllImport( " User32.dll " , EntryPoint  =   " SendInput " , CharSet  =  CharSet.Auto)]
59          internal   static   extern  UInt32 SendInput(UInt32 nInputs, Input[] pInputs, Int32 cbSize);
60
61         [DllImport( " Kernel32.dll " , EntryPoint  =   " GetTickCount " , CharSet  =  CharSet.Auto)]
62          internal   static   extern   int  GetTickCount();
63
64         [DllImport( " User32.dll " , EntryPoint  =   " GetKeyState " , CharSet  =  CharSet.Auto)]
65          internal   static   extern   short  GetKeyState( int  nVirtKey);
66
67         [DllImport( " User32.dll " , EntryPoint  =   " SendMessage " , CharSet  =  CharSet.Auto)]
68          internal   static   extern  IntPtr SendMessage(IntPtr hWnd,  int  msg, IntPtr wParam, IntPtr lParam);
69     }

70 }

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接