次の方法で共有


スクロール バーを使用したパンの従来のサポート

このセクションでは、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パン エクスペリエンスの向上」を参照してください。

Windows タッチ ジェスチャ