Idioma: HTML | XAML

Início rápido: ponteiros (XAML)

Applies to Windows and Windows Phone

Interações por toque, mouse e caneta são recebidas, processadas e gerenciadas como uma entrada de ponteiro em aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic.

Se você for iniciante no desenvolvimento de aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic:  Leia estes tópicos para se familiarizar com as tecnologias discutidas aqui.

Criar seu primeiro aplicativo da Windows Store em C# ou Visual Basic

Criar seu primeiro aplicativo da Windows Store em C++

Mapa de aplicativos do Tempo de Execução do Windows em C# ou Visual Basic

Mapa de aplicativos do Tempo de Execução do Windows em C++

Saiba mais sobre eventos em Visão geral de eventos e eventos roteados

Recursos de aplicativos, do início ao fim:  Explore esse recurso mais profundamente como parte da nossa série Recursos de aplicativos, do início ao fim

Interação do usuário, do início ao fim (XAML)

Personalização da interação do usuário, do início ao fim (XAML)

Diretrizes de experiência do usuário:  

As bibliotecas de controle de plataforma (HTML e XAML) fornecem a experiência de total interação do usuário do Windows, incluindo interações padrão, efeitos físicos animados e comentários visuais. Se não precisar de suporte para interação personalizado, use esses controles internos.

Se os controles de plataforma não forem suficientes, as seguintes diretrizes para interação do usuário podem ajudá-lo a proporcionar uma experiência de interação envolvente e imersiva, consistente entre os modos de entrada. Essas diretrizes têm como foco principal a entrada por toque, mas elas ainda são relevantes para entrada por touchpad, mouse, teclado e caneta.

Exemplos:  Veja esta funcionalidade em ação em nossos Exemplos de aplicativos da Windows Store.

Entrada: exemplo de eventos de entrada do usuário XAML

Entrada: amostra de recursos de dispositivo

Entrada: amostra de manipulações e gestos (C++)

Entrada: amostra de teste de hit de toque

Amostra de rolagem, movimento panorâmico e aplicação de zoom em XAML

Entrada: amostra de tinta simplificada

Objetivo: Para saber como escutar e manipular a entrada de ponteiro.

Pré-requisitos

Nós supomos que você possa criar um aplicativo do Tempo de Execução do Windows básico em C++, C# ou Visual Basic.

Para completar este tutorial, você precisa:

Tempo para conclusão: 30 minutos.

Instruções

O que é a entrada de ponteiro?

Ao unificar a entrada por toque, mouse, caneta/caneta digitalizadora como uma entrada de ponteiro abstrata, você pode manipular interações do usuário com o seu aplicativo independentemente do tipo de dispositivo de entrada em uso.

Um objeto de Pointer representa um contato de entrada único e exclusivo de um dispositivo de entrada (como mouse, caneta/caneta digitalizadora, um dedo ou vários dedos). O sistema cria um ponteiro quando um contato é detectado pela primeira vez, destruindo-o quando esse ponteiro sai (se afasta) do intervalo de detecção ou é cancelado. No caso de vários dispositivos ou entrada multitoque, cada contato é tratado como um ponteiro exclusivo.

Há um extenso conjunto de entradas de ponteiro com base em APIs de entrada que pode interceptar os dados de entrada diretamente de vários dispositivos. Você pode manipular eventos de ponteiro para obter informações básicas como estado de detecção (em intervalo ou contato) e tipo de dispositivo, e informações estendidas, como local, pressão e geometria de contato. Como, em vários casos, os aplicativos devem responder a diferentes modos de entrada de diferentes maneiras, propriedades de dispositivo específicas também estão disponíveis, como qual botão do mouse um usuário pressionou ou se um usuário está usando a ponta de borracha da caneta. Por exemplo, o toque pode ser filtrado para dar suporte a interações, como movimento panorâmico e rolagem, enquanto o mouse e a caneta/caneta digitalizadora são tipicamente mais adequados para tarefas precisas, como pintura e desenho. Caso seu aplicativo precise diferenciar entre dispositivos de entrada e suas funcionalidades, veja Guia de Início Rápido: Identificando Dispositivos de Entrada.

Se você implementar seu próprio suporte para interação, tenha em mente que os usuários esperam uma experiência intuitiva que envolva a interação direta com os elementos de interface do usuário do seu aplicativo. Recomendamos que você modele as interações personalizadas nas bibliotecas de controles de plataforma (HTML e XAML) para manter tudo consistente e detectável. Os controles nessas bibliotecas fornecem a experiência de interação completa para o usuário do Windows 8.1, incluindo interações padrão, efeitos físicos animados, comentários visuais e acessibilidade. Crie interações personalizadas somente se houver uma exigência clara e bem definida e se nenhuma das interações básicas for permitida no seu cenário.

Criar a interface do usuário

Para este exemplo, usamos um retângulo (targetContainer) como objeto de destino para a entrada de ponteiro. A cor do destino muda quando o status do ponteiro muda.

Detalhes de cada ponteiro são exibidos sob o retângulo, e os eventos de ponteiro propriamente ditos são exibidos à esquerda do retângulo (para relatar a sequência de eventos).

Este é um XAML (Extensible Application Markup Language) para este exemplo.


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


Escutar eventos de ponteiro

Na maioria dos casos, recomendamos que você obtenha informações de ponteiro por meio do argumento de evento dos manipuladores de eventos de ponteiro da estrutura de linguagem escolhida no Windows 8 (aplicativos do Tempo de Execução do Windows em JavaScript, aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic ou aplicativos da Windows Store em DirectX com C++).

Se o argumento do evento não representar intrinsecamente os detalhes de ponteiro exigidos pelo seu aplicativo, você poderá obter acesso a dados de ponteiro estendidos expostos por um objeto GetCurrentPoint e por meio dos métodos GetIntermediatePoints e PointerPoint de PointerRoutedEventArgs.

Para este exemplo, usamos um retângulo (targetContainer) como objeto de destino para a entrada de ponteiro. A cor do destino muda quando o status do ponteiro muda.

Os detalhes de cada ponteiro são exibidos em um bloco de texto flutuante associado ao ponteiro, e os eventos de ponteiro propriamente ditos são exibidos à direita do retângulo (para relatar a sequência de eventos).

O código a seguir configura o objeto de destino, declara variáveis globais e identifica os vários ouvintes de eventos de ponteiro para o 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);
        }



Manipular eventos de ponteiro

Em seguida, usamos comentários da interface do usuário para demonstrar manipuladores de eventos de ponteiro básicos.

  • Esse manipulador gerencia um evento de contato de ponteiro (para baixo, pressionado). Adicionamos o evento ao log de eventos, adicionamos o ponteiro à matriz de ponteiros usada para rastrear os ponteiros de interesse e exibimos os detalhes do ponteiro.

    Observação   Eventos PointerPressed e PointerReleased nem sempre ocorrem em pares. Seu aplicativo deve escutar e manipular qualquer evento que possa concluir uma ação de ponteiro para baixo (como PointerExited, PointerCanceled e 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);
            }
    
    
    
  • Esse manipulador gerencia um evento de entrada (sobre, focalização para caneta) de ponteiro. Adicionamos o evento ao log de eventos, adicionamos o ponteiro à coleção de ponteiros e exibimos os detalhes do ponteiro.

    
            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);
            }
    
    
    
  • Esse manipulador gerencia um evento de movimentação de ponteiro. Adicionamos o evento ao log de eventos e atualizamos os detalhes do ponteiro.

    Importante  A entrada do mouse é associada a um único ponteiro atribuído quando detectada pela primeira vez. Se o usuário clicar em um botão do mouse (esquerdo, roda ou direito), será criada uma associação secundária entre o ponteiro e esse botão por meio do evento PointerPressed. O evento PointerReleased é disparado somente quando esse mesmo botão do mouse é liberado (nenhum outro botão pode ser associado ao ponteiro até que o evento seja concluído). Em razão dessa associação exclusiva, outro cliques em botões do mouse são roteados através do 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);
    }
    
    
    
  • Esse manipulador gerencia um evento de roda do mouse (rotação). Nós adicionamos o evento ao log de eventos, adicionamos o ponteiro à matriz de ponteiros (se necessário) e exibimos os detalhes do ponteiro.

    
    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);
    }
    
    
    
  • Esse manipulador gerencia um evento de partida (levantado, para cima) de ponteiro no qual o contato com o digitalizador é encerrado. Adicionamos o evento ao log de eventos, removemos o ponteiro da coleção de ponteiros e atualizamos os detalhes do ponteiro.

    
    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;
    }
    
    
    
  • Esse manipulador gerencia um evento de partida (para fora) de ponteiro no qual o contato com o digitalizador é mantido. Adicionamos o evento ao log de eventos, removemos o ponteiro da matriz de ponteiros e atualizamos os detalhes do ponteiro.

    
    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;
    }
    
    
    
  • Esse manipulador gerencia um evento de cancelamento de ponteiro. Adicionamos o evento ao log de eventos, removemos o ponteiro da matriz de ponteiros e atualizamos os detalhes do ponteiro.

    
    // 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;
    }
    
    
    
  • Esse manipulador gerencia um evento de captura de ponteiro perdido. Adicionamos o evento ao log de eventos, removemos o ponteiro da matriz de ponteiros e atualizamos os detalhes do ponteiro.

    Observação  PointerCaptureLost pode ocorrer no lugar de PointerReleased. A captura do ponteiro pode ser perdida devido a manipulações do usuário ou porque outro ponteiro foi capturado programaticamente, ou a captura do ponteiro atual foi propositalmente liberada.
    
    // 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;
    }
    
    
    

Obter as propriedades de ponteiro

Conforme citado anteriormente, a estrutura de linguagem escolhida para o seu aplicativo determina como você obtém propriedades de ponteiro. Os aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic precisam obter informações de ponteiro mais estendidas por meio de um objeto Windows.UI.Input.PointerPoint obtido pelos métodos GetCurrentPoint e GetIntermediatePoints de PointerRoutedEventArgs.

  • Em primeiro lugar, criamos um novo TextBlock para cada ponteiro.

    
            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);
            }
    
    
    
  • Em seguida, fornecemos uma maneira de atualizar as informações do ponteiro em um TextBlock existente associado a esse ponteiro.

    
            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);
                        }
                    }
                }
            }
    
    
    
  • Por fim, consultamos várias propriedades de ponteiro.

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

Exemplo completo

Veja a seguir o código C# para este exemplo. Confira os Tópicos relacionados no final desta página para acessar links para amostras mais complexas.


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


Resumo e próximas etapas

Neste Guia de início rápido, você aprendeu sobre a entrada de ponteiro em aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic.

Eventos de ponteiro são úteis para o gerenciamento de manipulações simples, como tocar, deslizar e manipulações específicas de dispositivo, incluindo entrada de botões secundários do mouse, roda do mouse, botão da caneta e borracha da caneta.

Para manipular interações mais elaboradas, como os gestos descritos na linguagem de toque do Windows 8, veja Guia de início rápido: entrada por toque

Para saber mais sobre a linguagem de toque do Windows 8, veja Design da interação por toque.

Tópicos relacionados

Desenvolvedores
Respondendo à interação do usuário
Desenvolvendo aplicativos da Windows Store (XAML)
Guia de início rápido: entrada por toque
Designers
Design de interação por toque

 

 

Mostrar:
© 2015 Microsoft