Idioma: HTML | XAML

Inicio rápido: punteros (XAML)

Applies to Windows and Windows Phone

En las aplicaciones de Windows en tiempo de ejecución con C++, C# o Visual Basic, las interacciones táctiles, del mouse y de lápiz o la pluma se reciben, procesan y administran como entradas de puntero.

Si es la primera vez que desarrollas una aplicación de Windows en tiempo de ejecución con C++, C# o Visual Basic:  Consulta estos temas para familiarizarte con las tecnologías presentadas aquí.

Crear la primera aplicación de la Tienda Windows con C# o Visual Basic

Crear la primera aplicación de la Tienda Windows con C++

Guía básica para crear aplicaciones de Windows en tiempo de ejecución con C# o Visual Basic

Guía básica para crear aplicaciones Windows en tiempo de ejecución con C++

Encontrarás más información sobre eventos en Introducción a eventos y eventos enrutados

Características de la aplicación, de principio a fin:  Consulta esta funcionalidad con más detalle como parte de la serie Características de la aplicación, de principio a fin

Interacción del usuario, de principio a fin (XAML)

Personalización de la interacción del usuario, de principio a fin (XAML)

directrices sobre la experiencia del usuario:  

Las bibliotecas de control de la plataforma (HTML y XAML) proporcionan una experiencia de interacción del usuario de Windows completa, incluidas interacciones estándar, efectos físicos animados y comentarios visuales. Si no necesitas compatibilidad para interacción personalizada, usa estos controles integrados.

Si los controles de la plataforma no son suficientes, estas directrices para la interacción del usuario te pueden ayudar a proporcionar una experiencia de interacción atractiva y envolvente que sea coherente en todos los modos de entrada. Estas instrucciones se centran principalmente en la entrada táctil, pero también son válidas para las entradas de panel táctil, mouse, teclado y lápiz.

Ejemplos:  Para ver esta función en acción, consulta las Muestras de aplicaciones de la Tienda Windows.

Entrada: muestra de eventos de entrada de usuario de XAML

Entrada: muestra de funcionalidades del dispositivo

Entrada: muestra de manipulaciones y gestos (C++)

Entrada: muestra de prueba de acceso táctil

Muestra de desplazamiento, movimiento panorámico y zoom XAML

Entrada: muestra de entrada de lápiz simplificada

Objetivo: Para obtener información sobre cómo escuchar y controlar la entrada de puntero.

Requisitos previos

Damos por hecho que sabes crear una aplicación básica de Windows en tiempo de ejecución con C++, C# o Visual Basic.

Para completar este tutorial, necesitas:

Tiempo para finalizar: 30 minutos.

Instrucciones

¿Qué es una entrada de puntero?

Mediante la unificación de las entradas táctiles, de mouse y de lápiz o pluma en una entrada de puntero abstracta puedes controlar las interacciones del usuario con tu aplicación independientemente del tipo de dispositivo de entrada que se esté usando.

Un objeto Pointer representa un contacto de entrada único y singular de un dispositivo de entrada (como mouse, pluma/lápiz, un dedo o varios dedos). El sistema crea un puntero cuando se detecta un contacto por primera vez, y se lo destruye cuando se cancela el puntero o este deja el intervalo de detección. En el caso de dispositivos múltiples o entrada multitoque, cada contacto se trata como un solo puntero.

Existe un amplio conjunto de API para entrada de puntero que pueden interceptar datos de entrada en forma directa a partir de diversos dispositivos. Puedes controlar los eventos de puntero para obtener información básica, como el estado de detección (en un intervalo o un contacto) y el tipo de dispositivo, e información extendida, como la ubicación, la presión y la geometría de contacto. Como en muchos casos las aplicaciones deben responder a distintos modos de entrada de diferentes maneras, también se encuentran disponibles propiedades de dispositivo específicas, como qué botón del mouse presionó un usuario o si un usuario está usando el extremo borrador del lápiz. Por ejemplo, se puede filtrar la entrada táctil para que sea compatible con interacciones como el movimiento panorámico y el desplazamiento, mientras que el mouse y la pluma/lápiz suelen resultar más adecuados para tareas como escribir con lápiz y dibujar. Si tu aplicación necesita diferenciar entre distintos dispositivos de entrada y sus funcionalidades, consulta Inicio rápido: identificación de dispositivos de entrada.

Si implementas tu propia compatibilidad con la interacción, ten presente que los usuarios esperan una experiencia intuitiva en la que interactúen en forma directa con los elementos de la interfaz de usuario de tu aplicación. Te recomendamos que modeles tus interacciones personalizadas sobre la biblioteca de controles de la plataforma (HTML y XAML) para que todo sea coherente y pueda detectarse. Los controles de estas bibliotecas proporcionan una experiencia de interacción de usuario de Windows 8.1 completa, incluidas interacciones estándar, efectos físicos animados, comentarios visuales y accesibilidad. Crea únicamente interacciones personalizadas si existe un requisito claro y bien definido y no hay ninguna interacción básica que sea compatible con el escenario.

Crear la interfaz de usuario

Para este ejemplo, usamos un rectángulo (targetContainer) como el objeto de destino de la entrada de puntero. El color del destino cambia cuando cambia el estado del puntero.

Se muestran detalles del puntero bajo el rectángulo y los eventos del puntero en sí se muestran a la izquierda del rectángulo (para informar la secuencia de eventos).

Este es el lenguaje de marcado de aplicaciones extensible (XAML) para este ejemplo.


    <Page
    x:Class="PointerInput.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PointerInput"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Name="page">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="320" />
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Canvas Name="Container" 
                Grid.Column="0"
                Grid.Row="1"
                HorizontalAlignment="Center" 
                VerticalAlignment="Center" 
                Margin="0,0,0,0" 
                Height="320"  Width="640">
            <Rectangle Name="Target" 
                       Fill="#FF0000" 
                       Stroke="Black" 
                       StrokeThickness="0"
                       Height="320" Width="640" />
        </Canvas>
        <TextBox Name="eventLog" 
                 Grid.Column="1"
                 Grid.Row="0"
                 Grid.RowSpan="3" 
                 Background="#000000" 
                 TextWrapping="Wrap" 
                 Foreground="#FFFFFF" 
                 ScrollViewer.VerticalScrollBarVisibility="Visible" 
                 BorderThickness="0"/>
    </Grid>
</Page>


Escuchar eventos de puntero

En la mayoría de los casos, te recomendamos obtener información del puntero mediante el argumento de evento de los controladores de eventos de puntero del marco de lenguaje de Windows 8 que hayas elegido (aplicaciones de Windows en tiempo de ejecución con JavaScript, aplicaciones de Windows en tiempo de ejecución con C++, C# o Visual Basic, o aplicaciones de la Tienda Windows con DirectX con C++).

Si el argumento de evento no expone de manera intrínseca los detalles de puntero que necesita tu aplicación, puedes acceder a los datos extendidos de puntero que expone un objeto PointerPoint con los métodos GetCurrentPoint y GetIntermediatePoints de PointerRoutedEventArgs.

Para este ejemplo, usamos un rectángulo (targetContainer) como el objeto de destino de la entrada de puntero. El color del destino cambia cuando cambia el estado del puntero.

Se muestran detalles de cada puntero en un bloque de texto flotante asociado con el puntero y los eventos del puntero en sí se muestran a la derecha del rectángulo (para informar la secuencia de eventos).

El siguiente código establece el objeto de destino, declara variables globales e identifica los diversos agentes de escucha de eventos de puntero para el destino.


        // For this example, we track simultaneous contacts in case the 
        // number of contacts has reached the maximum supported by the device.
        // Depending on the device, additional contacts might be ignored 
        // (PointerPressed not fired). 
        uint numActiveContacts;
        Windows.Devices.Input.TouchCapabilities touchCapabilities = new Windows.Devices.Input.TouchCapabilities();

        // Dictionary to maintain information about each active contact. 
        // An entry is added during PointerPressed/PointerEntered events and removed 
        // during PointerReleased/PointerCaptureLost/PointerCanceled/PointerExited events.
        Dictionary<uint, Windows.UI.Xaml.Input.Pointer> contacts;

        public MainPage()
        {
            this.InitializeComponent();
            numActiveContacts = 0;
            // Initialize the dictionary.
            contacts = new Dictionary<uint, Windows.UI.Xaml.Input.Pointer>((int)touchCapabilities.Contacts);
            // Declare the pointer event handlers.
            Target.PointerPressed += new PointerEventHandler(Target_PointerPressed);
            Target.PointerEntered += new PointerEventHandler(Target_PointerEntered);
            Target.PointerReleased += new PointerEventHandler(Target_PointerReleased);
            Target.PointerExited += new PointerEventHandler(Target_PointerExited);
            Target.PointerCanceled += new PointerEventHandler(Target_PointerCanceled);
            Target.PointerCaptureLost += new PointerEventHandler(Target_PointerCaptureLost);
            Target.PointerMoved += new PointerEventHandler(Target_PointerMoved);
            Target.PointerWheelChanged += new PointerEventHandler(Target_PointerWheelChanged);
        }



Controlar eventos de puntero

A continuación, usamos comentarios de interfaz de usuario para demostrar controladores de eventos de puntero básicos.

  • Este controlador administra un evento de contacto de puntero (hacia abajo, presionado). Agregamos el evento al registro de eventos, agregamos el puntero a la matriz de punteros usada para realizar un seguimiento de los punteros de interés y mostramos los detalles de los punteros.

    Nota   Los eventos PointerPressed y PointerReleased no siempre se producen en pares. Tu aplicación debe escuchar y controlar cualquier evento que pueda dar conclusión a una acción de puntero abajo (como PointerExited, PointerCanceled y PointerCaptureLost).

    
            // PointerPressed and PointerReleased events do not always occur in pairs. 
            // Your app should listen for and handle any event that might conclude a pointer down action 
            // (such as PointerExited, PointerCanceled, and PointerCaptureLost).
            // For this example, we track the number of contacts in case the 
            // number of contacts has reached the maximum supported by the device.
            // Depending on the device, additional contacts might be ignored 
            // (PointerPressed not fired). 
            void Target_PointerPressed(object sender, PointerRoutedEventArgs e)
            {
                if (Convert.ToBoolean(touchCapabilities.TouchPresent) && (numActiveContacts > touchCapabilities.Contacts))
                {
                    // Number of supported contacts exceeded.
                    return;
                }
    
                Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
                // Update event sequence.
                eventLog.Text += "\nDown: " + ptr.PointerId;
    
                // Change background color of target when pointer contact detected.
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Green);
    
                // Check if pointer already exists (for example, enter occurred prior to press).
                if (contacts.ContainsKey(ptr.PointerId))
                {
                    return;
                }
                // Add contact to dictionary.
                contacts[ptr.PointerId] = ptr;
                ++numActiveContacts;
    
                // Prevent most handlers along the event route from handling the same event again.
                e.Handled = true;
    
                // Display pointer details.
                createInfoPop(e);
            }
    
    
    
  • Este controlador administra un evento de entrada de puntero (arriba, mantener el mouse para obtener un lápiz). Agregamos el evento al registro de eventos, agregamos el puntero a la colección de punteros y mostramos los detalles del puntero.

    
            private void Target_PointerEntered(object sender, PointerRoutedEventArgs e)
            {
                Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
                // Update event sequence.
                eventLog.Text += "\nOver: " + ptr.PointerId;
    
                if (contacts.Count == 0)
                {
                    // Change background color of target when pointer contact detected.
                    Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
                }
    
                // Check if pointer already exists (if enter occurred prior to down).
                if (contacts.ContainsKey(ptr.PointerId))
                {
                    return;
                }
    
                // Add contact to dictionary.
                contacts[ptr.PointerId] = ptr;
                ++numActiveContacts;
    
                // Prevent most handlers along the event route from handling the same event again.
                e.Handled = true;
    
                // Display pointer details.
                createInfoPop(e);
            }
    
    
    
  • Este controlador administra un evento de movimiento de puntero. Agregamos el evento al registro de eventos y actualizamos los detalles del puntero.

    Importante  La entrada de mouse se asocia con un solo puntero asignado al detectar por primera vez la entrada. Al hacer clic en un botón del mouse (primario, rueda o secundario), se crea una asociación secundaria entre el puntero y ese botón a través del evento PointerPressed. El evento PointerReleased solo se desencadena cuando se libera ese mismo botón del mouse (ningún otro botón se puede asociar con el puntero hasta que se complete este evento). Debido a esta asociación exclusiva, los clics de otros botones del mouse se enrutan mediante el evento PointerMoved.

    
    private void Target_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Multiple, simultaneous mouse button inputs are processed here.
        // Mouse input is associated with a single pointer assigned when 
        // mouse input is first detected. 
        // Clicking additional mouse buttons (left, wheel, or right) during 
        // the interaction creates secondary associations between those buttons 
        // and the pointer through the pointer pressed event. 
        // The pointer released event is fired only when the last mouse button 
        // associated with the interaction (not necessarily the initial button) 
        // is released. 
        // Because of this exclusive association, other mouse button clicks are 
        // routed through the pointer move event.          
        if (ptr.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
        {
            // To get mouse state, we need extended pointer details.
            // We get the pointer info through the getCurrentPoint method
            // of the event argument. 
            Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
            if (ptrPt.Properties.IsLeftButtonPressed)
            {
                eventLog.Text += "\nLeft button: " + ptrPt.PointerId;
            }
            if (ptrPt.Properties.IsMiddleButtonPressed)
            {
                eventLog.Text += "\nWheel button: " + ptrPt.PointerId;
            }
            if (ptrPt.Properties.IsRightButtonPressed)
            {
                eventLog.Text += "\nRight button: " + ptrPt.PointerId;
            }
        }
    
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    
        // Display pointer details.
        updateInfoPop(e);
    }
    
    
    
  • Este controlador administra un evento MouseWheel (rotación). Agregamos el evento al registro de eventos, agregamos el puntero a la matriz de punteros (si es necesario) y mostramos los detalles del puntero.

    
    private void Target_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Update event sequence.
        eventLog.Text += "\nMouse wheel: " + ptr.PointerId;
    
        // Check if pointer already exists (for example, enter occurred prior to wheel).
        if (contacts.ContainsKey(ptr.PointerId))
        {
            return;
        }
    
        // Add contact to dictionary.
        contacts[ptr.PointerId] = ptr;
        ++numActiveContacts;
    
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    
        // Display pointer details.
        createInfoPop(e);
    }
    
    
    
  • Este controlador administra un evento de salida de puntero (levantado, hacia arriba) donde se termina el contacto con el digitalizador. Agregamos el evento al registro de eventos, quitamos el puntero de la colección de punteros y actualizamos los detalles del puntero.

    
    void Target_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Update event sequence.
        eventLog.Text += "\nUp: " + ptr.PointerId;
    
        // If event source is mouse pointer and the pointer is still 
        // over the target, retain pointer and pointer details.
        // Return without removing pointer from pointers dictionary.
        // For this example, we assume a maximum of one mouse pointer.
        if (ptr.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
        {
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
            return;
        }
    
        // Update target UI.
        Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
    
    
        destroyInfoPop(ptr);
    
        // Remove contact from dictionary.
        if (contacts.ContainsKey(ptr.PointerId))
        {
            contacts[ptr.PointerId] = null;
            contacts.Remove(ptr.PointerId);
            --numActiveContacts;
        }
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    }
    
    
    
  • Este controlador administra un evento de salida de puntero (afuera) donde el contacto con el digitalizador se mantiene. Agregamos el evento al registro de eventos, quitamos el puntero de la matriz de punteros y actualizamos los detalles del puntero.

    
    private void Target_PointerExited(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Update event sequence.
        eventLog.Text += "\nPointer exited: " + ptr.PointerId;
    
        // Remove contact from dictionary.
        if (contacts.ContainsKey(ptr.PointerId))
        {
            contacts[ptr.PointerId] = null;
            contacts.Remove(ptr.PointerId);
            --numActiveContacts;
        }
    
        // Update the UI and pointer details.
        destroyInfoPop(ptr);
    
        if (contacts.Count == 0)
        {
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
        }
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    }
    
    
    
  • Este controlador administra un evento de cancelación de puntero. Agregamos el evento al registro de eventos, quitamos el puntero de la matriz de punteros y actualizamos los detalles del puntero.

    
    // Fires for for various reasons, including: 
    //    - Touch contact canceled by pen coming into range of the surface.
    //    - The device doesn't report an active contact for more than 100ms.
    //    - The desktop is locked or the user logged off. 
    //    - The number of simultaneous contacts exceeded the number supported by the device.
    private void Target_PointerCanceled(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Update event sequence.
        eventLog.Text += "\nPointer canceled: " + ptr.PointerId;
    
        // Remove contact from dictionary.
        if (contacts.ContainsKey(ptr.PointerId))
        {
            contacts[ptr.PointerId] = null;
            contacts.Remove(ptr.PointerId);
            --numActiveContacts;
        }
    
        destroyInfoPop(ptr);
    
        if (contacts.Count == 0)
        {
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
        }
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    }
    
    
    
  • Este controlador administra un evento de captura de puntero perdido. Agregamos el evento al registro de eventos, quitamos el puntero de la matriz de punteros y actualizamos los detalles del puntero.

    Nota  PointerCaptureLost puede producirse en lugar de PointerReleased. Puede perderse la captura de puntero debido a las interacciones de usuario o porque se capturó mediante programación otro puntero o se liberó intencionalmente la captura del puntero actual.

    
    // Fires for for various reasons, including: 
    //    - User interactions
    //    - Programmatic capture of another pointer
    //    - Captured pointer was deliberately released
    // PointerCaptureLost can fire instead of PointerReleased. 
    private void Target_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
    {
        Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
    
        // Update event sequence.
        eventLog.Text += "\nPointer capture lost: " + ptr.PointerId;
    
        // Remove contact from dictionary.
        if (contacts.ContainsKey(ptr.PointerId))
        {
            contacts[ptr.PointerId] = null;
            contacts.Remove(ptr.PointerId);
            --numActiveContacts;
        }
    
        destroyInfoPop(ptr);
    
        if (contacts.Count == 0)
        {
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
        }
        // Prevent most handlers along the event route from handling the same event again.
        e.Handled = true;
    }
    
    
    

Obtener las propiedades del puntero

Como se mencionó anteriormente, el marco de lenguaje que elijas para tu aplicación determina el modo en que se obtienen las propiedades de los punteros. Las aplicación de Windows en tiempo de ejecución con C++, C# o Visual Basic deben obtener la mayor parte de la información de puntero extendida mediante un objeto Windows.UI.Input.PointerPoint que se obtiene con los métodos GetCurrentPoint y GetIntermediatePoints de PointerRoutedEventArgs.

  • Primero, creamos un nuevo TextBlock para cada puntero.

    
            void createInfoPop(PointerRoutedEventArgs e)
            {
                TextBlock pointerDetails = new TextBlock();
                Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
                pointerDetails.Name = ptrPt.PointerId.ToString();
                pointerDetails.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
                pointerDetails.Text = queryPointer(ptrPt);
    
                TranslateTransform x = new TranslateTransform();
                x.X = ptrPt.Position.X + 20;
                x.Y = ptrPt.Position.Y + 20;
                pointerDetails.RenderTransform = x;
    
                Container.Children.Add(pointerDetails);
            }
    
    
    
  • Después, proporcionamos una manera de actualizar la información del puntero en un TextBlock existente asociado con ese puntero.

    
            void updateInfoPop(PointerRoutedEventArgs e)
            {
                foreach (var pointerDetails in Container.Children)
                {
                    if (pointerDetails.GetType().ToString() == "Windows.UI.Xaml.Controls.TextBlock")
                    {
                        TextBlock _TextBlock = (TextBlock)pointerDetails;
                        if (_TextBlock.Name == e.Pointer.PointerId.ToString())
                        {
                            // To get pointer location details, we need extended pointer info.
                            // We get the pointer info through the getCurrentPoint method
                            // of the event argument. 
                            Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
                            TranslateTransform x = new TranslateTransform();
                            x.X = ptrPt.Position.X + 20;
                            x.Y = ptrPt.Position.Y + 20;
                            pointerDetails.RenderTransform = x;
                            _TextBlock.Text = queryPointer(ptrPt);
                        }
                    }
                }
            }
    
    
    
  • Finalmente, consultamos diversas propiedades de puntero.

    
             String queryPointer(PointerPoint ptrPt)
             {
                 String details = "";
    
                 switch (ptrPt.PointerDevice.PointerDeviceType)
                 {
                     case Windows.Devices.Input.PointerDeviceType.Mouse:
                         details += "\nPointer type: mouse";
                         break;
                     case Windows.Devices.Input.PointerDeviceType.Pen:
                         details += "\nPointer type: pen";
                         if (ptrPt.IsInContact)
                         {
                             details += "\nPressure: " + ptrPt.Properties.Pressure;
                             details += "\nrotation: " + ptrPt.Properties.Orientation;
                             details += "\nTilt X: " + ptrPt.Properties.XTilt;
                             details += "\nTilt Y: " + ptrPt.Properties.YTilt;
                             details += "\nBarrel button pressed: " + ptrPt.Properties.IsBarrelButtonPressed;
                         }
                         break;
                     case Windows.Devices.Input.PointerDeviceType.Touch:
                         details += "\nPointer type: touch";
                         details += "\nrotation: " + ptrPt.Properties.Orientation;
                         details += "\nTilt X: " + ptrPt.Properties.XTilt;
                         details += "\nTilt Y: " + ptrPt.Properties.YTilt;
                         break;
                     default:
                         details += "\nPointer type: n/a";
                         break;
                 }
    
                 GeneralTransform gt = Target.TransformToVisual(page);
                 Point screenPoint;
    
                 screenPoint = gt.TransformPoint(new Point(ptrPt.Position.X, ptrPt.Position.Y));
                 details += "\nPointer Id: " + ptrPt.PointerId.ToString() +
                     "\nPointer location (parent): " + ptrPt.Position.X + ", " + ptrPt.Position.Y +
                     "\nPointer location (screen): " + screenPoint.X + ", " + screenPoint.Y;
                 return details;
             }
    
    
    

Ejemplo completo

A continuación se encuentra el código de C# para este ejemplo. Consulta Temas relacionados en la parte inferior de esta página para obtener vínculos a muestras más complejas.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace PointerInput
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        // For this example, we track simultaneous contacts in case the 
        // number of contacts has reached the maximum supported by the device.
        // Depending on the device, additional contacts might be ignored 
        // (PointerPressed not fired). 
        uint numActiveContacts;
        Windows.Devices.Input.TouchCapabilities touchCapabilities = new Windows.Devices.Input.TouchCapabilities();

        // Dictionary to maintain information about each active contact. 
        // An entry is added during PointerPressed/PointerEntered events and removed 
        // during PointerReleased/PointerCaptureLost/PointerCanceled/PointerExited events.
        Dictionary<uint, Windows.UI.Xaml.Input.Pointer> contacts;

        public MainPage()
        {
            this.InitializeComponent();
            numActiveContacts = 0;
            // Initialize the dictionary.
            contacts = new Dictionary<uint, Windows.UI.Xaml.Input.Pointer>((int)touchCapabilities.Contacts);
            // Declare the pointer event handlers.
            Target.PointerPressed += new PointerEventHandler(Target_PointerPressed);
            Target.PointerEntered += new PointerEventHandler(Target_PointerEntered);
            Target.PointerReleased += new PointerEventHandler(Target_PointerReleased);
            Target.PointerExited += new PointerEventHandler(Target_PointerExited);
            Target.PointerCanceled += new PointerEventHandler(Target_PointerCanceled);
            Target.PointerCaptureLost += new PointerEventHandler(Target_PointerCaptureLost);
            Target.PointerMoved += new PointerEventHandler(Target_PointerMoved);
            Target.PointerWheelChanged += new PointerEventHandler(Target_PointerWheelChanged);
        }


        // PointerPressed and PointerReleased events do not always occur in pairs. 
        // Your app should listen for and handle any event that might conclude a pointer down action 
        // (such as PointerExited, PointerCanceled, and PointerCaptureLost).
        // For this example, we track the number of contacts in case the 
        // number of contacts has reached the maximum supported by the device.
        // Depending on the device, additional contacts might be ignored 
        // (PointerPressed not fired). 
        void Target_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            if (Convert.ToBoolean(touchCapabilities.TouchPresent) && (numActiveContacts > touchCapabilities.Contacts))
            {
                // Number of supported contacts exceeded.
                return;
            }

            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nDown: " + ptr.PointerId;

            // Change background color of target when pointer contact detected.
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Green);

            // Check if pointer already exists (for example, enter occurred prior to press).
            if (contacts.ContainsKey(ptr.PointerId))
            {
                return;
            }
            // Add contact to dictionary.
            contacts[ptr.PointerId] = ptr;
            ++numActiveContacts;

            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;

            // Display pointer details.
            createInfoPop(e);
        }

        void Target_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nUp: " + ptr.PointerId;

            // If event source is mouse pointer and the pointer is still 
            // over the target, retain pointer and pointer details.
            // Return without removing pointer from pointers dictionary.
            // For this example, we assume a maximum of one mouse pointer.
            if (ptr.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
            {
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
                return;
            }

            // Update target UI.
            Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);


            destroyInfoPop(ptr);

            // Remove contact from dictionary.
            if (contacts.ContainsKey(ptr.PointerId))
            {
                contacts[ptr.PointerId] = null;
                contacts.Remove(ptr.PointerId);
                --numActiveContacts;
            }
            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;
        }

        private void Target_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Multiple, simultaneous mouse button inputs are processed here.
            // Mouse input is associated with a single pointer assigned when 
            // mouse input is first detected. 
            // Clicking additional mouse buttons (left, wheel, or right) during 
            // the interaction creates secondary associations between those buttons 
            // and the pointer through the pointer pressed event. 
            // The pointer released event is fired only when the last mouse button 
            // associated with the interaction (not necessarily the initial button) 
            // is released. 
            // Because of this exclusive association, other mouse button clicks are 
            // routed through the pointer move event.          
            if (ptr.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
            {
                // To get mouse state, we need extended pointer details.
                // We get the pointer info through the getCurrentPoint method
                // of the event argument. 
                Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
                if (ptrPt.Properties.IsLeftButtonPressed)
                {
                    eventLog.Text += "\nLeft button: " + ptrPt.PointerId;
                }
                if (ptrPt.Properties.IsMiddleButtonPressed)
                {
                    eventLog.Text += "\nWheel button: " + ptrPt.PointerId;
                }
                if (ptrPt.Properties.IsRightButtonPressed)
                {
                    eventLog.Text += "\nRight button: " + ptrPt.PointerId;
                }
            }

            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;

            // Display pointer details.
            updateInfoPop(e);
        }

        private void Target_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nOver: " + ptr.PointerId;

            if (contacts.Count == 0)
            {
                // Change background color of target when pointer contact detected.
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
            }

            // Check if pointer already exists (if enter occurred prior to down).
            if (contacts.ContainsKey(ptr.PointerId))
            {
                return;
            }

            // Add contact to dictionary.
            contacts[ptr.PointerId] = ptr;
            ++numActiveContacts;

            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;

            // Display pointer details.
            createInfoPop(e);
        }

        private void Target_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nMouse wheel: " + ptr.PointerId;

            // Check if pointer already exists (for example, enter occurred prior to wheel).
            if (contacts.ContainsKey(ptr.PointerId))
            {
                return;
            }

            // Add contact to dictionary.
            contacts[ptr.PointerId] = ptr;
            ++numActiveContacts;

            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;

            // Display pointer details.
            createInfoPop(e);
        }

        // Fires for for various reasons, including: 
        //    - User interactions
        //    - Programmatic capture of another pointer
        //    - Captured pointer was deliberately released
        // PointerCaptureLost can fire instead of PointerReleased. 
        private void Target_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nPointer capture lost: " + ptr.PointerId;

            // Remove contact from dictionary.
            if (contacts.ContainsKey(ptr.PointerId))
            {
                contacts[ptr.PointerId] = null;
                contacts.Remove(ptr.PointerId);
                --numActiveContacts;
            }

            destroyInfoPop(ptr);

            if (contacts.Count == 0)
            {
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
            }
            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;
        }

        // Fires for for various reasons, including: 
        //    - Touch contact canceled by pen coming into range of the surface.
        //    - The device doesn't report an active contact for more than 100ms.
        //    - The desktop is locked or the user logged off. 
        //    - The number of simultaneous contacts exceeded the number supported by the device.
        private void Target_PointerCanceled(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nPointer canceled: " + ptr.PointerId;

            // Remove contact from dictionary.
            if (contacts.ContainsKey(ptr.PointerId))
            {
                contacts[ptr.PointerId] = null;
                contacts.Remove(ptr.PointerId);
                --numActiveContacts;
            }

            destroyInfoPop(ptr);

            if (contacts.Count == 0)
            {
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
            }
            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;
        }

        private void Target_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;

            // Update event sequence.
            eventLog.Text += "\nPointer exited: " + ptr.PointerId;

            // Remove contact from dictionary.
            if (contacts.ContainsKey(ptr.PointerId))
            {
                contacts[ptr.PointerId] = null;
                contacts.Remove(ptr.PointerId);
                --numActiveContacts;
            }

            // Update the UI and pointer details.
            destroyInfoPop(ptr);

            if (contacts.Count == 0)
            {
                Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
            }
            // Prevent most handlers along the event route from handling the same event again.
            e.Handled = true;
        }

        void createInfoPop(PointerRoutedEventArgs e)
        {
            TextBlock pointerDetails = new TextBlock();
            Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
            pointerDetails.Name = ptrPt.PointerId.ToString();
            pointerDetails.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
            pointerDetails.Text = queryPointer(ptrPt);

            TranslateTransform x = new TranslateTransform();
            x.X = ptrPt.Position.X + 20;
            x.Y = ptrPt.Position.Y + 20;
            pointerDetails.RenderTransform = x;

            Container.Children.Add(pointerDetails);
        }

        void destroyInfoPop(Windows.UI.Xaml.Input.Pointer ptr)
        {
            foreach (var pointerDetails in Container.Children)
            {
                if (pointerDetails.GetType().ToString() == "Windows.UI.Xaml.Controls.TextBlock")
                {
                    TextBlock _TextBlock = (TextBlock)pointerDetails;
                    if (_TextBlock.Name == ptr.PointerId.ToString())
                    {
                        Container.Children.Remove(pointerDetails);
                    }
                }
            }
        }

        void updateInfoPop(PointerRoutedEventArgs e)
        {
            foreach (var pointerDetails in Container.Children)
            {
                if (pointerDetails.GetType().ToString() == "Windows.UI.Xaml.Controls.TextBlock")
                {
                    TextBlock _TextBlock = (TextBlock)pointerDetails;
                    if (_TextBlock.Name == e.Pointer.PointerId.ToString())
                    {
                        // To get pointer location details, we need extended pointer info.
                        // We get the pointer info through the getCurrentPoint method
                        // of the event argument. 
                        Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
                        TranslateTransform x = new TranslateTransform();
                        x.X = ptrPt.Position.X + 20;
                        x.Y = ptrPt.Position.Y + 20;
                        pointerDetails.RenderTransform = x;
                        _TextBlock.Text = queryPointer(ptrPt);
                    }
                }
            }
        }

         String queryPointer(PointerPoint ptrPt)
         {
             String details = "";

             switch (ptrPt.PointerDevice.PointerDeviceType)
             {
                 case Windows.Devices.Input.PointerDeviceType.Mouse:
                     details += "\nPointer type: mouse";
                     break;
                 case Windows.Devices.Input.PointerDeviceType.Pen:
                     details += "\nPointer type: pen";
                     if (ptrPt.IsInContact)
                     {
                         details += "\nPressure: " + ptrPt.Properties.Pressure;
                         details += "\nrotation: " + ptrPt.Properties.Orientation;
                         details += "\nTilt X: " + ptrPt.Properties.XTilt;
                         details += "\nTilt Y: " + ptrPt.Properties.YTilt;
                         details += "\nBarrel button pressed: " + ptrPt.Properties.IsBarrelButtonPressed;
                     }
                     break;
                 case Windows.Devices.Input.PointerDeviceType.Touch:
                     details += "\nPointer type: touch";
                     details += "\nrotation: " + ptrPt.Properties.Orientation;
                     details += "\nTilt X: " + ptrPt.Properties.XTilt;
                     details += "\nTilt Y: " + ptrPt.Properties.YTilt;
                     break;
                 default:
                     details += "\nPointer type: n/a";
                     break;
             }

             GeneralTransform gt = Target.TransformToVisual(page);
             Point screenPoint;

             screenPoint = gt.TransformPoint(new Point(ptrPt.Position.X, ptrPt.Position.Y));
             details += "\nPointer Id: " + ptrPt.PointerId.ToString() +
                 "\nPointer location (parent): " + ptrPt.Position.X + ", " + ptrPt.Position.Y +
                 "\nPointer location (screen): " + screenPoint.X + ", " + screenPoint.Y;
             return details;
         }
    }
}


Resumen y pasos siguientes

En este inicio rápido, has obtenido información sobre la entrada de puntero en aplicaciones de Windows en tiempo de ejecución con C++, C# o Visual Basic.

Los eventos de puntero son útiles para administrar interacciones simples como pulsación, deslizamiento e interacciones específicas del dispositivo que incluyen la entrada desde botones de mouse secundarios, la rueda del mouse, botones de menú contextual de pluma y el borrador de la pluma.

Para controlar interacciones más elaboradas, como los gestos descritos en el lenguaje táctil de Windows 8, consulta el tema de inicio rápido: entrada táctil.

Para obtener más información sobre el lenguaje táctil de Windows 8, consulta Diseño de interacción táctil.

Temas relacionados

Desarrolladores
Respuesta a la interacción del usuario
Desarrollar aplicaciones de la Tienda Windows (XAML)
Inicio rápido: entrada táctil
Diseñadores
Diseño de la interacción táctil

 

 

Mostrar:
© 2014 Microsoft