锁屏并不是一个很难的功能,初步想了一下觉得这样,其实未必……本文是我琢磨了好几天下来的成果,而且只是“初级”的,对Windows Mobile不够熟,没人辅导,真是累啊。
先给读者些感性认识,这是我手机上Windows Mobile 6.1默认的锁屏程序:
![](http://www.cppblog.com/images/cppblog_com/guogangj/lockscreen1_1.png)
虽然说是锁屏,其实是连键盘一块儿锁了,真正的英文名称是叫“Lock Device”的,锁设备。锁了之后,你碰一碰键盘上其它按键,大致就这样显示:
![](http://www.cppblog.com/images/cppblog_com/guogangj/lockscreen1_2.png)
表示你要继续使用设备的话,得先“解锁”。
从按键盘按键设备还有反应这点上看,所谓锁屏其实并没有真正屏蔽掉所有按键,只是对这些按键进行了一些别的处理而已。
但无疑这个锁屏太土了,很多人不喜欢,所以才有了别的锁屏软件,比如下面这个叫S2U2,这是个免费软件,好评率还蛮高的,这是它默认的锁屏界面,其实界面还是可以定制的,可以弄得很漂亮:
![](http://www.cppblog.com/images/cppblog_com/guogangj/lockscreen1_3.png)
这个软件的“锁屏”方式跟系统默认的就有所不同了,它貌似屏蔽了所有的键盘按键,只能通过滑动屏幕上的那个滑块来解锁。
现在接下来找个Windows Mobile 6.5的手机看看。
![](http://www.cppblog.com/images/cppblog_com/guogangj/lockscreen1_4.png)
更好看一些,我稍微研究了一下6.5的锁屏,其实也并非屏蔽所有按键,你可以这么试验一下:隐藏所有窗口,在“今日”下锁屏,然后按一下绿色的电话键,然后解锁。你就会发觉屏幕显示的不是“今日”,而是拨号面板,说明电话键还是起作用了,但我尝试下来挂机键却没起作用。
如果上面这些问题你都不认为是什么问题,那么处理来电消息的问题呢?有没想过。默认情况下,电话一来,系统会弹出消息框,键盘自动解锁,但这很容易引起误操作,所以我看见HTC的锁屏就很好地处理了这个问题,它需要用户在屏幕上划一下,才解锁,虽然有的用户会嫌麻烦,但我想总比误接听好吧?
现在你认识到了吧,“锁”,不是简单的锁而已。
前面是不是说得有点多了,所以本文显得有些头重脚轻,因为我目前实现的只有“初级”,所以内容还不是很多。
首先是锁键盘,锁屏时候屏蔽所有按键,这个可以用钩子,关于Windows Mobile上的钩子,网上文章有不少,但你看完后发觉都是抄来抄去的,烦都烦死,原作我找了一下,很可能(不是100%)是来自这里:
http://www.codeproject.com/KB/windows/wincekbhook.aspx,而且,目前只能设置WH_KEYBOARD_LL类型的钩子,WH_KEYBOARD_LL被define为20,这个跟Windows系统还不一样,不过也不能怪Microsoft,因为hook在Windows Mobile中本来就是undefined的,不推荐使用。而且我在使用钩子的过程中遇到了问题,就是钩子对我的手机Samsung i780完全无效,(而模拟器还有另外两台多普达的机器是没问题的)当然了,安装钩子的时候我查看过返回值,都是正常的,只是hook不到任何键盘消息,我的手机上出现了这种情况,这也意味着别的手机也可能出现。
![](http://www.cppblog.com/images/cppblog_com/guogangj/lockscreen1_5.png)
折腾了许久之后,(我还尝试了另外好几种方法,但都不理想)我终于找到了解决方案,那就是从GAPI中分离出来的一个API,AllKeys,在本地的MSDN中是找不到这个函数的,但通过在线的MSDN很快就能找到这个函数的说明,用起来十分十分简单,完全能达到我的功能要求,而且对我的Samsung i780是有效的!
键盘解决了,然后是来电处理,来电时候我目前的处理跟系统默认的一样,一来电,就立即自动解锁键盘,并且显示电话拨号面板,电话结束后再自动锁上,这样做虽然不是很好,但至少可以接受。那就要处理来电和挂断消息了,一开始打算用TAPI,网上很多人也都这么说的,但TAPI非常复杂,功能很强大,而我需要的仅仅是得到通知这么一个功能,有点牛刀杀鸡的感觉,而TAPI还有个问题,就是貌似它具有“独占性”,我的程序一旦占据了电话,别的程序要用电话就可能有问题了,这个我没深入研究。
最后我采用的方法是注册系统通知消息,RegistryNotifyWindow,现在把关键代码贴出来:
#define WM_USER_TELEPHONE_STATE (WM_USER+1086)
//WM_CREATE
//Register the notification for monitoring the telephone state.
RegistryNotifyWindow(SN_PHONEINCOMINGCALL_ROOT, //defined in snapi.h
SN_PHONEINCOMINGCALL_PATH, SN_PHONEINCOMINGCALL_VALUE, hWnd, //handle to our window to receive msg
WM_USER_TELEPHONE_STATE, //app defined message to send
NULL, //app defined value
NULL, &g_hregNotifyPhone);
//![](http://www.cppblog.com/Images/dot.gif)
![](http://www.cppblog.com/Images/dot.gif)
//Phone state changed!
case WM_USER_TELEPHONE_STATE:
if ((wParam&SN_PHONEINCOMINGCALL_BITMASK)==SN_PHONEINCOMINGCALL_BITMASK
|| (wParam&SN_PHONECALLTALKING_BITMASK)==SN_PHONECALLTALKING_BITMASK)
{
AllKeys(FALSE);
ShowWindow(hWnd, SW_HIDE);
}
else
{
AllKeys(TRUE);
ShowWindow(hWnd, SW_SHOW);
SHFullScreen(hWnd, SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
SetForegroundWindow(hWnd);
}
break;
代码看起来简单,我却研究了许久……这样实现的功能就是来电时候锁屏窗口隐藏,解锁键盘,让系统默认程序接管,电话结束时候重新show出窗口,继续锁屏。其余细节代码就不贴了,虽然细节还有很多,但大致就这些,要真正弄出跟HTC那样的锁屏,还有很多要研究的。下次有机会我再写吧,当然前提是我已经研究出来之后。