在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近做了一个智能设备开发的项目,用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); ……
|
请发表评论