您的位置:首页 > 编程语言 > C#

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

2007-08-25 00:10 344 查看
最近做了一个智能设备开发的项目,用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中就能够将硬件按键事件注册到应用的主窗体中,执行自己需要的逻辑。终于写完了,不知道是否有用,是否说清楚了,如果有不明欢迎骚扰!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: