Win7有一些酷炫的功能是XP、Vista系統沒有的,例如窗口分組預覽、快速隱藏桌面圖標、搖走其他窗口……這些酷炫的功能是怎麼設計的?我們開發的個人軟件如何使用這些功能,給用戶帶來驚喜?
在《少數派報告》中阿湯哥直接用雙指在觸摸屏上操作程序,酷斃了。這種功能Win 7也支持,只要有觸摸設備,我們也可以在Win7上用雙手玩轉電腦。雙指觸控如縮放、雙指放大、雙指翻頁等特效都可以在Win 7中實現。
Win7常用的兩種觸控手勢
1.縮放手勢
縮放手勢用於界面放大或縮小,在浏覽圖片、文章閱讀等程序中常常會用到。雙指縮放的手勢如圖1所示:雙指並攏置於窗體中,一指向上滑動,一指向下滑動,這是放大,雙指分開置於窗體上,兩指向中間滑動,則是縮小。
程序要識別出這個手勢,第一步,要得到手指點到屏幕的消息。第二步,根據兩指的坐標計算出距離,根據一個經驗值對兩指距離進行比較,來得到這是兩指分開或兩指並攏。第三步,可以根據一個定時器來實時捕捉手指點的坐標,來計算出移動方向及速率,進一步就可判斷出兩指是反向滑動還是相向滑動。
2.平移手勢
平移手勢往往用於導航。例如在一個圖片查看程序中,使用向左平移手勢可以導航到上一張,使用向右平移手勢導航到下一張圖片。平移手勢如圖2所示:雙指同時向左滑動,或向右滑動。如何區分用戶是要改變圖片的位置還是翻頁呢?這裡必須使用到加速度。
可以在一個定時器中實時捕捉手指坐標,計算出速率和加速度,可以通過一個經驗值去和加速度比較,當加速度比較大的時候,可以認為是翻頁,反之則是拖動。當然,這還不夠,當拖動時,還需要進一步判斷是否到達程序邊界,如果到達邊界,也認為是翻頁。對於翻頁的處理,向左快速移動或到達左邊界,則認為是上一頁。
雙指觸控API揭秘
雙指觸控的核心是把原始觸摸數據放入運動模型中去計算,以識別出用戶的手勢。原始觸摸數據可以從WM_TOUCH消息中得到。通過WM_TOUCH識別出縮放和平移手勢。
第一步:檢查多點觸控硬件
這裡使用GetSystemMetrics API來獲取硬件是不是就緒:
BYTE digitizerStatus = (BYTE)GetSystemMetrics(SM_DIGITIZER);
if ((digitizerStatus & (0x80 + 0x40)) == 0){
//沒檢測到多點觸控設備或設備沒有就緒
}
//檢查設備支持幾個觸摸點,需要注意的是目前Win 7對2個觸摸點支持得比較好
BYTE nInputs = (BYTE)GetSystemMetrics(SM_MAXIMUMTOUCHES);
第二步:切換到原始觸摸消息
在默認情況下,Win 7默認提供 WM_GESTURE(手勢)消息。這個手勢是系統根據原始觸摸數據來識別的手勢,使用 RegisterTouchWindow API函數可讓系統返回WM_TOUCH原始觸摸輸入消息,核心代碼:
RegisterTouchWindow(hWnd, 0)) //hwnd為當前窗口的句柄。
第三步:得到原始觸摸數據
使用GetTouchInputInfo API得到原始觸摸數據,核心代碼:
GetTouchInputInfo((HTOUCHINPUT)lParam,numInputs,ti,sizeof(TOUCHINPUT)))
numInputs為預先聲明的變量,用於存儲有幾個觸摸點,如果是5個手指同時在屏幕滑動,那麼numInputs就為5。
ti是TOUCHINPUT結構,其包含了觸點的X和Y坐標、發生時間、觸摸類型(類似於鼠標按下、鼠標移動、鼠標釋放等)。
for(unsigned int i=0; i<numInputs; ++i){ //根據觸摸輸入點循環
if (ti[i].dwFlags & TOUCHEVENTF_DOWN){
OnTouchDownHandler(hWnd, ti[i]);//交給觸點按下函數處理
}else if (ti[i].dwFlags & TOUCHEVENTF_MOVE){
OnTouchMoveHandler(hWnd, ti[i]);//交給觸點移動函數處理
}else if (ti[i].dwFlags & TOUCHEVENTF_UP){
OnTouchUpHandler(hWnd, ti[i]);} //交給觸點釋放函數處理
}
這裡的觸點按下、移動、釋放等函數,實際上是一個運動仿真模型,我們在模型中,要將觸點的軌跡生成若干條運動曲線,並計算出每個點的方位角、速率、法向加速度、切向加速度等,以識別出具體的手勢。
小知識:讓程序支持多點觸控最簡單的方法是用Win 7的手勢識別功能,主要用到以下API:
GetSystemMetrics,用於檢查多點觸控硬件設備是否存在並就緒。
GetGestureInfo,用於獲取手勢類型及相關數據