Processing input with DirectManipulation
This section provides an overview of the Direct Manipulation threading model, how window messages are processed by Direct Manipulation, and how the state of a viewport changes as input is mapped to output motions.
Direct Manipulation uses two threads to coordinate asynchronous operations:
UI thread - the thread that owns the HWND associated with input. This thread owns initialization of Direct Manipulation. Mouse and keyboard input processing also happens on the UI thread.
Delegate thread - the thread created and owned by Direct Manipulation. Touch input processing happens on the delegate thread.
In a typical configuration where hit testing is done on the UI thread, window messages are processed by Direct Manipulation in the following order:
For a viewport at rest:
- A series of window messages reach the delegate thread.
- WM_POINTERDOWN and DM_POINTERHITTEST messages are sent by the delegate thread to the Independent Hit Test (IHT) thread.
- If SetContact is called from the IHT thread, messages might get sent to the UI thread by the delegate thread, depending on the value of DIRECTMANIPULATION_HITTEST_TYPE when RegisterHitTestTarget was called.
- If SetContact is not called from the IHT thread, messages are always sent by the delegate thread to the UI thread.
- The client can call SetContact from the UI thread to let Direct Manipulation detect a manipulation.
- If a manipulation is detected, Direct Manipulation sends a WM_POINTERCAPTURECHANGED message to notify the client that the input is being handled by Direct Manipulation. The viewport status is set to RUNNING and the output transform will be updated.
- If an interaction other than a manipulation is detected, Direct Manipulation sends remaining messages to the UI thread.
For a viewport in motion (with a status of RUNNING or INERTIA), the window message reaches the delegate thread first, where Direct Manipulation hit tests against all running viewports. Direct Manipulation automatically assigns the contact to the appropriate viewports identified by hit testing. The viewport status is RUNNING and the output transform will be updated.
In some cases, an application UI thread may be too slow to respond to hit testing. A hit test thread may be used (RegisterHitTestTarget) to allow the client to move WM_POINTERDOWN and DM_POINTERHITTEST messages to a specific thread to allow for hit testing.
Typically, Direct Manipulation sends only WM_POINTERDOWN and DM_POINTERHITTEST messages to the UI thread, withholding later messages while waiting for a response from the client. If the client calls SetContact, the only messages the UI thread receives when a manipulation is detected are WM_POINTERDOWN,DM_POINTERHITTEST, and WM_POINTERCAPTURECHANGED.
The client might not call SetContact when processing WM_POINTERDOWN and DM_POINTERHITTEST messages. In this case, Direct Manipulation sends all messages to the UI thread without analyzing the messages to see if there is a manipulation. The client can then choose any point to call SetContact and have Direct Manipulation start detecting manipulations, and send WM_POINTERCAPTURECHANGED messages when one is detected.
Windows 10 and later: You can decide which manipulations you want to handle by calling DeferContact before calling SetContact on a WM_POINTERDOWN or DM_POINTERHITTEST message. DeferContact ensures all subsequent messages are sent to the UI thread for the specified period of time.