在程序启动的时候如何监听键盘事件,请高手给个事例;

解决方案 »

  1.   

    要用到钩子,试一下去codeproject找一下
      

  2.   

    钩子函数,比较容易,网上资料多的是
    得到鼠标的消息的类:using System;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Threading;
    using System.Windows.Forms;
    namespace HookGlobal

     /// <summary>
     /// 这个类可以让你得到一个在运行中程序的所有鼠标事件
     /// 并且引发一个带MouseEventArgs参数的.NET鼠标事件以便你很容易使用这些信息
     /// </summary>
     public class MouseHook
     {
      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;
    //全局的事件
      public event MouseEventHandler OnMouseActivity;
    static int hMouseHook = 0; //鼠标钩子句柄
      //鼠标常量
      public const int WH_MOUSE_LL  = 14; //mouse hook constant
      HookProc MouseHookProcedure; //声明鼠标钩子事件类型.
      //声明一个Point的封送类型
      [StructLayout(LayoutKind.Sequential)]
       public class POINT 
      {
       public int x;
       public int y;
      }
      //声明鼠标钩子的封送结构类型
      [StructLayout(LayoutKind.Sequential)]
       public class MouseHookStruct 
      {
       public POINT pt;
       public int hWnd;
       public int wHitTestCode;
       public int dwExtraInfo;
      }
      //装置钩子的函数
      [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, Int32 wParam, IntPtr lParam);  
      public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
      /// <summary>
      /// 墨认的构造函数构造当前类的实例.
      /// </summary>
      public MouseHook() 
      {
       //Start();
      }
      //析构函数.
      ~MouseHook() 
      { 
       Stop();
      } 
      public void Start()
      {
       //安装鼠标钩子
       if(hMouseHook == 0)
       {
        //生成一个HookProc的实例.
        MouseHookProcedure = new HookProc(MouseHookProc);
        hMouseHook = SetWindowsHookEx( WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
      //如果装置失败停止钩子
        if(hMouseHook == 0 ) 
        {
         Stop();
         throw new Exception("SetWindowsHookEx failed.");
        }
       }
      }
      public void Stop()
      {
       bool retMouse =true;
       if(hMouseHook != 0)
       {
        retMouse = UnhookWindowsHookEx(hMouseHook);
        hMouseHook = 0;
       } 
       
       //如果卸下钩子失败
       if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed.");
      }
      private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
      {
       //如果正常运行并且用户要监听鼠标的消息
       if ((nCode >= 0) && (OnMouseActivity!=null)) 
       { 
        MouseButtons button=MouseButtons.None;
        int clickCount=0;
        switch (wParam)
        {
         case WM_LBUTTONDOWN: 
          button=MouseButtons.Left; 
          clickCount=1;
          break;
         case WM_LBUTTONUP: 
          button=MouseButtons.Left; 
          clickCount=1;
          break;
         case WM_LBUTTONDBLCLK: 
          button=MouseButtons.Left; 
          clickCount=2;
          break;
         case WM_RBUTTONDOWN: 
          button=MouseButtons.Right; 
          clickCount=1;
          break;
         case WM_RBUTTONUP: 
          button=MouseButtons.Right; 
          clickCount=1;
          break;
         case WM_RBUTTONDBLCLK: 
          button=MouseButtons.Right; 
          clickCount=2;
          break;
        }
        //从回调函数中得到鼠标的信息
        MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
        MouseEventArgs e=new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0 );
        OnMouseActivity(this, e);
       }
       return CallNextHookEx(hMouseHook, nCode, wParam, lParam); 
      }
     }
    }
    得到键盘消息的类:
    using System;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Threading;
    using System.Windows.Forms;
    namespace HookGlobal
    {
     
     /// <summary>
     /// 这个类可以让你得到一个在运行中程序的所有键盘或鼠标事件
     /// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息
     /// </summary>
     /// <res>
     ///  修改:lihx
     ///  修改时间:04.11.8
     /// </res>
     public class KeyBordHook
     {
      private const int WM_KEYDOWN   = 0x100;
      

  3.   

    private const int WM_KEYUP    = 0x101;
      private const int WM_SYSKEYDOWN  = 0x104;
      private const int WM_SYSKEYUP   = 0x105;
      
      //全局的事件
      public event KeyEventHandler OnKeyDownEvent;
      public event KeyEventHandler OnKeyUpEvent;
      public event KeyPressEventHandler OnKeyPressEvent;
      static int hKeyboardHook = 0; //键盘钩子句柄
      //鼠标常量
      public const int WH_KEYBOARD_LL = 13; //keyboard hook constant 
      HookProc KeyboardHookProcedure; //声明键盘钩子事件类型.
      //声明键盘钩子的封送结构类型
      [StructLayout(LayoutKind.Sequential)]
       public class KeyboardHookStruct
      {
       public int vkCode; //表示一个在1到254间的虚似键盘码
       public int scanCode; //表示硬件扫描码
       public int flags;  
       public int time; 
       public int dwExtraInfo;
      }
      //装置钩子的函数
      [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, Int32 wParam, IntPtr lParam);  
      [DllImport("user32")] 
      public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState,byte[] lpwTransKey, int fuState);
      [DllImport("user32")] 
      public static extern int GetKeyboardState(byte[] pbKeyState);
      public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
      /// <summary>
      /// 墨认的构造函数构造当前类的实例并自动的运行起来.
      /// </summary>
      public KeyBordHook() 
      {
       Start();
      }
      //析构函数.
      ~KeyBordHook() 
      { 
       Stop();
      } 
      public void Start()
      {
       //安装键盘钩子 
       if(hKeyboardHook == 0)
       {
        KeyboardHookProcedure = new HookProc(KeyboardHookProc);
        hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
        if(hKeyboardHook == 0 ) 
        {
         Stop();
         throw new Exception("SetWindowsHookEx ist failed.");
        }
       }
      }
      public void Stop()
      {
       bool retKeyboard = true;
       
       if(hKeyboardHook != 0)
       {
        retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
        hKeyboardHook = 0;
       } 
      //如果卸下钩子失败
       if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
      }
      private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
      {
       if ((nCode >= 0) && (OnKeyDownEvent!=null || OnKeyUpEvent!=null || OnKeyPressEvent!=null))
       {
        KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
        //引发OnKeyDownEvent
        if ( OnKeyDownEvent!=null && ( wParam ==WM_KEYDOWN || wParam==WM_SYSKEYDOWN ))
        {
         Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
         KeyEventArgs e = new KeyEventArgs(keyData);
         OnKeyDownEvent(this, e);
        }
        
        //引发OnKeyPressEvent
        if ( OnKeyPressEvent!=null &&  wParam ==WM_KEYDOWN )
        {
         byte[] keyState = new byte[256];
         GetKeyboardState(keyState);
         byte[] inBuffer= new byte[2];
         if (ToAscii(MyKeyboardHookStruct.vkCode,
          MyKeyboardHookStruct.scanCode,
          keyState,
          inBuffer,
          MyKeyboardHookStruct.flags)==1) 
         {
          KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
          OnKeyPressEvent(this, e);
         }
        }
        
        //引发OnKeyUpEvent
        if ( OnKeyUpEvent!=null && ( wParam ==WM_KEYUP || wParam==WM_SYSKEYUP ))
        {
         Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
         KeyEventArgs e = new KeyEventArgs(keyData);
         OnKeyUpEvent(this, e);
        }
       }
       return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); 
      }
     }
    }
      

  4.   

    [StructLayout(LayoutKind.Sequential)]
    这个是什么意思啊!什么布局啊.
      

  5.   

    [StructLayout(LayoutKind.Sequential)]
    ---------
    控制结构中各类型参数按出现的次序在内存中依次排列,这是Attribute属性的应用,在托管代码调用非托管代码时经常用的
      

  6.   

    我这个和你类似:
    http://community.csdn.net/Expert/topic/5221/5221453.xml?temp=.9955713
    已经解决了
      

  7.   

    [LayoutKind.Sequential 用于强制将成员按其出现的顺序进行顺序布局。
     [LayoutKind.Explicit] 用于控制每个数据成员的精确位置。
      

  8.   

    在.NET中并不支持全局的Hook,所以我不建议使用Hook。
    你可以通过应用程序一级的消息来得到对按键的处理。比如通过MessageFilter来对应用程序的每一个消息进行处理,可以参考下面的例子不用任何API就可以做到:using System;
    using System.Collections.Generic;
    using System.Windows.Forms;namespace AddMessageFilterApp
    {
    static class Program
    {
    class MsgFilter : IMessageFilter
    {
    public bool PreFilterMessage(ref Message m)
    {
    if (m.Msg == 0x100 && m.WParam == (IntPtr)0x11) //(WM_RBUTTONDOWN)
    {
    System.Console.WriteLine(m);
    }
    else if (m.Msg == 0x100)//WM_KEYDOWN
    {
    System.Console.WriteLine(m);
    }
    else if (m.Msg == 0x101)//WM_KEYUP
    {
    System.Console.WriteLine(m);
    }
    else if (m.Msg == 102)//WM_CHAR
    {
    System.Console.WriteLine(m);
    }
    return false;
    }
    } /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main()
    {
    Application.EnableVisualStyles();
    MsgFilter ms=new MsgFilter();
    Application.AddMessageFilter(ms);
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
    Application.RemoveMessageFilter(ms);
    }
    }
    }