使用捲軸移動流覽的舊版支援
本節說明在 Windows 應用程式中使用捲軸進行移動流覽的支援。
在 Windows 7 中,移動流覽手勢會產生WM_*SCROLL 訊息,以啟用移動流覽的舊版支援。 因為您的應用程式可能不支援所有WM_*SCROLL 訊息,所以移動流覽可能無法正常運作。 本主題描述您必須採取的步驟,以確保應用程式中的舊版移動流覽體驗如使用者預期般運作。
概觀
下列各節說明如何啟用舊版移動流覽體驗:
- 使用捲軸建立應用程式。
- 停用筆動。
- 自訂移動流覽體驗。
使用捲軸建立應用程式
使用 Microsoft Visual Studio 精靈啟動新的 Win32 專案。 請確定應用程式類型已設定為 Windows 應用程式。 您不需要啟用 Active Template Library (ATL) 的支援。 下圖顯示專案在您啟動專案之後的外觀。
接下來,在影像上啟用捲軸。 變更 InitInstance 中的視窗建立程式碼,讓 CreateWindow 函式呼叫建立具有捲軸的視窗。 下列程式碼示範如何執行這項操作。
hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // style
200, // x
200, // y
550, // width
300, // height
NULL,
NULL,
hInstance,
NULL
);
變更視窗建立程式碼之後,您的應用程式會有捲軸。 下圖顯示應用程式可能在此時間點的外觀。
變更視窗建立程式碼之後,請將捲軸物件新增至您的應用程式,以及一些要捲動的文字。 將下列程式碼放在 WndProc 方法的頂端。
TEXTMETRIC tm;
SCROLLINFO si;
// These variables are required to display text.
static int xClient; // width of client area
static int yClient; // height of client area
static int xClientMax; // maximum width of client area
static int xChar; // horizontal scrolling unit
static int yChar; // vertical scrolling unit
static int xUpper; // average width of uppercase letters
static int xPos; // current horizontal scrolling position
static int yPos; // current vertical scrolling position
int i; // loop counter
int x, y; // horizontal and vertical coordinates
int FirstLine; // first line in the invalidated area
int LastLine; // last line in the invalidated area
HRESULT hr;
int abcLength = 0; // length of an abc[] item
int lines = 0;
// Create an array of lines to display.
static const int LINES=28;
static LPCWSTR abc[] = {
L"anteater", L"bear", L"cougar",
L"dingo", L"elephant", L"falcon",
L"gazelle", L"hyena", L"iguana",
L"jackal", L"kangaroo", L"llama",
L"moose", L"newt", L"octopus",
L"penguin", L"quail", L"rat",
L"squid", L"tortoise", L"urus",
L"vole", L"walrus", L"xylophone",
L"yak", L"zebra",
L"This line contains words, but no character. Go figure.",
L""
};
接下來,實作應用程式邏輯來設定文字計量的文字計算。 下列程式碼應該取代WndProc函式中的現有WM_CREATE案例。
case WM_CREATE :
// Get the handle to the client area's device context.
hdc = GetDC (hWnd);
// Extract font dimensions from the text metrics.
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
// Free the device context.
ReleaseDC (hWnd, hdc);
// Set an arbitrary maximum width for client area.
// (xClientMax is the sum of the widths of 48 average
// lowercase letters and 12 uppercase letters.)
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
接下來,實作應用程式邏輯,以在調整視窗大小時重新計算文字區塊。 下列程式碼應該放在 WndProc中的訊息交換器中。
case WM_SIZE:
// Retrieve the dimensions of the client area.
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
// Set the vertical scrolling range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = LINES - 1;
si.nPage = yClient / yChar;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
// Set the horizontal scrolling range and page size.
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + xClientMax / xChar;
si.nPage = xClient / xChar;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
return 0;
接下來,實作垂直捲動訊息的應用程式邏輯。 下列程式碼應該放在 WndProc中的訊息交換器中。
case WM_VSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
// Save the position for comparison later on
yPos = si.nPos;
switch (LOWORD (wParam))
{
// user clicked the HOME keyboard key
case SB_TOP:
si.nPos = si.nMin;
break;
// user clicked the END keyboard key
case SB_BOTTOM:
si.nPos = si.nMax;
break;
// user clicked the top arrow
case SB_LINEUP:
si.nPos -= 1;
break;
// user clicked the bottom arrow
case SB_LINEDOWN:
si.nPos += 1;
break;
// user clicked the scroll bar shaft above the scroll box
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// user clicked the scroll bar shaft below the scroll box
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
// user positioned the scroll box
// This message is the one used by Windows Touch
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
// If the position has changed, scroll window and update it
if (si.nPos != yPos)
{
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
}
break;
接下來,更新程式碼以重新繪製視窗。 下列程式碼應該取代WndProc中的預設WM_PAINT案例。
case WM_PAINT:
// Prepare the window for painting
hdc = BeginPaint (hWnd, &ps);
// Get vertical scroll bar position
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
// Get horizontal scroll bar position
GetScrollInfo (hWnd, SB_HORZ, &si);
xPos = si.nPos;
// Find painting limits
FirstLine = max (0, yPos + ps.rcPaint.top / yChar);
LastLine = min (LINES - 1, yPos + ps.rcPaint.bottom / yChar);
for (i = FirstLine; i <= LastLine; i++)
{
x = xChar * (1 - xPos);
y = yChar * (i - yPos);
// Note that "55" in the following depends on the
// maximum size of an abc[] item.
//
abcLength = wcslen(abc[i]);
hr = S_OK;
if ((FAILED(hr)))
{
MessageBox(hWnd, L"err", L"err", NULL);
}else{
TextOut(hdc, x, y, abc[i], abcLength);
}
}
// Indicate that painting is finished
EndPaint (hWnd, &ps);
return 0;
現在當您建置並執行應用程式時,它應該會有重複使用的文字和垂直捲動條。 下圖顯示應用程式的外觀。
停用閃爍
若要改善應用程式中的移動流覽體驗,您應該關閉閃爍。 若要這樣做,請在初始化時,在 hWnd 值上設定視窗屬性。 用於筆動的值會儲存在 tpcshrd.h 標頭中,也必須包含此值。 在您建立hWnd之後,下列程式碼應該放在您的 include 指示詞和InitInstance函式中。
注意
這適用于需要觸控或手寫筆向下事件立即意見反應的應用程式,而不是測試時間或距離閾值。
#include <tpcshrd.h>
[...]
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
[...]
const DWORD_PTR dwHwndTabletProperty =
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, drag up)
SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast<HANDLE>(dwHwndTabletProperty));
自訂移動流覽體驗
根據預設,您可能會想要與 Windows 7 供應專案不同的移動流覽體驗。 若要改善移動流覽體驗,您必須新增 WM_GESTURE 訊息的處理常式。 如需詳細資訊,請參閱 改善Single-Finger移動流覽體驗。
相關主題