鎖屏并不是一個(gè)很難的功能,初步想了一下覺得這樣,其實(shí)未必……本文是我琢磨了好幾天下來的成果,而且只是“初級(jí)”的,對(duì)Windows Mobile不夠熟,沒人輔導(dǎo),真是累啊。
先給讀者些感性認(rèn)識(shí),這是我手機(jī)上Windows Mobile 6.1默認(rèn)的鎖屏程序:

雖然說是鎖屏,其實(shí)是連鍵盤一塊兒鎖了,真正的英文名稱是叫“Lock Device”的,鎖設(shè)備。鎖了之后,你碰一碰鍵盤上其它按鍵,大致就這樣顯示:

表示你要繼續(xù)使用設(shè)備的話,得先“解鎖”。
從按鍵盤按鍵設(shè)備還有反應(yīng)這點(diǎn)上看,所謂鎖屏其實(shí)并沒有真正屏蔽掉所有按鍵,只是對(duì)這些按鍵進(jìn)行了一些別的處理而已。
但無疑這個(gè)鎖屏太土了,很多人不喜歡,所以才有了別的鎖屏軟件,比如下面這個(gè)叫S2U2,這是個(gè)免費(fèi)軟件,好評(píng)率還蠻高的,這是它默認(rèn)的鎖屏界面,其實(shí)界面還是可以定制的,可以弄得很漂亮:

這個(gè)軟件的“鎖屏”方式跟系統(tǒng)默認(rèn)的就有所不同了,它貌似屏蔽了所有的鍵盤按鍵,只能通過滑動(dòng)屏幕上的那個(gè)滑塊來解鎖。
現(xiàn)在接下來找個(gè)Windows Mobile 6.5的手機(jī)看看。

更好看一些,我稍微研究了一下6.5的鎖屏,其實(shí)也并非屏蔽所有按鍵,你可以這么試驗(yàn)一下:隱藏所有窗口,在“今日”下鎖屏,然后按一下綠色的電話鍵,然后解鎖。你就會(huì)發(fā)覺屏幕顯示的不是“今日”,而是撥號(hào)面板,說明電話鍵還是起作用了,但我嘗試下來掛機(jī)鍵卻沒起作用。
如果上面這些問題你都不認(rèn)為是什么問題,那么處理來電消息的問題呢?有沒想過。默認(rèn)情況下,電話一來,系統(tǒng)會(huì)彈出消息框,鍵盤自動(dòng)解鎖,但這很容易引起誤操作,所以我看見HTC的鎖屏就很好地處理了這個(gè)問題,它需要用戶在屏幕上劃一下,才解鎖,雖然有的用戶會(huì)嫌麻煩,但我想總比誤接聽好吧?
現(xiàn)在你認(rèn)識(shí)到了吧,“鎖”,不是簡(jiǎn)單的鎖而已。
前面是不是說得有點(diǎn)多了,所以本文顯得有些頭重腳輕,因?yàn)槲夷壳皩?shí)現(xiàn)的只有“初級(jí)”,所以內(nèi)容還不是很多。
首先是鎖鍵盤,鎖屏?xí)r候屏蔽所有按鍵,這個(gè)可以用鉤子,關(guān)于Windows Mobile上的鉤子,網(wǎng)上文章有不少,但你看完后發(fā)覺都是抄來抄去的,煩都煩死,原作我找了一下,很可能(不是100%)是來自這里:
http://www.codeproject.com/KB/windows/wincekbhook.aspx,而且,目前只能設(shè)置WH_KEYBOARD_LL類型的鉤子,WH_KEYBOARD_LL被define為20,這個(gè)跟Windows系統(tǒng)還不一樣,不過也不能怪Microsoft,因?yàn)閔ook在Windows Mobile中本來就是undefined的,不推薦使用。而且我在使用鉤子的過程中遇到了問題,就是鉤子對(duì)我的手機(jī)Samsung i780完全無效,(而模擬器還有另外兩臺(tái)多普達(dá)的機(jī)器是沒問題的)當(dāng)然了,安裝鉤子的時(shí)候我查看過返回值,都是正常的,只是hook不到任何鍵盤消息,我的手機(jī)上出現(xiàn)了這種情況,這也意味著別的手機(jī)也可能出現(xiàn)。

折騰了許久之后,(我還嘗試了另外好幾種方法,但都不理想)我終于找到了解決方案,那就是從GAPI中分離出來的一個(gè)API,AllKeys,在本地的MSDN中是找不到這個(gè)函數(shù)的,但通過在線的MSDN很快就能找到這個(gè)函數(shù)的說明,用起來十分十分簡(jiǎn)單,完全能達(dá)到我的功能要求,而且對(duì)我的Samsung i780是有效的!
鍵盤解決了,然后是來電處理,來電時(shí)候我目前的處理跟系統(tǒng)默認(rèn)的一樣,一來電,就立即自動(dòng)解鎖鍵盤,并且顯示電話撥號(hào)面板,電話結(jié)束后再自動(dòng)鎖上,這樣做雖然不是很好,但至少可以接受。那就要處理來電和掛斷消息了,一開始打算用TAPI,網(wǎng)上很多人也都這么說的,但TAPI非常復(fù)雜,功能很強(qiáng)大,而我需要的僅僅是得到通知這么一個(gè)功能,有點(diǎn)牛刀殺雞的感覺,而TAPI還有個(gè)問題,就是貌似它具有“獨(dú)占性”,我的程序一旦占據(jù)了電話,別的程序要用電話就可能有問題了,這個(gè)我沒深入研究。
最后我采用的方法是注冊(cè)系統(tǒng)通知消息,RegistryNotifyWindow,現(xiàn)在把關(guān)鍵代碼貼出來:
#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);
//

//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;
代碼看起來簡(jiǎn)單,我卻研究了許久……這樣實(shí)現(xiàn)的功能就是來電時(shí)候鎖屏窗口隱藏,解鎖鍵盤,讓系統(tǒng)默認(rèn)程序接管,電話結(jié)束時(shí)候重新show出窗口,繼續(xù)鎖屏。其余細(xì)節(jié)代碼就不貼了,雖然細(xì)節(jié)還有很多,但大致就這些,要真正弄出跟HTC那樣的鎖屏,還有很多要研究的。下次有機(jī)會(huì)我再寫吧,當(dāng)然前提是我已經(jīng)研究出來之后。