Share via


Melhorando a experiência de movimento panorâmico Single-Finger

Se você criar um aplicativo direcionado ao Windows Touch, ele fornecerá automaticamente suporte de movimento panorâmico básico. No entanto, você pode usar a mensagem WM_GESTURE para fornecer suporte aprimorado para movimento panorâmico de dedo único.

Visão geral

Para melhorar a experiência de movimento panorâmico de dedo único, use estas etapas, conforme explicado nas seções seguintes deste tópico:

  • Crie um aplicativo com barras de rolagem e com movimentos desabilitados.
  • Adicione suporte para mensagens de painel de gestos.
  • Habilitar salto.

Criar um aplicativo com barras de rolagem e com Flicks desabilitado

Antes de começar, você deve criar um aplicativo com barras de rolagem. A seção Suporte herdado para movimento panorâmico com barras de rolagem explica esse processo. Se você quiser começar com o conteúdo de exemplo, vá para essa seção e crie um aplicativo com barras de rolagem e desabilite os movimentos. Se você já tiver um aplicativo com barras de rolagem funcionando, desabilite os movimentos conforme descrito nessa seção.

Adicionar suporte a movimento panorâmico personalizado para mensagens de panorâmica de gestos

Para dar suporte a mensagens de painel de gestos, você deve tratá-las no método WndProc . As mensagens de gesto são usadas para determinar deltas horizontais e verticais para mensagens de panorâmica. Os deltas são usados para atualizar o objeto da barra de rolagem, que atualiza a interface do usuário.

Primeiro, atualize as configurações de versão do Windows no arquivo targetver.h para habilitar o Windows Touch. O código a seguir mostra as várias configurações de versão do Windows que devem substituí-las em 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

Em seguida, adicione o arquivo UXTheme.h ao seu projeto e adicione a biblioteca uxtheme.lib às dependências adicionais do projeto.

#include <uxtheme.h>

Em seguida, adicione as variáveis a seguir à parte superior da função WndProc . Eles serão usados em cálculos para movimento 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;  

Em seguida, adicione o manipulador para a mensagem WM_GESTURE para que as barras de rolagem sejam atualizadas com deltas com base em gestos de movimento panorâmico. Isso lhe dá um controle muito mais refinado do movimento panorâmico.

O código a seguir obtém a estrutura GESTUREINFO do lParam, salva a última coordenada y da estrutura e determina a alteração na posição para atualizar o objeto da barra de rolagem. O código a seguir deve ser colocado em sua instrução 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);

Agora, ao executar o gesto de movimento panorâmico na janela, você verá a rolagem de texto com inércia. Neste ponto, talvez você queira alterar o texto para ter mais linhas para que possa explorar grandes seções de texto em movimento panorâmico.

Comentários de limite no WndProc

Os comentários de limite são um tipo de comentários visuais fornecidos aos usuários quando eles chegam ao final de uma área pannável. Ele é disparado pelo aplicativo quando um limite é atingido. Na implementação de exemplo anterior da mensagem de WM_GESTURE , a condição (si.nPos == si.yPos) final do caso WM_GESTURE é usada para testar se você atingiu o final de uma região que pode ser panorâmica. As variáveis a seguir são usadas para rastrear valores e testar erros.

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

O caso de gesto de panorâmica é atualizado para disparar comentários de limite. O código a seguir ilustra o caso de GID_PAN do manipulador de mensagens 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);
  

Agora, a janela do aplicativo deve ter comentários de limite quando um usuário passa pela parte inferior da região da barra de rolagem.

Gestos de Toque do Windows

BeginPanningFeedback

EndPanningFeedback

UpdatePanningFeedback