Verbessern der Benutzerfreundlichkeit bei der Verschiebung mit einem Finger

Wenn Sie eine Anwendung erstellen, die auf Windows Touch abzielt, bietet sie automatisch grundlegende Verschiebungsunterstützung. Sie können jedoch die WM_GESTURE-Meldung verwenden, um erweiterte Unterstützung für die Verschiebung mit einem Finger bereitzustellen.

Übersicht

Um die Benutzerfreundlichkeit bei der Verschiebung mit einem Finger zu verbessern, verwenden Sie die folgenden Schritte, die in den nachfolgenden Abschnitten dieses Themas erläutert werden:

  • Erstellen Sie eine Anwendung mit Bildlaufleisten und deaktivierten Stiftbewegungen.
  • Fügen Sie Unterstützung für Verschiebungsgestenmeldungen hinzu.
  • Aktivieren Sie Begrenzungsmeldungen.

Erstellen einer Anwendung mit Bildlaufleisten und deaktivierten Stiftbewegungen

Sie müssen zunächst eine Anwendung mit Bildlaufleisten erstellen. Die entsprechende Vorgehensweise wird im Abschnitt Legacyunterstützung für die Verschiebung mit Bildlaufleisten erläutert. Wenn Sie mit den Beispielinhalten beginnen möchten, wechseln Sie zu diesem Abschnitt, und erstellen Sie eine Anwendung mit Bildlaufleisten. Deaktivieren Sie dann Stiftbewegungen. Wenn Sie bereits über eine Anwendung mit funktionierenden Bildlaufleisten verfügen, deaktivieren Sie Stiftbewegungen entsprechend der Beschreibung in diesem Abschnitt.

Hinzufügen benutzerdefinierter Unterstützung für Verschiebungsgestenmeldungen

Um Verschiebungsgestenmeldungen zu unterstützen, müssen Sie sie in der WndProc-Methode behandeln. Mithilfe der Gestenmeldungen werden horizontale und vertikale Deltawerte für Verschiebungsmeldungen bestimmt. Die Deltawerte werden verwendet, um das Bildlaufleistenobjekt zu aktualisieren, das wiederum die Benutzeroberfläche aktualisiert.

Aktualisieren Sie zuerst die Windows-Versionseinstellungen in der Datei targetver.h, um Windows Touch zu aktivieren. Im folgenden Code werden die verschiedenen Windows-Versionseinstellungen gezeigt, die die in targetver.h ersetzen sollten.


#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


Fügen Sie als Nächstes Ihrem Projekt die Datei UXTheme.h und den zusätzlichen Abhängigkeiten des Projekts die Bibliothek uxtheme.lib hinzu.


#include <uxtheme.h>


Fügen Sie dann am Anfang der WndProc-Funktion die folgenden Variablen hinzu. Diese werden in Verschiebungsberechnungen verwendet.


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


Fügen Sie als Nächstes den Handler für die WM_GESTURE-Meldung hinzu, damit die Bildlaufleisten auf der Basis von Verschiebungsgesten mit Deltawerten aktualisiert werden. Dadurch erhalten Sie eine viel präzisere Kontrolle über die Verschiebung.

Im folgenden Code wird die GESTUREINFO-Struktur aus lParam abgerufen, die letzte y-Koordinate aus der Struktur gespeichert und die Positionsänderung bestimmt, um das Bildlaufleistenobjekt zu aktualisieren. Der folgende Code sollte in die switch-Anweisung von WndProc eingefügt werden.


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


Wenn Sie jetzt die Verschiebungsgeste auf dem Fenster ausführen, sehen Sie, wie ein Bildlauf durch den Text mit Trägheit durchgeführt wird. Nun sollten Sie den Text so ändern, dass er mehr Zeilen aufweist, damit Sie die Verschiebung großer Textabschnitte untersuchen können.

Begrenzungsmeldungen in WndProc

Begrenzungsmeldungen sind eine Art visuelles Feedback, das Benutzer erhalten, wenn sie das Ende eines verschiebbaren Bereichs erreichen. Es wird von der Anwendung ausgelöst, wenn eine Begrenzung erreicht wird. In der vorstehenden Beispielimplementierung der WM_GESTURE-Meldung wird mithilfe der Endbedingung (si.nPos == si.yPos) aus dem Case-Abschnitt von WM_GESTURE getestet, ob Sie das Ende eines verschiebbaren Bereichs erreicht haben. Die folgenden Variablen werden verwendet, um Werte und Testfehler zu verfolgen.


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


Der Case-Abschnitt für die Verschiebungsgeste wird aktualisiert, um Begrenzungsmeldungen auszulösen. Im folgenden Code wird der Case-Abschnitt für GID_PAN aus dem WM_GESTURE-Meldungshandler veranschaulicht.



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

Jetzt sollte das Fenster der Anwendung Begrenzungsmeldungen aufweisen, wenn ein Benutzer eine Verschiebung über das Ende des Bildlaufleistenbereichs hinaus durchführt.

Verwandte Themen

Windows Touch-Gesten
BeginPanningFeedback
EndPanningFeedback
UpdatePanningFeedback

 

 

Anzeigen: