改善Single-Finger移動流覽體驗
如果您建置以 Windows Touch 為目標的應用程式,它會自動提供基本的移動流覽支援。 不過,您可以使用 WM_GESTURE 訊息來提供單指移動流覽的增強支援。
概觀
若要改善單指移動流覽體驗,請使用下列步驟,如本主題後續各節所述:
- 建立具有捲軸且已停用閃爍的應用程式。
- 新增對手勢移動流覽訊息的支援。
- 啟用退回。
建立具有捲軸且已停用閃爍的應用程式
開始之前,您必須建立具有捲軸的應用程式。 使用 捲軸進行移動流覽的舊版支援 一節將說明此程式。 如果您想要從範例內容開始,請移至該區段,並使用捲軸建立應用程式,然後停用閃爍。 如果您已經有具有運作中捲軸的應用程式,請停用該區段中所述的閃爍。
新增手勢移動流覽訊息的自訂移動流覽支援
若要支援手勢移動流覽訊息,您必須在 WndProc 方法中處理它們。 手勢訊息可用來判斷移動流覽訊息的水準和垂直差異。 差異可用來更新捲軸物件,以更新使用者介面。
首先,更新 targetver.h 檔案中的 Windows 版本設定,以啟用 Windows Touch。 下列程式碼顯示應該取代 targetver.h 中各種 Windows 版本設定。
#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
接下來,將 UXTheme.h 檔案新增至您的專案,並將 uxtheme.lib 程式庫新增至專案的其他相依性。
#include <uxtheme.h>
接下來,將下列變數新增至 WndProc 函式的頂端。 這些會用於移動流覽的計算中。
// The following are used for the custom panning handler
BOOL bResult = FALSE;
static int scale = 8; // altering the scale value will change how fast the page scrolls
static int lastY = 0; // used for panning calculations (initial / previous vertical position)
static int lastX = 0; // used for panning calculations (initial / previous horizontal position)
GESTUREINFO gi;
接下來,新增 WM_GESTURE 訊息的處理常式,以便根據移動流覽手勢以差異更新捲軸。 這可讓您更精細地控制移動流覽。
下列程式碼會從lParam取得GESTUREINFO結構、從 結構儲存最後一個 Y 座標,並判斷位置變更以更新捲軸物件。 下列程式碼應該放在 WndProc switch 語句中。
case WM_GESTURE:
// Get all the vertial scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(GESTUREINFO);
bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
if (bResult){
// now interpret the gesture
switch (gi.dwID){
case GID_BEGIN:
lastY = gi.ptsLocation.y;
CloseGestureInfoHandle((HGESTUREINFO)lParam);
break;
// A CUSTOM PAN HANDLER
// COMMENT THIS CASE OUT TO ENABLE DEFAULT HANDLER BEHAVIOR
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin || si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom / top, pan
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
case GID_ZOOM:
// Add Zoom handler
return DefWindowProc(hWnd, message, lParam, wParam);
default:
// You have encountered an unknown gesture
return DefWindowProc(hWnd, message, lParam, wParam);
}
}else{
DWORD dwErr = GetLastError();
if (dwErr > 0){
// something is wrong
// 87 indicates that you are probably using a bad
// value for the gi.cbSize
}
}
return DefWindowProc (hWnd, message, wParam, lParam);
現在,當您在視窗上執行移動流覽手勢時,您會看到具有慣性的文字捲動。 此時,您可能會想要將文字變更為有更多行,以便探索移動流覽大型文字區段。
WndProc 中的界限意見反應
界限意見反應是當使用者到達可移動流覽區域結束時,提供給使用者的視覺意見反應類型。 達到界限時,應用程式會觸發它。 在先前WM_GESTURE訊息的範例實作中,會使用WM_GESTURE案例中的結束條件 (si.nPos == si.yPos)
來測試您已到達可移動流覽區域的結尾。 下列變數可用來追蹤值和測試錯誤。
// The following are used for panning feedback (Window Bounce)
static int animCount = 0;
static DWORD dwErr = 0;
static BOOL isOverpan = FALSE;
static long xOverpan = 0;
static long yOverpan = 0;
移動流覽手勢案例會更新為觸發界限意見反應。 下列程式碼說明來自 WM_GESTURE 訊息處理常式 GID_PAN 案例。
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin){
// we reached the top, pan upwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}else if (si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom, pan downwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
現在,當使用者移動流覽超過捲軸區域底部時,應用程式視窗應該會有界限意見反應。
相關主題