Bagikan melalui


Dukungan Warisan untuk Panning dengan Bilah Gulir

Bagian ini menjelaskan dukungan untuk menggeser menggunakan bilah gulir di aplikasi berbasis Windows.

Di Windows 7, gerakan panning menghasilkan pesan WM_*SCROLL untuk mengaktifkan dukungan warisan untuk panning. Karena aplikasi Anda mungkin tidak mendukung semua pesan WM_*SCROLL, pengalihan mungkin tidak berfungsi dengan benar. Topik ini menjelaskan langkah-langkah yang harus Anda ambil untuk memastikan bahwa pengalaman panning warisan dalam aplikasi berfungsi seperti yang diharapkan pengguna.

Gambaran Umum

Bagian berikut menjelaskan cara mengaktifkan pengalaman panning warisan:

  • Buat aplikasi dengan bilah gulir.
  • Nonaktifkan berkedot.
  • Sesuaikan pengalaman panning.

Membuat Aplikasi dengan Bilah Gulir

Mulai proyek Win32 baru menggunakan wizard Microsoft Visual Studio. Pastikan jenis aplikasi diatur ke aplikasi Windows. Anda tidak perlu mengaktifkan dukungan untuk Pustaka Templat Aktif (ATL). Gambar berikut menunjukkan seperti apa proyek Anda setelah Anda memulainya.

cuplikan layar memperlihatkan jendela tanpa bilah gulir

Selanjutnya, aktifkan bilah gulir pada gambar. Ubah kode pembuatan jendela di InitInstance sehingga panggilan fungsi CreateWindow membuat jendela dengan bilah gulir. Kode berikut menunjukkan cara melakukannya.

   hWnd = CreateWindow(
      szWindowClass, 
      szTitle, 
      WS_OVERLAPPEDWINDOW | WS_VSCROLL,  // style
      200,                               // x
      200,                               // y
      550,                               // width
      300,                               // height
      NULL,
      NULL,
      hInstance,
      NULL
    );  

Setelah Anda mengubah kode pembuatan jendela, aplikasi Anda akan memiliki bilah gulir. Gambar berikut menunjukkan bagaimana aplikasi mungkin terlihat pada titik ini.

cuplikan layar memperlihatkan jendela dengan bilah gulir vertikal tetapi tanpa teks

Setelah Anda mengubah kode pembuatan jendela, tambahkan objek bilah gulir ke aplikasi Anda dan beberapa teks untuk digulir. Tempatkan kode berikut ke bagian atas metode 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""
     };        

Selanjutnya, terapkan logika aplikasi untuk mengonfigurasi perhitungan teks untuk metrik teks. Kode berikut harus menggantikan kasus WM_CREATE yang ada dalam fungsi WndProc .

    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;

Selanjutnya, terapkan logika aplikasi untuk perhitungan ulang blok teks saat jendela diubah ukurannya. Kode berikut harus ditempatkan ke dalam sakelar pesan di 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;

Selanjutnya, terapkan logika aplikasi untuk pesan gulir vertikal. Kode berikut harus ditempatkan ke dalam sakelar pesan di 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;

Selanjutnya, perbarui kode untuk menggambar ulang jendela. Kode berikut harus menggantikan kasus WM_PAINT default di WndProc.

    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;

Sekarang ketika Anda membangun dan menjalankan aplikasi Anda, aplikasi harus memiliki teks boilerplate dan bilah gulir vertikal. Gambar berikut menunjukkan tampilan aplikasi Anda.

cuplikan layar memperlihatkan jendela dengan bilah gulir vertikal dan teks

Nonaktifkan Flicks

Untuk meningkatkan pengalaman panning di aplikasi Anda, Anda harus menonaktifkan berkedip. Untuk melakukan ini, atur properti jendela pada nilai hWnd saat diinisialisasi. Nilai yang digunakan untuk flicks disimpan di header tpcshrd.h, yang juga harus disertakan. Kode berikut harus ditempatkan dalam arahan sertakan Anda dan dalam fungsi InitInstance setelah Anda membuat hWnd Anda.

Catatan

Ini berguna untuk aplikasi yang memerlukan umpan balik segera pada peristiwa sentuhan atau pena ke bawah alih-alih menguji untuk ambang waktu atau jarak.

 

#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));

Menyesuaikan Pengalaman Panning

Anda mungkin menginginkan pengalaman panning yang berbeda dari penawaran Windows 7 secara default. Untuk meningkatkan pengalaman panning, Anda harus menambahkan handler untuk pesan WM_GESTURE . Untuk informasi selengkapnya, lihat Meningkatkan Pengalaman Panning Single-Finger.

Gerakan Sentuh Windows