Interacciones de lápiz y Windows Ink en aplicaciones de Windows

Imagen prominente del Lápiz surface.
Lápiz para Surface (disponible para su compra en Microsoft Store).

Información general

Optimice la aplicación de Windows para la entrada del lápiz para proporcionar tanto la funcionalidad del dispositivo de puntero estándar como la mejor experiencia de Windows Ink para los usuarios.

Nota:

Este tema se centra en la plataforma Windows Ink. Para poder controlar las entradas generales del puntero (es algo similar al mouse, a la función táctil y al panel táctil), consulta el artículo Controlar la entrada de puntero.

Uso de la entrada de lápiz en la aplicación de Windows

Uso del lápiz de Windows y Windows Ink para crear aplicaciones empresariales más atractivas

La plataforma de Windows Ink, junto con un dispositivo de lápiz, te ofrece una forma natural de crear notas, dibujos y anotaciones manuscritas, todo ello de forma digital. Asimismo, la plataforma te permite capturar los datos de entrada del digitalizador a modo de datos de entrada de lápiz, generar datos de entrada de lápiz, administrarlos, representarlos como trazos de lápiz en el dispositivo de salida y convertirlos en texto a través del reconocimiento de escritura a mano.

Además de capturar la posición básica y el movimiento del lápiz a medida que el usuario escribe o dibuja, la aplicación también puede realizar un seguimiento y recopilar los distintos niveles de presión que se usan en un trazo. Esta información, junto con la configuración de la forma de la punta del lápiz, el tamaño y la rotación, el color de la entrada de lápiz y el propósito (como la entrada de lápiz sin formato y las acciones de borrar, resaltar y seleccionar), te permite proporcionar experiencias de usuario que se asemejan mucho a escribir o dibujar sobre papel con un lápiz, un bolígrafo o un pincel.

Nota:

La aplicación también es compatible con la entrada de lápiz de otros dispositivos señaladores, como digitalizadores táctiles y dispositivos de mouse. 

La plataforma de entrada de lápiz es muy flexible. Está diseñada para admitir varios niveles de funcionalidad, dependiendo de los requisitos.

Para obtener directrices sobre la experiencia del usuario de Windows Ink, consulta Controles de entrada de lápiz.

Componentes de la plataforma Windows Ink

Componente Descripción
InkCanvas Un control de plataforma de interfaz de usuario XAML que, de manera predeterminada, recibe y muestra todas las entradas de lápiz como un trazo de lápiz o un trazo de borrado.
Para obtener más información sobre cómo usar InkCanvas, consulta Reconocer trazos de Windows Ink como texto y Almacenar y recuperar datos de trazos de lápiz de Windows Ink.
InkPresenter Un objeto de código subyacente, cuya instancia se creó con un control InkCanvas (expuesto a través de la propiedad InkCanvas.InkPresenter). Este objeto proporciona todas las funcionalidades de entrada manuscrita predeterminadas y que expuso InkCanvas, junto con un completo conjunto de API para la personalización adicional.
Para obtener más información sobre cómo usar InkPresenter, consulta Reconocer trazos de Windows Ink como texto y Almacenar y recuperar datos de trazos de lápiz de Windows Ink.
InkToolbar Control de plataforma de interfaz de usuario XAML que contiene una colección personalizable y extensible de botones que activan características relacionadas con la entrada de lápiz en un inkCanvas asociado.
Para obtener más información sobre cómo usar InkToolbar, consulta Agregar una inkToolbar a una aplicación de entrada manuscrita de windows.
IInkD2DRenderer Habilita la representación de trazos de lápiz en el contexto de dispositivo de Direct2D designado de una aplicación universal de Windows, en lugar del control InkCanvas predeterminado. Esto permite la personalización completa de la experiencia de entrada manuscrita.
Para obtener más información, consulta Complex ink sample (Muestra de entrada de lápiz compleja).

Entrada manuscrita básica con InkCanvas

Para agregar funcionalidad básica de entrada manuscrita, basta con colocar un control de plataforma para UWP inkCanvas en la página adecuada de la aplicación.

De manera predeterminada, el control InkCanvas solo admite la entrada de lápiz que se haya realizado con un lápiz. La entrada se representa como un trazo de lápiz mediante la configuración predeterminada de color y espesor (como un bolígrafo negro con un grosor de 2 píxeles) o se trata como si fuera un borrador de trazos (cuando la entrada se realiza desde un extremo del borrador o cuando la punta del lápiz se modifica con un botón de borrador).

Nota

Si no hay ningún botón o extremo borrador, InkCanvas puede configurarse para procesar la entrada de la punta del lápiz como trazos de borrado.

En este ejemplo, un control InkCanvas se superpone a una imagen en segundo plano.

Nota:

Un InkCanvas tiene las propiedades Height y Width predeterminadas de cero, a menos que sea el elemento secundario de un elemento que ajuste automáticamente el tamaño de sus elementos secundarios, como los controles StackPanel o Grid .

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
        <TextBlock x:Name="Header"
                   Text="Basic ink sample"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   Margin="10,0,0,0" />            
    </StackPanel>
    <Grid Grid.Row="1">
        <Image Source="Assets\StoreLogo.png" />
        <InkCanvas x:Name="inkCanvas" />
    </Grid>
</Grid>

Esta serie de imágenes muestra cómo se representa la entrada manuscrita mediante el control InkCanvas.

Captura de pantalla de InkCanvas en blanco con una imagen de fondo. Captura de pantalla de InkCanvas con trazos de lápiz. Captura de pantalla de InkCanvas con un trazo borrado.
InkCanvas en blanco con una imagen de fondo. InkCanvas con trazos de lápiz. Control InkCanvas con un trazo borrado (ten en cuenta que la opción de borrado actúa en todo el trazo, no en una parte).

La funcionalidad de entrada manuscrita admitida por el control InkCanvas la proporciona un objeto de código subyacente denominado InkPresenter.

Para realizar entradas manuscritas básicas, no es necesario preocuparse por InkPresenter. Sin embargo, para personalizar y configurar el comportamiento de la entrada manuscrita en la clase InkCanvas, debe acceder al objeto correspondiente InkPresenter.

Personalización básica con InkPresenter

Se crea una instancia de un objeto InkPresenter con cada control InkCanvas.

Nota

No se pueden crear instancias de la propiedad InkPresenter directamente. En su lugar, debes acceder a ellas a través de la propiedad InkPresenter de la clase InkCanvas

Además de proporcionar todos los comportamientos de entrada manuscrita predeterminados de su control InkCanvas correspondiente, InkPresenter proporciona un conjunto completo de API para personalizar más trazos y administrar más detalladamente la entrada del lápiz (estándar y modificado). Esto incluye las propiedades de trazo, los tipos de dispositivo de entrada admitidos y si el objeto procesa la entrada o se pasa a la aplicación para su procesamiento.

Nota

La entrada de lápiz estándar (desde la punta del lápiz o el botón de borrador) no se modifica con una prestación de hardware secundaria, como un botón de barril de lápiz, un botón derecho del mouse o un mecanismo similar.

De forma predeterminada, solo se admite la entrada manuscrita para la entrada del lápiz. En este apartado, configuraremos InkPresenter para que interprete los datos de entrada del lápiz y el mouse como trazos de lápiz. También establecemos algunos atributos iniciales de trazo de lápiz que se usan para representar trazos en InkCanvas.

Para habilitar el mouse y la entrada manuscrita táctil, establezca la propiedad InputDeviceTypes de InkPresenter en la combinación de valores CoreInputDeviceTypes que desee.

public MainPage()
{
    this.InitializeComponent();

    // Set supported inking device types.
    inkCanvas.InkPresenter.InputDeviceTypes =
        Windows.UI.Core.CoreInputDeviceTypes.Mouse |
        Windows.UI.Core.CoreInputDeviceTypes.Pen;

    // Set initial ink stroke attributes.
    InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
    drawingAttributes.Color = Windows.UI.Colors.Black;
    drawingAttributes.IgnorePressure = false;
    drawingAttributes.FitToCurve = true;
    inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}

Los atributos de trazo de lápiz se pueden establecer de forma dinámica para así ajustarlos a las preferencias del usuario o a los requisitos de la aplicación.

Aquí dejamos que un usuario elija en una lista de colores de entrada de lápiz.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
        <TextBlock x:Name="Header"
                   Text="Basic ink customization sample"
                   VerticalAlignment="Center"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   Margin="10,0,0,0" />
        <TextBlock Text="Color:"
                   Style="{StaticResource SubheaderTextBlockStyle}"
                   VerticalAlignment="Center"
                   Margin="50,0,10,0"/>
        <ComboBox x:Name="PenColor"
                  VerticalAlignment="Center"
                  SelectedIndex="0"
                  SelectionChanged="OnPenColorChanged">
            <ComboBoxItem Content="Black"/>
            <ComboBoxItem Content="Red"/>
        </ComboBox>
    </StackPanel>
    <Grid Grid.Row="1">
        <Image Source="Assets\StoreLogo.png" />
        <InkCanvas x:Name="inkCanvas" />
    </Grid>
</Grid>

A continuación, controlamos los cambios en el color seleccionado y actualizamos los atributos de trazo de lápiz en consecuencia.

// Update ink stroke color for new strokes.
private void OnPenColorChanged(object sender, SelectionChangedEventArgs e)
{
    if (inkCanvas != null)
    {
        InkDrawingAttributes drawingAttributes =
            inkCanvas.InkPresenter.CopyDefaultDrawingAttributes();

        string value = ((ComboBoxItem)PenColor.SelectedItem).Content.ToString();

        switch (value)
        {
            case "Black":
                drawingAttributes.Color = Windows.UI.Colors.Black;
                break;
            case "Red":
                drawingAttributes.Color = Windows.UI.Colors.Red;
                break;
            default:
                drawingAttributes.Color = Windows.UI.Colors.Black;
                break;
        };

        inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
    }
}

Estas imágenes muestran cómo se procesa y personaliza la entrada manuscrita mediante InkPresenter.

Captura de pantalla que muestra InkCanvas con trazos de lápiz negro predeterminados.

InkCanvas con trazos de lápiz negro predeterminados.

Captura de pantalla de InkCanvas con trazos de lápiz rojos seleccionados por el usuario.

InkCanvas con trazos de lápiz rojo seleccionados por el usuario.

Para proporcionar funcionalidades que vayan más allá de la entrada manuscrita y el borrado (como la selección de trazo), la aplicación debe identificar la entrada específica de InkPresenter, la cual debe pasarse sin procesar para que la aplicación la controle.

Entrada de paso a través para el procesamiento avanzado

De forma predeterminada, InkPresenter procesa todas las entradas como un trazo de lápiz o un trazo de borrado, incluida la entrada modificada por una prestación de hardware secundaria, como un botón de barril de lápiz, un botón derecho del mouse o similar. Sin embargo, los usuarios suelen esperar alguna funcionalidad adicional o un comportamiento modificado con estas prestaciones secundarias.

En algunos casos, es posible que también tengas que exponer funcionalidad adicional para los lápices sin prestaciones secundarias (la funcionalidad no suele estar asociada con la sugerencia del lápiz), otros tipos de dispositivos de entrada o algún tipo de comportamiento modificado en función de una selección de usuario en la interfaz de usuario de la aplicación.

Para que esta acción sea compatible, puedes configurar InkPresenter para que deje una entrada específica sin procesar. A continuación, esta entrada sin procesar se pasa a través de la aplicación para su procesamiento.

Ejemplo: uso de la entrada sin procesar para implementar la selección de trazos

La plataforma Windows Ink no proporciona compatibilidad integrada con acciones que requieren entrada modificada, como la selección de trazos. Para admitir características como esta, debe proporcionar una solución personalizada en las aplicaciones.

En el ejemplo de código siguiente (todo el código está en los archivos MainPage.xaml y MainPage.xaml.cs) se describe cómo habilitar la selección de trazos cuando se modifica la entrada con un botón de barril de lápiz (o botón derecho del mouse).

  1. En primer lugar, debemos configurar la interfaz de usuario en MainPage.xaml.

    Una vez hecho esto, agregamos un lienzo (debajo de InkCanvas) para dibujar el trazo de selección. Si usas una capa independiente para dibujar el trazo de selección, InkCanvas y su contenido no se modifican.

    Captura de pantalla de InkCanvas en blanco con un lienzo de selección subyacente.

      <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
          <TextBlock x:Name="Header"
            Text="Advanced ink customization sample"
            VerticalAlignment="Center"
            Style="{ThemeResource HeaderTextBlockStyle}"
            Margin="10,0,0,0" />
        </StackPanel>
        <Grid Grid.Row="1">
          <!-- Canvas for displaying selection UI. -->
          <Canvas x:Name="selectionCanvas"/>
          <!-- Inking area -->
          <InkCanvas x:Name="inkCanvas"/>
        </Grid>
      </Grid>
    
  2. En MainPage.xaml.cs, declaramos un par de variables globales para mantener las referencias a los aspectos de la interfaz de usuario de selección. Usaremos específicamente el trazo de lazo de selección y el rectángulo delimitador que resalta los trazos seleccionados.

      // Stroke selection tool.
      private Polyline lasso;
      // Stroke selection area.
      private Rect boundingRect;
    
  3. A continuación, configuramos InkPresenter para interpretar los datos de entrada de lápiz y mouse como trazos de lápiz, y establecemos algunos atributos iniciales de trazos de lápiz usados para representar trazos en InkCanvas.

    Recuerda usar la propiedad InputProcessingConfiguration de InkPresenter para indicar que la aplicación debe procesar cualquier entrada modificada. La entrada modificada se especifica asignando InputProcessingConfiguration.RightDragAction un valor de InkInputRightDragAction.LeaveUnprocessed. Cuando se establece este valor, InkPresenter pasa a la clase InkUnprocessedInput , un conjunto de eventos de puntero que se van a controlar.

    Asignamos agentes de escucha para los eventos PointerPressed, PointerMoved y PointerReleased no procesados pasados por InkPresenter. Todas las funcionalidades de selección se implementan en los controladores de estos eventos.

    Por último, asignamos agentes de escucha para los eventos StrokeStarted y StrokesErased de la propiedad InkPresenter. Los controladores de estos eventos se usan para limpiar la interfaz de usuario de selección si se inicia un nuevo trazo o se borra un trazo existente.

    Captura de pantalla de la aplicación de ejemplo de personalización avanzada de lápiz que muestra inkcanvas con trazos de lápiz negro predeterminados.

      public MainPage()
      {
        this.InitializeComponent();
    
        // Set supported inking device types.
        inkCanvas.InkPresenter.InputDeviceTypes =
          Windows.UI.Core.CoreInputDeviceTypes.Mouse |
          Windows.UI.Core.CoreInputDeviceTypes.Pen;
    
        // Set initial ink stroke attributes.
        InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
        drawingAttributes.Color = Windows.UI.Colors.Black;
        drawingAttributes.IgnorePressure = false;
        drawingAttributes.FitToCurve = true;
        inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
    
        // By default, the InkPresenter processes input modified by
        // a secondary affordance (pen barrel button, right mouse
        // button, or similar) as ink.
        // To pass through modified input to the app for custom processing
        // on the app UI thread instead of the background ink thread, set
        // InputProcessingConfiguration.RightDragAction to LeaveUnprocessed.
        inkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction =
            InkInputRightDragAction.LeaveUnprocessed;
    
        // Listen for unprocessed pointer events from modified input.
        // The input is used to provide selection functionality.
        inkCanvas.InkPresenter.UnprocessedInput.PointerPressed +=
            UnprocessedInput_PointerPressed;
        inkCanvas.InkPresenter.UnprocessedInput.PointerMoved +=
            UnprocessedInput_PointerMoved;
        inkCanvas.InkPresenter.UnprocessedInput.PointerReleased +=
            UnprocessedInput_PointerReleased;
    
        // Listen for new ink or erase strokes to clean up selection UI.
        inkCanvas.InkPresenter.StrokeInput.StrokeStarted +=
            StrokeInput_StrokeStarted;
        inkCanvas.InkPresenter.StrokesErased +=
            InkPresenter_StrokesErased;
      }
    
  4. A continuación, definimos controladores para los eventos PointerPressed, PointerMoved y PointerReleased no procesados pasados por InkPresenter.

    Todas las funcionalidades de selección se implementan en estos controladores, incluido el trazo de lazo y el rectángulo delimitador.

    Captura de pantalla de la lazo de selección.

      // Handle unprocessed pointer events from modified input.
      // The input is used to provide selection functionality.
      // Selection UI is drawn on a canvas under the InkCanvas.
      private void UnprocessedInput_PointerPressed(
        InkUnprocessedInput sender, PointerEventArgs args)
      {
        // Initialize a selection lasso.
        lasso = new Polyline()
        {
            Stroke = new SolidColorBrush(Windows.UI.Colors.Blue),
            StrokeThickness = 1,
            StrokeDashArray = new DoubleCollection() { 5, 2 },
            };
    
            lasso.Points.Add(args.CurrentPoint.RawPosition);
    
            selectionCanvas.Children.Add(lasso);
        }
    
        private void UnprocessedInput_PointerMoved(
          InkUnprocessedInput sender, PointerEventArgs args)
        {
          // Add a point to the lasso Polyline object.
          lasso.Points.Add(args.CurrentPoint.RawPosition);
        }
    
        private void UnprocessedInput_PointerReleased(
          InkUnprocessedInput sender, PointerEventArgs args)
        {
          // Add the final point to the Polyline object and
          // select strokes within the lasso area.
          // Draw a bounding box on the selection canvas
          // around the selected ink strokes.
          lasso.Points.Add(args.CurrentPoint.RawPosition);
    
          boundingRect =
            inkCanvas.InkPresenter.StrokeContainer.SelectWithPolyLine(
              lasso.Points);
    
          DrawBoundingRect();
        }
    
  5. Para concluir el controlador de eventos PointerReleased, borramos la capa de selección de todo el contenido (trazo de lazo) y, a continuación, dibujamos un único rectángulo delimitador alrededor de los trazos de lápiz incluidos en el área del lazo.

    Captura de pantalla del rectángulo delimitador de selección.

      // Draw a bounding rectangle, on the selection canvas, encompassing
      // all ink strokes within the lasso area.
      private void DrawBoundingRect()
      {
        // Clear all existing content from the selection canvas.
        selectionCanvas.Children.Clear();
    
        // Draw a bounding rectangle only if there are ink strokes
        // within the lasso area.
        if (!((boundingRect.Width == 0) ||
          (boundingRect.Height == 0) ||
          boundingRect.IsEmpty))
          {
            var rectangle = new Rectangle()
            {
              Stroke = new SolidColorBrush(Windows.UI.Colors.Blue),
                StrokeThickness = 1,
                StrokeDashArray = new DoubleCollection() { 5, 2 },
                Width = boundingRect.Width,
                Height = boundingRect.Height
            };
    
            Canvas.SetLeft(rectangle, boundingRect.X);
            Canvas.SetTop(rectangle, boundingRect.Y);
    
            selectionCanvas.Children.Add(rectangle);
          }
        }
    
  6. Por último, definimos los controladores de los eventos StrokeStarted y StrokesErased de la propiedad InkPresenter.

    Ambos llaman a la misma función de limpieza para borrar la selección actual siempre que se detecta un nuevo trazo.

      // Handle new ink or erase strokes to clean up selection UI.
      private void StrokeInput_StrokeStarted(
        InkStrokeInput sender, Windows.UI.Core.PointerEventArgs args)
      {
        ClearSelection();
      }
    
      private void InkPresenter_StrokesErased(
        InkPresenter sender, InkStrokesErasedEventArgs args)
      {
        ClearSelection();
      }
    
  7. Esta es la función para quitar toda la interfaz de usuario de selección del lienzo de selección cuando se inicia un nuevo trazo o se borra un trazo existente.

      // Clean up selection UI.
      private void ClearSelection()
      {
        var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
        foreach (var stroke in strokes)
        {
          stroke.Selected = false;
        }
        ClearDrawnBoundingRect();
       }
    
      private void ClearDrawnBoundingRect()
      {
        if (selectionCanvas.Children.Any())
        {
          selectionCanvas.Children.Clear();
          boundingRect = Rect.Empty;
        }
      }
    

Representación de entrada de lápiz personalizada

De forma predeterminada, la entrada de lápiz se procesa en un subproceso de fondo de baja latencia y se representa en curso, o "mojado", ya que se dibuja. Cuando se completa el trazo (se levanta el lápiz o el dedo o se libera el botón del mouse), el trazo se procesa en el subproceso de la interfaz de usuario y se representa como "seco" en la capa de InkCanvas (lo verás sobre el contenido de la aplicación y reemplazando la entrada de lápiz húmeda).

Puede invalidar este comportamiento predeterminado y controlar completamente la experiencia de entrada manuscrita mediante el "secado personalizado" de los trazos de lápiz húmedos. Aunque el comportamiento predeterminado suele ser suficiente para la mayoría de las aplicaciones, hay algunos casos en los que podría ser necesario el secado personalizado, estos incluyen:

  • Administración más eficaz de colecciones de trazos de lápiz grandes o complejos
  • Compatibilidad con movimiento panorámico y zoom más eficaz en lienzos de lápiz grandes
  • Intercalar la entrada de lápiz y otros objetos, como formas o texto, a la vez que se mantiene el orden z
  • Secado y conversión de tinta sincrónicamente en una forma DirectX (por ejemplo, una línea recta o forma rasterizada e integrada en el contenido de la aplicación en lugar de como una capa InkCanvas independiente).

El secado personalizado requiere un objeto IInkD2DRenderer para administrar la entrada de lápiz y representarla en el contexto de dispositivo Direct2D de la aplicación universal de Windows, en lugar del control InkCanvas predeterminado.

Al llamar a ActivateCustomDrying (antes de cargar InkCanvas), una aplicación crea un objeto InkSynchronizer para personalizar la representación de un trazo de lápiz seco en la clase SurfaceImageSource o VirtualSurfaceImageSource.

SurfaceImageSource y VirtualSurfaceImageSource proporcionan una superficie compartida de DirectX para que la aplicación se dibuje y componga en el contenido de la aplicación, aunque VSIS proporciona una superficie virtual que es mayor que la pantalla para realizar el movimiento panorámico y el zoom. Dado que las actualizaciones visuales de estas superficies se sincronizan con el subproceso de interfaz de usuario XAML, cuando la entrada de lápiz se representa en cualquiera de ellas, la tinta húmeda se puede quitar de InkCanvas simultáneamente.

También puede personalizar la entrada de lápiz seca en un SwapChainPanel, pero no se garantiza la sincronización con el subproceso de la interfaz de usuario y puede haber un retraso entre cuando la entrada de lápiz se representa en swapChainPanel y cuando se quita la entrada de lápiz de InkCanvas.

Para obtener un ejemplo completo de esta funcionalidad, consulta la muestra de entrada de lápiz compleja.

Nota:

El secado personalizado y la clase InkToolbar
Si tu aplicación invalida el comportamiento predeterminado de representación de entrada de lápiz de la clase InkPresenter con una implementación de secado personalizado, los trazos de lápiz representados ya no están disponibles para InkToolbar y los comandos de borrado integrados de InkToolbar no funcionan según lo previsto. Para proporcionar la funcionalidad de borrado, debes controlar todos los eventos de puntero, realizar la prueba de posicionamiento en cada trazo e invalidar el comando "Borrar todas las entradas de lápiz" integrado.

Tema Descripción
Reconocer trazos de lápiz Conversión de trazos de lápiz en texto mediante el reconocimiento de escritura a mano o en formas mediante el reconocimiento personalizado
Almacenar y recuperar trazos de lápiz Almacena los datos de trazo de lápiz en un archivo de formato de intercambio de elementos gráficos (GIF) mediante los metadatos Ink Serialized Format (ISF) insertados.
Agregar un control InkToolbar a una aplicación de entrada manuscrita de Windows Agregue una inkToolbar predeterminada a una aplicación de Windows de entrada manuscrita, agregue un botón de lápiz personalizado a InkToolbar y enlace el botón de lápiz personalizado a una definición de lápiz personalizada.

API existentes

Ejemplos

Muestras de archivo