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

最近做了一个智能设备开发的项目,用c#,其中不免会遇到一些问题,我近期准备将这些问题总结一下,共大家参考,在以后的开发中少走弯路。
我们在这个项目中,需要在应用程序中截获PPC的硬件按钮事件,大家可能首先想到的KeyDown和KeyUp事件,但是大家可以试验一下,这只能截获到中间的导航键的消息,其他的按钮不能正常截获。接下来,我在internet上一顿google,找到一些答案,但是都是不全,所以特将这些资料汇总,拿出来共享。

如果想PPC截获硬件按钮事件,需要以下几步:

1.         组合键常量和硬件按键常量。它们配合上面的api使用。

2.         几个api函数,这些api函数可以注册热键到你的应用中,它们是:RegisterHotKeyUnregisterHotKeyUnregisterFunc1(据说这个是未公开的接口函数)它们都在”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;

  }

<?XML:NAMESPACE PREFIX = O />

 

//第二步,封装两个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

 

    //注册热键,封装了UnregisterFunc1RegisterHotKey

    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中就能够将硬件按键事件注册到应用的主窗体中,执行自己需要的逻辑。终于写完了,不知道是否有用,是否说清楚了,如果有不明欢迎骚扰!




添加的方法:首先在右键点击项目的引用-》添加引用,在.net中找到Microsoft.WindowsCE.Forms,添加,然后再你的.cs文件中在useing这个命名空间,就可以继承MessageWindow,重写WndProc方法了。
# wuyazhe 发表于2008-06-20 23:31:40  IP: 58.248.7.*
你好。这样做确实是可以实现效果。但显然不是最好办法。当然我也没更好办法。

对于快捷键。我的想法是自己做快捷键类。我就是都添加keyup,事件。递归父类子类,但是效果。貌似有些地方不可以用。打算用RegistHotkey。是这个大家都想的到。但是不知道如何捕获消息。wince下不支持IMessageFilter这个接口。你用的这个MessageWindow虽然也可以。但多少感觉这样会多一个window。这都不是主要的。最重要的是需要添加Microsoft.WindowsCE.Forms这个引用。添加了这个引用的就不可以在pc上用了。我自己的程序,都写成:

public static void Postmessage(...)
{
if(Envirment.OsVersion.PlatformID == PlatForm.Wince)
{
PostMessageCE(...);
}
else
{
PostMessagePC(...);
}

[...coredll.dll]
public extern void PostMessageCE(...)

[kernal32.dll]
public extern void PostMessagePC(...)
}

这样的。

我就希望可以写一次程序,在wince,pc上都可以运行的。所以,我不想用那个dll。

那么,我的选择就是2个,
1.用键盘钩子
2.自己重写Application.Run方法,也就是重写Application类。

方法1因为麻烦点。还没尝试。方法2是没弄成功。可以启动。但不能结束。诶。。。。



呵呵。有兴趣的话。交流一下啊。我的email:wuyazhe@yeah.net


QQ:32610303


对了。请注明:ppc 同行

转载于:https://www.cnblogs.com/jiangchao/archive/2008/11/28/1343204.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值