Miglioramento dell'esperienza di panoramica Single-Finger

Se si compila un'applicazione destinata a Windows Touch, fornisce automaticamente il supporto di panoramica di base. È tuttavia possibile usare il messaggio WM_GESTURE per fornire supporto avanzato per la panoramica a dito singolo.

Panoramica

Per migliorare l'esperienza di panoramica a dito singolo, usare questi passaggi, come illustrato nelle sezioni successive di questo argomento:

  • Creare un'applicazione con barre di scorrimento e con flick disabilitati.
  • Aggiungere il supporto per i messaggi di panoramica dei movimenti.
  • Abilitare il rimbalzo.

Creare un'applicazione con barre di scorrimento e con Flicks disabilitato

Prima di iniziare, è necessario creare un'applicazione con barre di scorrimento. La sezione Supporto legacy per Panning con barre di scorrimento illustra questo processo. Se si vuole iniziare con il contenuto di esempio, passare a tale sezione e creare un'applicazione con barre di scorrimento e quindi disabilitare le scorrere. Se si dispone già di un'applicazione con barre di scorrimento funzionanti, disabilitare le flick come descritto in tale sezione.

Aggiungere il supporto di panoramica personalizzata per i messaggi di panoramica dei movimenti

Per supportare i messaggi di panoramica dei movimenti, è necessario gestirli nel metodo WndProc . I messaggi di movimento vengono usati per determinare delta orizzontali e verticali per i messaggi di panoramica. I delta vengono usati per aggiornare l'oggetto barra di scorrimento, che aggiorna l'interfaccia utente.

Prima di tutto, aggiornare le impostazioni della versione di Windows nel file targetver.h per abilitare Windows Touch. Il codice seguente mostra le varie impostazioni della versione di Windows che devono sostituire quelle in 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

Aggiungere quindi il file UXTheme.h al progetto e aggiungere la libreria uxtheme.lib alle dipendenze aggiuntive del progetto.

#include <uxtheme.h>

Aggiungere quindi le variabili seguenti alla parte superiore della funzione WndProc . Questi verranno usati nei calcoli per la panoramica.

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

Aggiungere quindi il gestore per il messaggio WM_GESTURE in modo che le barre di scorrimento vengano aggiornate con delta in base ai movimenti di panoramica. Questo ti dà un controllo molto più sottile della panoramica.

Il codice seguente ottiene la struttura GESTUREINFOdall'oggetto lParam, salva l'ultima coordinata y dalla struttura e determina la modifica in posizione per aggiornare l'oggetto barra di scorrimento. Il codice seguente deve essere inserito nell'istruzione switch WndProc .

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

Ora, quando si esegue il movimento di panoramica sulla finestra, verrà visualizzato lo scorrimento del testo con inertia. A questo punto, è possibile modificare il testo in modo da avere più righe in modo da poter esplorare le sezioni di testo di grandi dimensioni.

Feedback sui limiti in WndProc

Il feedback sui limiti è un tipo di feedback visivo fornito agli utenti quando raggiungono la fine di un'area pannable. Viene attivato dall'applicazione quando viene raggiunto un limite. Nell'implementazione precedente del messaggio di WM_GESTURE la condizione (si.nPos == si.yPos) finale del caso di WM_GESTURE viene usata per verificare che sia stata raggiunta la fine di un'area pannable. Le variabili seguenti vengono usate per tenere traccia dei valori e degli errori di test.

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

Il caso di movimento di panoramica viene aggiornato per attivare il feedback sui limiti. Il codice seguente illustra il caso GID_PAN dal gestore messaggi di 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);
  

Ora la finestra dell'applicazione deve avere commenti e suggerimenti sui limiti quando un utente passa la parte inferiore dell'area della barra di scorrimento.

Movimenti tocco di Windows

BeginPanningFeedback

EndPanningFeedback

UpdatePanningFeedback