Language: JavaScript and HTML | VB/C#/C++ and XAML

Quickstart: Capturing ink data (Windows Store apps using C#/VB/C++ and XAML)

Applies to Windows only

This Quickstart walks you through configuring your app to capture ink data from an input digitizer.

Objective: After completing this Quickstart you will understand how to use the ink platform to detect and capture input from a pointer device (mouse, pen/stylus, or touch) in a Windows Store app using C++, C#, or Visual Basic.

Prerequisites

This topic assumes that you can create a basic Windows Store app using C++, C#, or Visual Basic. For instructions on creating your first Windows Store app, see Building your first Windows Store app using C++, C#, or Visual Basic.

Instructions

1. Add the namespace for inking

Include the Windows.UI.Input.Inking namespace in your app's code.


using Windows.UI.Input.Inking;


2. Set up a drawing surface in your UI

To support ink in your Windows Store app using C++, C#, or Visual Basic, you need to add a Canvas element. A Canvas is a UI element that acts as a surface for dynamically drawing, rendering, and manipulating graphical elements in a Windows Store app using C++, C#, or Visual Basic.

Here we declare a Canvas element in XAML with a name of InkCanvas that you'll use to reference the element in your C++, C#, or Visual Basic code-behind.


    <!-- Inking area -->
    <Grid x:Name="inkPanel" Grid.Row="1" Margin="0,0,0,61">
        <Canvas x:Name="InkCanvas" Background="White" Margin="62,0,62,10" />
    </Grid>


3. Create an ink manager

Initialize an InkManager object that will process and manipulate the ink-related data obtained from the pointer input.


InkManager _inkManager = new Windows.UI.Input.Inking.InkManager();


4. Attach input event listeners to the drawing surface

Using the name of the Canvas element, attach the following PointerEventHandler listeners for pointer device input. (The event handler functions identified in this example are discussed later in this Quickstart.)

  • PointerPressed fires when a user presses down on the digitizer surface with a pen or finger, or they click the left button on a mouse.
  • PointerMoved fires when the pointer associated with the PointerPressed event moves across the Canvas.
  • PointerReleased fires when the user lifts the pen or finger from the digitizer surface or releases the left mouse button.

InkCanvas.PointerPressed += new PointerEventHandler(InkCanvas_PointerPressed);
InkCanvas.PointerMoved += new PointerEventHandler(InkCanvas_PointerMoved);
InkCanvas.PointerReleased += new PointerEventHandler(InkCanvas_PointerReleased);
InkCanvas.PointerExited += new PointerEventHandler(InkCanvas_PointerReleased);


5. Define the event handler functions

In this section, we define the event handlers to be associated with the event listeners that you added in the previous step.

  • PointerPressed is the event that is used to initiate ink capture.

    In this example, the GetCurrentPoint method gets information about the pointer location, including the coordinates at which to begin displaying the ink data. (Capturing ink and displaying it are two separate actions.) The location coordinates are relative to the Canvas. Next, the code checks the device type associated with the pointer input. If the pointer input is coming from the pen/stylus or the mouse (left button only), the pointer information is passed to _inkManager for processing by calling the ProcessPointerDown method.

    The application-defined global variable, _penID, stores the PointerId of the input pointer associated with this event. We'll discuss the need for this later.

    Note  This example filters the pointer input (using the Pointer.PointerDeviceType property) so that ink capture is performed for pen/stylus input and mouse input only when the left button is pressed. Touch input is reserved for manipulating the UI of the app.

    
    public void InkCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        // Get information about the pointer location.
        PointerPoint pt = e.GetCurrentPoint(InkCanvas);
        _previousContactPt = pt.Position;
    
        // Accept input only from a pen or mouse with the left button pressed. 
        PointerDeviceType pointerDevType = e.Pointer.PointerDeviceType;
        if (pointerDevType == PointerDeviceType.Pen || 
                pointerDevType == PointerDeviceType.Mouse && 
                pt.Properties.IsLeftButtonPressed)
        {
            // Pass the pointer information to the InkManager.
            _inkManager.ProcessPointerDown(pt);
            _penID = pt.PointerId;
    
            e.Handled = true;
        }
    
        else if (pointerDevType == PointerDeviceType.Touch)
        {
            // Process touch input
        }
    }
    
    
    
  • Ink data is captured when a PointerMoved event occurs.

    In the following example, the global variable, _penId, is used to ensure that the PointerId for this event is identical to that of the associated PointerPressed event. If it's not, the input is ignored and no ink data is captured. This is useful, for example, to filter input from a mouse that is moved accidentally during a pen stroke.

    A Line object is used to draw on the Canvas as the mouse moves. The PointerMoved event is then processed through _inkManager by passing the pointer data (GetCurrentPoint) of the event to the ProcessPointerUpdate method.

    
    public void InkCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (e.Pointer.PointerId == _penID)
        {
            PointerPoint pt = e.GetCurrentPoint(InkCanvas);
    
            // Render a red line on the canvas as the pointer moves. 
            // Distance() is an application-defined function that tests
            // whether the pointer has moved far enough to justify 
            // drawing a new line.
            Point currentContactPt = pt.Position;
            if (Distance(currentContactPt, _previousContactPt) > 2)
            {
                Line line = new Line()
                {
                    X1 = _previousContactPt.X,
                    Y1 = _previousContactPt.Y,
                    X2 = currentContactPt.X,
                    Y2 = currentContactPt.Y,
                    StrokeThickness = STROKETHICKNESS,
                    Stroke = new SolidColorBrush(Colors.Red)
                };
    
                _previousContactPt = currentContactPt;
    
                // Draw the line on the canvas by adding the Line object as
                // a child of the Canvas object.
                InkCanvas.Children.Add(line);
    
                // Pass the pointer information to the InkManager.
                _inkManager.ProcessPointerUpdate(pt);
            }
        }
    
        else if (e.Pointer.PointerId == _touchID)
        { 
            // Process touch input
        }
    
        e.Handled = true;
    }
    
    
    
  • Ink data capture is complete when a PointerReleased event occurs.

    As in the previous example, this function uses the global variable, _penId, to ensure that the PointerId for this event is identical to that of the associated PointerPressed and PointerMoved events. If it's not, the input is ignored and no ink data is captured.

    The PointerReleased event is processed through _inkManager by passing the pointer data (GetCurrentPoint) of the event to the ProcessPointerUp method.

    The RenderAllStrokes function in this example is optional and is called to process both the ink data and the raw stroke segments on the Canvas element.

    
    public void InkCanvas_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        if (e.Pointer.PointerId == _penID)
        {
            PointerPoint pt = e.GetCurrentPoint(InkCanvas);
    
            // Pass the pointer information to the InkManager. 
            _inkManager.ProcessPointerUp(pt);
        }
    
        else if (e.Pointer.PointerId == _touchID)
        {
            // Process touch input
        }
    
        _touchID = 0;
        _penID = 0;
    
        // Call an application-defined function to render the ink strokes.
        RenderAllStrokes();
    
        e.Handled = true;
    }
    
    
    

Summary

You now have a basic idea of how to capture ink data with your app.

Related topics

Windows.UI.Input.Inking

 

 

Show:
© 2014 Microsoft. All rights reserved.