Bagikan melalui


Meningkatkan Pengalaman Panning Single-Finger

Jika Anda membangun aplikasi yang menargetkan Windows Touch, aplikasi tersebut secara otomatis menyediakan dukungan panning dasar. Namun, Anda dapat menggunakan pesan WM_GESTURE untuk memberikan dukungan yang ditingkatkan untuk panning satu jari.

Gambaran Umum

Untuk meningkatkan pengalaman panning satu jari, gunakan langkah-langkah ini, seperti yang dijelaskan di bagian berikutnya dari topik ini:

  • Buat aplikasi dengan bilah gulir dan dengan flicks dinonaktifkan.
  • Tambahkan dukungan untuk pesan gestur.
  • Aktifkan pantulan.

Membuat Aplikasi dengan Bilah Gulir dan dengan Flicks Dinonaktifkan

Sebelum memulai, Anda harus membuat aplikasi dengan bilah gulir. Bagian Dukungan Warisan untuk Panning dengan Scrollbars menjelaskan proses ini. Jika Anda ingin memulai dengan konten contoh, buka bagian tersebut dan buat aplikasi dengan bilah gulir lalu nonaktifkan jentikkan. Jika Anda sudah memiliki aplikasi dengan bilah gulir yang berfungsi, nonaktifkan jentik seperti yang dijelaskan di bagian tersebut.

Menambahkan Dukungan Panning Kustom untuk Pesan Gesture Pan

Untuk mendukung pesan gesture pan, Anda harus menanganinya dalam metode WndProc . Pesan gerakan digunakan untuk menentukan delta horizontal dan vertikal untuk pesan geser. Delta digunakan untuk memperbarui objek bilah gulir, yang memperbarui antarmuka pengguna.

Pertama, perbarui pengaturan versi Windows di file targetver.h untuk mengaktifkan Windows Touch. Kode berikut menunjukkan berbagai pengaturan versi Windows yang harus menggantikan yang ada di targetver.h.

#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

Selanjutnya, tambahkan file UXTheme.h ke proyek Anda dan tambahkan pustaka uxtheme.lib ke dependensi tambahan proyek Anda.

#include <uxtheme.h>

Selanjutnya, tambahkan variabel berikut ke bagian atas fungsi WndProc . Ini akan digunakan dalam perhitungan untuk panning.

// 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;  

Selanjutnya, tambahkan handler untuk pesan WM_GESTURE sehingga bilah gulir diperbarui dengan delta berdasarkan gerakan panning. Ini memberi Anda kontrol panning yang jauh lebih halus.

Kode berikut mendapatkan struktur GESTUREINFO dari lParam, menyimpan koordinat y terakhir dari struktur, dan menentukan perubahan posisi untuk memperbarui objek bilah gulir. Kode berikut harus ditempatkan dalam pernyataan sakelar WndProc Anda.

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

Sekarang, ketika Anda melakukan gerakan panci di jendela Anda, Anda akan melihat gulir teks dengan inertia. Pada titik ini, Anda mungkin ingin mengubah teks agar memiliki lebih banyak baris sehingga Anda dapat menjelajahi bagian teks yang besar.

Umpan Balik Batas di WndProc

Umpan balik batas adalah jenis umpan balik visual yang diberikan kepada pengguna ketika mereka mencapai akhir area pannable. Ini dipicu oleh aplikasi ketika batas tercapai. Dalam contoh implementasi pesan WM_GESTURE sebelumnya, kondisi (si.nPos == si.yPos) akhir dari kasus WM_GESTURE digunakan untuk menguji bahwa Anda telah mencapai akhir wilayah pannable. Variabel berikut digunakan untuk melacak nilai dan menguji kesalahan.

// 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;

Kasus gerakan pan diperbarui untuk memicu umpan balik batas. Kode berikut mengilustrasikan kasus GID_PAN dari penangan pesan WM_GESTURE .

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

Sekarang jendela aplikasi Anda harus memiliki umpan balik batas saat pengguna menggeser melewati bagian bawah wilayah bilah gulir.

Gerakan Sentuh Windows

BeginPanningFeedback

EndPanningFeedback

UpdatePanningFeedback