Compartir a través de


Mejora de la experiencia de movimiento panorámico de Single-Finger

Si compilas una aplicación destinada a Windows Touch, proporciona automáticamente compatibilidad básica con movimiento panorámico. Sin embargo, puede usar el mensaje de WM_GESTURE para proporcionar compatibilidad mejorada con el movimiento panorámico de un solo dedo.

Información general

Para mejorar la experiencia de movimiento panorámico de un solo dedo, siga estos pasos, como se explica en las secciones posteriores de este tema:

  • Cree una aplicación con barras de desplazamiento y con parpadeos deshabilitados.
  • Se ha agregado compatibilidad con los mensajes panorámicos de gestos.
  • Habilite el rebote.

Crear una aplicación con barras de desplazamiento y con flicks deshabilitado

Antes de comenzar, debe crear una aplicación con barras de desplazamiento. En la sección Compatibilidad heredada con movimiento panorámico con barras de desplazamiento se explica este proceso. Si desea empezar con el contenido de ejemplo, vaya a esa sección y cree una aplicación con barras de desplazamiento y, a continuación, deshabilite los parpadeos. Si ya tiene una aplicación con barras de desplazamiento funcionales, deshabilite los parpadeos tal y como se describe en esa sección.

Agregar compatibilidad con movimiento panorámico personalizado para mensajes de movimiento panorámico de gestos

Para admitir mensajes panorámicos de gestos, debe controlarlos en el método WndProc . Los mensajes de gestos se usan para determinar los deltas horizontales y verticales de los mensajes panorámicos. Los deltas se usan para actualizar el objeto de barra de desplazamiento, que actualiza la interfaz de usuario.

En primer lugar, actualice la configuración de la versión de Windows en el archivo targetver.h para habilitar Windows Touch. En el código siguiente se muestran las distintas configuraciones de versión de Windows que deben reemplazar las de 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

A continuación, agregue el archivo UXTheme.h al proyecto y agregue la biblioteca uxtheme.lib a las dependencias adicionales del proyecto.

#include <uxtheme.h>

A continuación, agregue las siguientes variables a la parte superior de la función WndProc . Se usarán en cálculos para el movimiento panorámico.

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

A continuación, agregue el controlador para el mensaje de WM_GESTURE para que las barras de desplazamiento se actualicen con deltas en función de los gestos de movimiento panorámico. Esto le proporciona un control mucho más preciso de movimiento panorámico.

El código siguiente obtiene la estructura GESTUREINFO de lParam, guarda la última coordenada y de la estructura y determina el cambio de posición para actualizar el objeto de barra de desplazamiento. El código siguiente debe colocarse en la instrucción 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);

Ahora, al realizar el gesto de movimiento panorámico en la ventana, verá el desplazamiento de texto con inercia. En este punto, es posible que quiera cambiar el texto para que tenga más líneas para que pueda explorar secciones grandes de texto en movimiento panorámico.

Comentarios de límites en WndProc

Los comentarios de límites son un tipo de comentarios visuales que se proporcionan a los usuarios cuando llegan al final de un área que se puede desplazar. La aplicación lo desencadena cuando se alcanza un límite. En la implementación del ejemplo anterior del mensaje de WM_GESTURE , la condición (si.nPos == si.yPos) final del caso de WM_GESTURE se usa para probar que ha llegado al final de una región que se puede desplazar. Las variables siguientes se usan para realizar un seguimiento de los valores y los errores de prueba.

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

El caso de gestos panorámicos se actualiza para desencadenar comentarios de límites. En el código siguiente se muestra el caso GID_PAN del controlador de mensajes 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);
  

Ahora la ventana de la aplicación debe tener comentarios sobre los límites cuando un usuario se desplaza más allá de la parte inferior de la región de la barra de desplazamiento.

Gestos táctiles de Windows

BeginPanningFeedback

EndPanningFeedback

UpdatePanningFeedback