title | ms.date | helpviewer_keywords | ms.assetid | description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
The Ink Threading Model |
03/30/2017 |
|
c85fcad1-cb50-4431-847c-ac4145a35c89 |
Learn how, with the Ink Threading model, a tablet pen collects input data at a much higher rate than a mouse does and renders the ink as the user writes. |
One of the benefits of ink on a Tablet PC is that it feels a lot like writing with a regular pen and paper. To accomplish this, the tablet pen collects input data at a much higher rate than a mouse does and renders the ink as the user writes. The application's user interface (UI) thread is not sufficient for collecting pen data and rendering ink, because it can become blocked. To solve this, a WPF application uses two additional threads when a user writes ink.
The following list describes the threads that take part in collecting and rendering digital ink:
-
Pen thread - the thread that takes input from the stylus. (In reality, this is a thread pool, but this topic refers to it as a pen thread.)
-
Application user interface thread - the thread that controls the user interface of the application.
-
Dynamic rendering thread - the thread that renders the ink while the user draws a stroke. The dynamic rendering thread is different than the thread that renders other UI elements for the application, as mentioned in Window Presentation Foundation Threading Model.
The inking model is the same whether the application uses the xref:System.Windows.Controls.InkCanvas or a custom control similar to the one in Creating an Ink Input Control. Although this topic discusses threading in terms of the xref:System.Windows.Controls.InkCanvas, the same concepts apply when you create a custom control.
The following diagram illustrates the threading model when a user draws a stroke:
-
Actions occurring while the user draws the stroke
-
When the user draws a stroke, the stylus points come in on the pen thread. Stylus plug-ins, including the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer, accept the stylus points on the pen thread and have the chance to modify them before the xref:System.Windows.Controls.InkCanvas receives them.
-
The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer renders the stylus points on the dynamic rendering thread. This happens at the same time as the previous step.
-
The xref:System.Windows.Controls.InkCanvas receives the stylus points on the UI thread.
-
-
Actions occurring after the user ends the stroke
-
When the user finishes drawing the stroke, the xref:System.Windows.Controls.InkCanvas creates a xref:System.Windows.Ink.Stroke object and adds it to the xref:System.Windows.Controls.InkPresenter, which statically renders it.
-
The UI thread alerts the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer that the stroke is statically rendered, so the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer removes its visual representation of the stroke.
-
Each xref:System.Windows.UIElement has a xref:System.Windows.Input.StylusPlugIns.StylusPlugInCollection. The xref:System.Windows.Input.StylusPlugIns.StylusPlugIn objects in the xref:System.Windows.Input.StylusPlugIns.StylusPlugInCollection receive and can modify the stylus points on the pen thread. The xref:System.Windows.Input.StylusPlugIns.StylusPlugIn objects receive the stylus points according to their order in the xref:System.Windows.Input.StylusPlugIns.StylusPlugInCollection.
The following diagram illustrates the hypothetical situation where the xref:System.Windows.UIElement.StylusPlugIns%2A collection of a xref:System.Windows.UIElement contains stylusPlugin1
, a xref:System.Windows.Input.StylusPlugIns.DynamicRenderer, and stylusPlugin2
, in that order.
In the previous diagram, the following behavior takes place:
-
StylusPlugin1
modifies the values for x and y. -
xref:System.Windows.Input.StylusPlugIns.DynamicRenderer receives the modified stylus points and renders them on the dynamic rendering thread.
-
StylusPlugin2
receives the modified stylus points and further modifies the values for x and y. -
The application collects the stylus points, and, when the user finishes the stroke, statically renders the stroke.
Suppose that stylusPlugin1
restricts the stylus points to a rectangle and stylusPlugin2
translates the stylus points to the right. In the previous scenario, the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer receives the restricted stylus points, but not the translated stylus points. When the user draws the stroke, the stroke is rendered within the bounds of the rectangle, but the stroke doesn't appear to be translated until the user lifts the pen.
Because accurate hit-testing cannot be performed on the pen thread, some elements might occasionally receive stylus input intended for other elements. If you need to make sure the input was routed correctly before performing an operation, subscribe to and perform the operation in the xref:System.Windows.Input.StylusPlugIns.StylusPlugIn.OnStylusDownProcessed%2A, xref:System.Windows.Input.StylusPlugIns.StylusPlugIn.OnStylusMoveProcessed%2A, or xref:System.Windows.Input.StylusPlugIns.StylusPlugIn.OnStylusUpProcessed%2A method. These methods are invoked by the application thread after accurate hit-testing has been performed. To subscribe to these methods, call the xref:System.Windows.Input.StylusPlugIns.RawStylusInput.NotifyWhenProcessed%2A method in the method that occurs on the pen thread.
The following diagram illustrates the relationship between the pen thread and UI thread with respect to the stylus events of a xref:System.Windows.Input.StylusPlugIns.StylusPlugIn.
As the user draws a stroke, xref:System.Windows.Input.StylusPlugIns.DynamicRenderer renders the ink on a separate thread so the ink appears to "flow" from the pen even when the UI thread is busy. The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer builds a visual tree on the dynamic rendering thread as it collects stylus points. When the user finishes the stroke, the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer asks to be notified when the application does the next rendering pass. After the application completes the next rendering pass, the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer cleans up its visual tree. The following diagram illustrates this process.
-
The user begins the stroke.
- The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer creates the visual tree.
-
The user is drawing the stroke.
- The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer builds the visual tree.
-
The user ends the stroke.
-
The xref:System.Windows.Controls.InkPresenter adds the stroke to its visual tree.
-
The Media Integration Layer (MIL) statically renders the strokes.
-
The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer cleans up the visuals.
-