Partager via


Détection et suivi de plusieurs points tactiles

Les étapes suivantes expliquent comment suivre plusieurs points tactiles à l’aide de Windows Touch.

  1. Créez une application et activez Windows Touch.
  2. Ajoutez un gestionnaire pour WM_TOUCH et les points de suivi.
  3. Dessinez les points.

Une fois que votre application est en cours d’exécution, elle affiche des cercles sous chaque contact. La capture d’écran suivante montre comment votre application peut ressembler lors de l’exécution.

capture d’écran montrant une application qui affiche les points tactiles sous forme de cercles verts et jaunes

Créer une application et activer Windows Touch

Commencez par une application Microsoft Win32 à l’aide de l’Assistant Microsoft Visual Studio. Une fois que vous avez terminé l'assistant, ajoutez la prise en charge des messages tactiles Windows en spécifiant la version de Windows dans targetver.h et en incluant windows.h et windowsx.h dans votre application. Le code suivant montre comment définir la version de Windows dans targetver.h.

#ifndef WINVER                  // Specifies that the minimum required platform is Windows 7.
#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 7.
#define _WIN32_WINNT 0x0601     // Change this to the appropriate value to target other versions of Windows.
#endif     

#ifndef _WIN32_WINDOWS          // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE                       // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700        // Change this to the appropriate value to target other versions of IE.
#endif

Le code suivant montre comment vos directives include doivent être ajoutées. Vous pouvez également créer des variables globales qui seront utilisées ultérieurement.

#include <windows.h>    // included for Windows Touch
#include <windowsx.h>   // included for point conversion

#define MAXPOINTS 10

// You will use this array to track touch points
int points[MAXPOINTS][2];

// You will use this array to switch the color / track ids
int idLookup[MAXPOINTS];


// You can make the touch points larger
// by changing this radius value
static int radius      = 50;

// There should be at least as many colors
// as there can be touch points so that you
// can have different colors for each point
COLORREF colors[] = { RGB(153,255,51), 
                      RGB(153,0,0), 
                      RGB(0,153,0), 
                      RGB(255,255,0), 
                      RGB(255,51,204), 
                      RGB(0,0,0),
                      RGB(0,153,0), 
                      RGB(153, 255, 255), 
                      RGB(153,153,255), 
                      RGB(0,51,153)
                    };

Ajouter un gestionnaire pour WM_TOUCH et des points de suivi

Tout d’abord, déclarez certaines variables utilisées par le gestionnaire WM_TOUCH dans WndProc.

int wmId, wmEvent, i, x, y;

UINT cInputs;
PTOUCHINPUT pInputs;
POINT ptInput;   

À présent, initialisez les variables utilisées pour stocker des points tactiles et inscrivez la fenêtre pour l’entrée tactile à partir de la méthode InitInstance .

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd) {
      return FALSE;
   }

   // register the window for touch instead of gestures
   RegisterTouchWindow(hWnd, 0);  

   // the following code initializes the points
   for (int i=0; i< MAXPOINTS; i++){
     points[i][0] = -1;
     points[i][1] = -1;
     idLookup[i]  = -1;
   }  

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

Ensuite, gérez le message WM_TOUCH de la méthode WndProc . Le code suivant montre une implémentation du gestionnaire pour WM_TOUCH.

case WM_TOUCH:        
  cInputs = LOWORD(wParam);
  pInputs = new TOUCHINPUT[cInputs];
  if (pInputs){
    if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))){
      for (int i=0; i < static_cast<INT>(cInputs); i++){
        TOUCHINPUT ti = pInputs[i];
        index = GetContactIndex(ti.dwID);
        if (ti.dwID != 0 && index < MAXPOINTS){                            
          // Do something with your touch input handle
          ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x);
          ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y);
          ScreenToClient(hWnd, &ptInput);
          
          if (ti.dwFlags & TOUCHEVENTF_UP){                      
            points[index][0] = -1;
            points[index][1] = -1;

            // Remove the old contact index to make it available for the new incremented dwID.
            // On some touch devices, the dwID value is continuously incremented.
            RemoveContactIndex(index);                
          }else{
            points[index][0] = ptInput.x;
            points[index][1] = ptInput.y;                
          }
        }
      }

      InvalidateRect(hWnd, NULL, FALSE);
    }
    // If you handled the message and don't want anything else done with it, you can close it
    CloseTouchInputHandle((HTOUCHINPUT)lParam);
    delete [] pInputs;
  }else{
    // Handle the error here 
  }  

Note

Pour utiliser la fonction ScreenToClient, votre application doit prendre en charge les DPI élevés. Pour plus d’informations sur la prise en charge de High DPI, consultez High DPI.

Maintenant, lorsqu’un utilisateur touche l’écran, les positions qu’il touche sont stockées dans le tableau de points. Le membre dwID de la structure TOUCHINPUT stocke un identificateur qui sera dépendant du matériel.

Pour résoudre le problème du membre dwID dépendant du matériel, le gestionnaire de cas WM_TOUCH utilise une fonction GetContactIndex qui mappe le membre dwID de la structure TOUCHINPUT à un point dessiné sur l’écran. Le code suivant montre une implémentation de cette fonction.

// This function is used to return an index given an ID
int GetContactIndex(int dwID){
  for (int i = 0; i < MAXPOINTS; i++) {
      if (idLookup[i] == dwID) {
          return i;
      }
  }

  for (int i = 0; i < MAXPOINTS; i++) {
      if (idLookup[i] == -1) {
          idLookup[i] = dwID;
          return i;
      }
  }
  // Out of contacts
  return -1;
}

// Mark the specified index as initialized for new use
BOOL RemoveContactIndex(int index) {
    if (index >= 0 && index < MAXPOINTS) {
        idLookup[index] = -1;
        return true;
    }

    return false;
}

Important

Windows 11 et ultérieur

Certaines interactions tactiles à trois ou quatre doigts ne fonctionneront plus par défaut dans certaines applications Windows.

Le système utilise désormais par défaut les interactions tactiles à trois ou quatre doigts pour des opérations comme le basculement ou la réduction d’une fenêtre, ou encore les changements apportés aux bureaux virtuels. Ces interactions étant désormais gérées au niveau du système, le fonctionnement de votre application pourrait être affecté par ce changement.

Pour prendre en charge les interactions à trois ou quatre doigts dans une application, un nouveau paramètre utilisateur a été introduit qui spécifie si le système gère ou non ces interactions :

Bluetooth & périphériques > Fonction tactile > « Mouvements tactiles à trois et quatre doigts »

Lorsqu’il est réglé sur « Activé » (par défaut), le système gère toutes les interactions à trois et quatre doigts (les applications ne peuvent pas les prendre en charge).

Lorsqu’il est réglé sur « Désactivé », les interactions à trois et quatre doigts peuvent être prises en charge par les applications (elles ne seront pas gérées par le système).

Si votre application doit prendre en charge ces interactions, nous vous recommandons d’informer les utilisateurs de ce paramètre et de fournir un lien qui lance les paramètres Windows vers la page appropriée (ms-settings :devices-touch). Pour plus d’informations, consultez La méthode Launcher.LaunchUriAsync.

Dessiner les points

Déclarez les variables suivantes pour la routine de dessin.

    // For double buffering
    static HDC memDC       = 0;
    static HBITMAP hMemBmp = 0;
    HBITMAP hOldBmp        = 0;
   
    // For drawing / fills
    PAINTSTRUCT ps;
    HDC hdc;
    HBRUSH hBrush;
    
    // For tracking dwId to points
    int index;

Le contexte d’affichage de la mémoire memDC est utilisé pour stocker un contexte graphique temporaire qui est échangé avec le contexte d’affichage rendu, hdc, pour éliminer le scintillement. Implémentez la routine de dessin, qui prend les points que vous avez stockés et dessine un cercle aux points. Le code suivant montre comment implémenter le gestionnaire WM_PAINT .

  case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);    
    RECT client;
    GetClientRect(hWnd, &client);        
  
    // start double buffering
    if (!memDC){
      memDC = CreateCompatibleDC(hdc);
    }
    hMemBmp = CreateCompatibleBitmap(hdc, client.right, client.bottom);
    hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp);          

    hBrush = CreateSolidBrush(RGB(255, 255, 255));
    FillRect(memDC, &client, hBrush);
    DeleteObject(hBrush);

    //Draw Touched Points                
    for (i=0; i < MAXPOINTS; i++){
      hBrush = CreateSolidBrush(colors[i]);        
      SelectObject( memDC, hBrush);           

      x = points[i][0];
      y = points[i][1];
      if  (x >0 && y>0){              
        Ellipse(memDC, x - radius, y - radius, x+ radius, y + radius);
      }

      DeleteObject(hBrush);
    }
  
    BitBlt(hdc, 0,0, client.right, client.bottom, memDC, 0,0, SRCCOPY);      
    EndPaint(hWnd, &ps);

    SelectObject(memDC, hOldBmp);
    DeleteObject(hMemBmp);

    break;

Lorsque vous exécutez votre application, elle doit maintenant ressembler à l’illustration au début de cette section.

Pour vous amuser, vous pouvez dessiner quelques lignes supplémentaires autour des points tactiles. La capture d’écran suivante montre comment l’application pourrait ressembler avec quelques lignes supplémentaires dessinées autour des cercles.

capture d’écran montrant une application qui affiche des points tactiles sous forme de cercles avec des lignes à travers les centres et croisant les bords des points tactiles

Entrée tactile Windows