スクロール バーを使用したパンの従来のサポート
このセクションでは、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パン エクスペリエンスの向上」を参照してください。
関連トピック