c#在智能设备开发中截获PPC(PocketPC)硬件按钮事件

最近做了一个智能设备开发的项目,用c#,其中不免会遇到一些问题,我近期准备将这些问题总结一下,共大家参考,在以后的开发中少走弯路。
我们在这个项目中,需要在应用程序中截获PPC的硬件按钮事件,大家可能首先想到的KeyDown和KeyUp事件,但是大家可以试验一下,这只能截获到中间的导航键的消息,其他的按钮不能正常截获。接下来,我在internet上一顿google,找到一些答案,但是都是不全,所以特将这些资料汇总,拿出来共享。
如果想PPC截获硬件按钮事件,需要以下几步:
1.         组合键常量和硬件按键常量。它们配合上面的api使用。
2.         几个api函数,这些api函数可以注册热键到你的应用中,它们是:RegisterHotKey,UnregisterHotKey,UnregisterFunc1(据说这个是未公开的接口函数)它们都在”coredll.dll”中,它们的参数和用法在以下的例子中说明。
3.         有了以上的准备,最后一步就要重写应用主窗体的消息循环函数wndproc,截获WM_HOTKEY消息。
为了重用,我们都以类的方式提供,代码及说明如下:
 
//第一步常量类,声明virsual key 的组合键常量
public class KeyModifers
 {
    public const uint MOD_ALT = 0x1;
    public const uint MOD_CONTROL = 0x2;
    public const uint MOD_SHIFT = 0x4;
    public const uint MOD_WIN = 0x8;
 }
//声明硬件按键常量 只能是这几个值
public class KeysHardware
 {
    public const uint Hardware1 = 193;
    public const uint Hardware2 = 194;
    public const uint Hardware3 = 195;
    public const uint Hardware4 = 196;
    public const uint Hardware5 = 197;
 }
 
//第二步,封装两个api函数,调用非托管dll函数类
 public class RegisterHotKeys
 {
    //声明aapi
    [DllImport("coredll.dll")]
private static extern bool UnregisterFunc1(
uint fsModifiers, //组合键的键值
uint vk //热键键值
);
 
    [DllImport("coredll.dll")]
    private static extern bool RegisterHotKey(
     IntPtr hWnd, //要注册的窗体的句柄
     int id, // 热键的键值
     uint fsModifiers, //组合键的键值
     uint vk // virtual-key code (虚拟键的编码,这里和第二个参数一样)
    );
 
    [DllImport("coredll.dll")]
    private static extern bool UnregisterHotKey(
     IntPtr hWnd, //要注册的窗体的句柄
     int id //热键的键值
    );
    //end
 
    //注册热键,封装了UnregisterFunc1和RegisterHotKey
    private static bool _mRegisterHotKey(IntPtr hwnd, int id, uint vk)
    {
      bool re = UnregisterFunc1(KeyModifers.MOD_WIN, vk);
      bool re1 = RegisterHotKey(hwnd, id, KeyModifers.MOD_WIN, vk);
      return re && re1;
    }
 
   public static bool RegisterHotKey(IntPtr hwnd)
    {
      bool re = true;
      for (int i = (int)KeysHardware.Hardware1; i <= (int)KeysHardware.Hardware5; i++)
      {
        re = _mRegisterHotKey(hwnd, i, (uint)i);
        if (!re) break;
      }
      return re;
    }
 
    public static bool UnRegisterHotKey(IntPtr hwnd)
    {
      bool re = true;
      for (int i = (int)KeysHardware.Hardware1; i <= (int)KeysHardware.Hardware5; i++)
      {
        UnregisterHotKey(hwnd, i);
        if (!re) break;
      }
      return re;
    }
 
 }//大家可以看到这个类只有两个public函数,其他的函数对外不提供,为内部服务
//第三步重写消息循环,定义消息窗体,并重写wndproc方法
public class MyMsgWindow : MessageWindow
 {
    public const int WM_HOTKEY = 0x0312;
    private TestForm form = null; //TestForm为你的热键要注册的应用主窗体
 
   public MyMsgWindow(TestForm form)
    {
      this.form = form;
    }
    protected override void WndProc(ref Message msg)
    {
      switch (msg.Msg)
      {
        case WM_HOTKEY:
          form.clickHardWareButton(msg.WParam.ToInt32());//clickHardWareButton是你在主窗体中定义的按钮事件函数,在这里被调用
          return;
      }
      base.WndProc(ref msg);
    }
 }
我的事例中主窗体为TestForm,它是怎么和MessageWindow关联的呢?很简单,在TestForm的构造函数中这样写:
public class TestForm : System.Windows.Forms.Form
 {
public TestForm()
    {
      InitializeComponent();
      //以下是我添加的代码
      mmw = new MyMsgWindow(this);//主窗体被传入MessageWindow中, 主窗体中的
//消息循环按照新的消息循环执行
      if (!RegisterHotKeys.RegisterHotKey(mmw.Hwnd))
        MessageBox.Show("register hot key error");
}
public void clickHardWareButton(int value)//消息循环执行的函数
{
      if ((value >= 0xc1) && (value <= 0xcf))
      {
        MessageBox.Show(value.ToString());
      }
 }
        //窗体关闭时,卸载注册的热键
    Private void TestForm_Closing(object sender,     System.ComponentModel.CancelEventArgs e)
      {
      RegisterHotKeys.UnRegisterHotKey1(mmw.Hwnd);
      }
……
  }

这样在PPC中就能够将硬件按键事件注册到应用的主窗体中,执行自己需要的逻辑。终于写完了,不知道是否有用,是否说清楚了,如果有不明欢迎骚扰!
 
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页