Condividi tramite


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 con un solo dito.

Panoramica

Per migliorare l'esperienza di panoramica con un solo dito, seguire questa procedura, come illustrato nelle sezioni successive di questo argomento:

  • Creare un'applicazione con barre di scorrimento e con i scorrere 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 lo Scorrimento 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 i scorrere. Se si dispone già di un'applicazione con barre di scorrimento funzionanti, disabilitare i flick come descritto in tale sezione.

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

Per supportare i messaggi di scorrimento dei gesti, è necessario gestirli nel metodo WndProc. I messaggi di movimento vengono usati per determinare delta orizzontali e verticali per i messaggi di panoramica. I valori delta vengono utilizzati per aggiornare l'oggetto della barra di scorrimento, che a sua volta 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 all'inizio 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. In questo modo si ottiene un controllo molto più dettagliato della panoramizzazione.

Il codice seguente ottiene la strutturaGESTUREINFO dal lParam, salva l'ultima coordinata y dalla struttura e determina la modifica della 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 gesto di trascinamento sulla finestra, verrà visualizzato lo scorrimento del testo con inerzia. A questo punto, potresti modificare il testo per ottenere più righe, così da poter scorrere 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 panoramabile. Viene attivato dall'applicazione quando viene raggiunto un limite. Nell'implementazione di esempio precedente del messaggio WM_GESTURE, la condizione finale (si.nPos == si.yPos) dal caso WM_GESTURE viene utilizzata per verificare che si sia raggiunta la fine di un'area scorrevole. 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 del gesto di pan viene aggiornato per attivare il feedback del limite. Il codice seguente illustra il caso GID_PAN dal gestore messaggi 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);
  

Adesso, la finestra della tua applicazione dovrebbe fornire un feedback sui limiti quando un utente esegue una panoramica oltre la parte inferiore dell'area della barra di scorrimento.

Gesti Touch di Windows

BeginPanningFeedback

EndPanningFeedback

UpdatePanningFeedback