Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En los pasos siguientes se explica cómo realizar un seguimiento de varios puntos táctiles mediante Windows Touch.
- Cree una aplicación y habilite Windows Touch.
- Agregue un controlador para WM_TOUCH y realice un seguimiento de los puntos.
- Dibuje los puntos.
Una vez que tenga su aplicación en funcionamiento, se representarán círculos debajo de cada toque. En la captura de pantalla siguiente se muestra el aspecto de la aplicación mientras se ejecuta.
Crear una aplicación y habilitar Windows Touch
Comience con una aplicación de Microsoft Win32 mediante el asistente de Microsoft Visual Studio. Una vez completado el asistente, agregue compatibilidad con los mensajes de Windows Touch estableciendo la versión de Windows en targetver.h e incluyendo windows.h y windowsx.h en la aplicación. En el código siguiente se muestra cómo establecer la versión de Windows en 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
En el código siguiente se muestra cómo se deben agregar las directivas include. Además, puede crear algunas variables globales que se usarán más adelante.
#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)
};
Agregar controlador para WM_TOUCH y puntos de seguimiento
En primer lugar, declare algunas variables que usa el controlador de WM_TOUCH en WndProc.
int wmId, wmEvent, i, x, y;
UINT cInputs;
PTOUCHINPUT pInputs;
POINT ptInput;
Ahora, inicialice las variables usadas para almacenar puntos táctiles y registre la ventana para la entrada táctil desde el método 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;
}
A continuación, controle el mensaje WM_TOUCH del método WndProc . El código siguiente muestra una implementación del controlador para 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
}
Nota:
Para usar la función ScreenToClient, debe tener compatibilidad con alto soporte DPI en su aplicación. Para obtener más información sobre cómo admitir valores altos de PPP, consulte PPP alto.
Ahora cuando un usuario toca la pantalla, las posiciones que está tocando se almacenarán en la matriz de puntos. El miembro dwID de la estructura TOUCHINPUT almacena un identificador que dependerá del hardware.
Para solucionar el problema del miembro dwID que depende del hardware, el manejador del caso WM_TOUCH usa una función, GetContactIndex, que asigna el miembro dwID de la estructura TOUCHINPUT a un punto que se dibuja en la pantalla. El código siguiente muestra una implementación de esta función.
// 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;
}
Importante
Windows 11 y más recientes
Algunas interacciones táctiles con tres y cuatro dedos ya no funcionarán en aplicaciones de Windows de forma predeterminada.
De forma predeterminada, el sistema ahora utiliza interacciones táctiles con tres y cuatro dedos para operaciones como cambiar o minimizar ventanas y cambiar escritorios virtuales. Como estas interacciones ahora se manejan a nivel del sistema, este cambio podría afectar la funcionalidad de su aplicación.
Para admitir interacciones con tres o cuatro dedos dentro de una aplicación, se ha introducido una nueva configuración de usuario que especifica si el sistema maneja o no estas interacciones:
Bluetooth y dispositivos > Panel táctil > "Gestos con tres y cuatro dedos"
Cuando está configurado en "Activado" (predeterminado), el sistema manejará todas las interacciones con tres y cuatro dedos (las aplicaciones no podrán admitirlas).
Cuando está configurado en "Desactivado", las aplicaciones pueden admitir interacciones con tres y cuatro dedos (el sistema no las manejará).
Si la aplicación debe admitir estas interacciones, se recomienda informar a los usuarios de esta configuración y proporcionar un vínculo que inicie la configuración de Windows en la página correspondiente (ms-settings:devices-touch). Para obtener más información, vea Método Launcher.LaunchUriAsync.
Dibujar los puntos
Declare las siguientes variables para la rutina de dibujo.
// 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;
El contexto de visualización de memoria memDC se usa para almacenar un contexto de gráficos temporales que se intercambia con el contexto de visualización representado, hdc, para eliminar el parpadeo. Implemente la rutina de dibujo, que toma los puntos almacenados y dibuja un círculo en los puntos. En el código siguiente se muestra cómo se puede implementar el controlador de 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;
Al ejecutar la aplicación, ahora debería tener un aspecto similar a la ilustración al principio de esta sección.
Para divertirse, puedes dibujar algunas líneas adicionales alrededor de los puntos táctiles. En la captura de pantalla siguiente se muestra cómo podría verse la aplicación con algunas líneas adicionales dibujadas alrededor de los círculos.