Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Windows Touch 程式開發
許煜坤
台灣微軟研究開發處
2010/3/10
Agendas
• “Good, Better, Best” model
• Platforms details
– WPF 4 – Integrated Foundation for Multi-Touch
– Silverlight 3.0/4.0
– Native Win32 APIs – MS Windows SDK 7.0
– Windows 7 Multi-Touch .Net Interop Sample Library – VS2008 (Windows Form, WPF)
• Related contents and resources
Touch Platform Overview Good Better Best
APIs For Free! •Panning/zoom
gestures •Right click gesture
•Gesture notifications •Pan/zoom/rotate/etc
•Raw touch data •Manipulation and
Inertia processors
Native Win32
•Controls with standard scrollbars
•WM_GESTURE message •WM_TOUCH •COM based
Manipulation and Inertia Processors
WPF •WPF 4.0 pan support in ScrollViewer etc.
•Gesture events • Inertia configuration
• Touch events •Manipulation and Inertia
Processors
WinForms •Controls with standard scrollbars
•WM_GESTURE message • P/Invoke
•Manipulation and Inertia Processors in Microsoft.Ink.DLL
•Real-time Stylus or Ink Collector
GetSystemMetrics() • SM_DIGITIZER returns data about available
digitizers on the system
• SM_TABLETPC returns data about Tablet functionality
• SM_MAXIMUMTOUCHES yields the largest number of contacts any of the available digitizers supports
• P/Invoke in c# [DllImport("user32.dll")] static extern int GetSystemMetrics(SystemMetric smIndex);
WPF 4 Multi-Touch APIs Overview
WPF Controls Styles with Panning Enabled
ScrollViewer Panning Support
Manipulation Events
Touch Events
Extensible Touch Device
Win7 Touch Device Surface Touch
Device
WPF 4.0 Experiences
demo
Row Touch
Multi-Touch and Multi-Capture
• Enables multiple active controls
• APIs:
– UIElement.CaptureTouch(TouchDevice)
– Got/LostTouchCapture event
– AreAnyTouchesCaptured/Within
– TouchDevice.Capture(IInputElement)
– TouchDevice.Captured, CaptureMode
WPF 4 Touch Events public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // listen to touch events from the system this.TouchDown += new EventHandler<TouchEventArgs>(MainWindow_TouchDown); this.TouchMove += new EventHandler<TouchEventArgs>(MainWindow_TouchMove); this.TouchUp += new EventHandler<TouchEventArgs>(MainWindow_TouchUp); } void MainWindow_TouchUp(object sender, TouchEventArgs e) { // a new touch has come down } void MainWindow_TouchMove(object sender, TouchEventArgs e) { // a previously down touch has moved } void MainWindow_TouchDown(object sender, TouchEventArgs e) { // a touch has been removed } }
WPF 4.0 Experience
demo
Manipulations
Manipulation Container
Canvas
Manipulation Events
Starting Started Delta Inertia
Starting Delta Completed
StartInertia() StartInertia()
Touch Down (Initial)
Touch Move Touch Up
(All)
Initialize: •Mode •Container •Pivot
Completed()
Manipulation Delta Event Args Manipulation Delta Event Args Type Description
ManipulationContainer IInputElement
ManipulationOrigin Point Relative to container
IsInertial bool true after Inertia Starting event
Manipulators IEnumerable<IManipulators> (RC Builds Only)
Velocities AngularVelocity : Double Degrees per millisec
ExpansionVelocity: Vector 1/96th inch per millisec
LinearVelocity: Vector 1/96th inch per millisec
DeltaManipulation Expansion Relative to container Since last event
Rotation
Scale
Translation
CumulativeManipulation Expansion Relative to container Since Manipulation Started event
Rotation
Scale
Translation
StartInertia() Jump to Inertia Starting event
Complete() Jump to Completed event
Cancel() Cancel and promote to mouse (RC)
WPF 4 Manipulations Events public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.ManipulationStarted += new
EventHandler<ManipulationStartedEventArgs>(MainWindow_ManipulationStarted); this.ManipulationInertiaStarting += new
EventHandler<ManipulationInertiaStartingEventArgs>(MainWindow_ManipulationInertiaStarting); this.ManipulationCompleted += new
EventHandler<ManipulationCompletedEventArgs>(MainWindow_ManipulationCompleted); this.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(MainWindow_ManipulationDelta); } void MainWindow_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { // process delta data } void MainWindow_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) { // Manipulations/Inertia complete } void MainWindow_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) { // start inertia } void MainWindow_ManipulationStarted(object sender, ManipulationStartedEventArgs e) { // Manipulations started } }
WPF 4.0 Experience
demo
Manipulation Inertia
Inertia Behaviors
• Deceleration and Displacement/Rotation/Expansion mutually exclusive
• Deceleration – useful to simulate friction • Displacement – useful on page flips • Default – no inertial movements
ManipulationInertiaStarting EventArgs
Properties Units
TranslationBehavior InitialVelocity 1/96th DIP per millisec
DesiredDeceleration 1/96th DIP per millisec^2
DesiredDisplacement 1/96th DIP
RotationBehavior InitialVelocity Degrees per millisec
DesiredDeceleration Decrees per millisec^2
DesiredRotation Degrees
ExpansionBehavior InitialVelocity 1/96th DIP per millisec
InitialRadius 1/96th DIP
DesiredDeceleration 1/96th DIP per millisec^2
DesiredExpansion 1/96th DIPS
WPF 4.0 Experience
demo
Manipulation Pivot
Manipulation Pivot
• Pivot enables single finger rotation – Center property specifies pivot center
– Radios property specifies slack around center
• Default to no Manipulation Pivot
• Set initial Pivot in: – ManipulationStartingEventArgs.Pivot
• Update during manipulation with: – Manipluation.Set/GetManipulationPivot()
– Only valid during Started and Completed events
WPF 4.0 Experience
demo
Boundary Feedback
Boundary Feedback
• ManipulationDelta Event handler reports boundary feedback – ReportBoundaryFeedback(ManipulationDelta)
• Window class translates BoundaryFeedback event to Windows 7 Boundary Feedback
• Handle BoundaryFeedback at Control level. E.g. Listbox – ManipulationBoundaryFeedback event
WPF 4.0 Experience
demo
Extensible Touch Device
Extensible Touch Device
• Derive from abstract class TouchDevice – StylusTouchDevice for Windows 7
– SurfaceTouchDevice for Surface
• One touch device per contact
• Call SetActiveSource()
• Call Activate/Deactivate, ReportDown/Move/Up to update the device state
• Override GetTouchPoint() to provide position data – Use Visual.TransformToDescendant()
• GetIntermediateTouchPoints() can return empty collection
Implementing TouchDevice
• Initialize – Call SetActiveSource()
– Call Activate()
• Updates – Call ReportDown/Move/Up()
• Return State – Override GetTouchPoint()
– TouchPoint Extensible
• Cleanup – Call Deactivate()
SetActiveSource
Activate
ReportDown
ReportMove
ReportUp
Deactivate
Silverlight 3.0 Touch Experiences
demo
Silverlight 3.0 • Add Touch.FrameReported event handler
• GetTouchPoints or GetPrimaryTouchPoint to get TouchPoint
• TouchPoint Class
– Position
– TouchAction – Up, Down and Move
Silverlight 3 Touch APIs - Listening
public partial class MainPage : UserControl { public MainPage() { ... // listen to touch events from the system Touch.FrameReported += new TouchFrameEventHandler(OnFrame); } void OnFrame(object sender, TouchFrameEventArgs e) { // enumerate and respond to touch events } }
Silverlight 3 Touch APIs - Processing
void Touch_FrameReported(object sender, TouchFrameEventArgs e) { TouchPointCollection touchPoints = e.GetTouchPoints(LayoutRoot); foreach (TouchPoint tp in touchPoints) { if (tp.Action == TouchAction.Down) { // a new touch has come down } if (tp.Action == TouchAction.Move) { // a previously down touch has moved } if (tp.Action == TouchAction.Up) { // a touch has been removed } } }
Microsoft Surface Manipulations and Inertia Sample for Microsoft Silverlight
demo
Gesture Experiences
demo
WM_GESTURE Applications
Windows Touch Gesture WM_GESTURE
• Provides notifications when the user performs gestures over your window
• Contains additional information like center of gesture and gesture-specific arguments
• WM_GESTURENOTIFY – SetGestureConfig & GESTURECONFIG Structure
• WM_GESTURE – GetGestureInfo & GESTUREINFO Structure
• Gesture command – GID_ZOOM, GID_PAN, GID_ROTATE, GID_TWOFINGERTAP, GID_PRESSANDTAP
– CloseGestureInfoHandle
Decode Gesture LRESULT DecodeGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
// Create a structure to populate and retrieve the extra message info.
GESTUREINFO gi;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(GESTUREINFO);
BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
BOOL bHandled = FALSE;
if (bResult) {
// now interpret the gesture
switch (gi.dwID) {
case GID_ZOOM:
// Code for zooming goes here
bHandled = TRUE;
break;
….
}
} else {
// error handeling
}
if (bHandled) {
return 0;
} else {
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
Disable Flicks #include <tpcshrd.h> [...] BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ [...] const DWORD_PTR dwHwndTabletProperty =
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) //gesture TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up //(waves) TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen //button down (circle) TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, //drag up) SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY,
reinterpret_cast<HANDLE>(dwHwndTabletProperty));
Richer Touch Experiences
demo
WM_TOUCH Applications
Windows Touch Input WM_TOUCH
• Provides raw touch input data, conceptually similar to mouse messages
• Finger painting, custom gestures, feeding higher-level controls (e.g. Manipulations)
• Touch APIs – RegisterTouchWindow & UnregisterTouchWindow
– GetTouchInputInfo & CloseTouchInputHandle
• Decode WM_TOUCH message – GetTouchInputInfo & TOUCHINPUT Structure
• TOUCHEVENTF_DOWN, TOUCHEVENTF_MOVE, TOUCHEVENTF_UP
– CloseTouchInputHandle
Decode Touch LRESULT OnTouch( WPARAM wParam, LPARAM lParam ) { UINT cInputs = LOWORD(wParam); PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs]; if (NULL != pInputs) { if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) { for (UINT i=0; i<cInputs; i++) { // insert your input handler code here //ProcessInputs(pInputs[i].dwID, pInputs[i].x, pInputs[i].y); // or, you could return // DefWindowProc(hWnd, WM_TOUCH, wParam, lParam); // if you are not handling the message } } else { // GetLastError() and error handling } delete [] pInputs; } else { // error handling, presumably out of memory } if (!CloseTouchInputHandle((HTOUCHINPUT)lParam)) { // error handling } return 0; }
Touch-Optimized Experiences
demo
WM_TOUCH, Manipulations and More
Manipulations in Unmanaged Code • Implement event sink for the _IManipulationEvents
interface • Pass data received from WM_TOUCH to the
IManipulationProcessor – ProcessDown – ProcessMove – ProcessUp
• IManipulationEvents methods – ManipulationStatred – ManipulationDelta – ManipulationCompleted
• IManipulationProcessor properties – Single Finger Rotation – PivotPointX, PivotPointY, PivotRadius
Inertia in Unmanaged Code • Add IInertiaProcessor interface • Pass data received from WM_TOUCH to the
IManipulationProcessor – ProcessDown – ProcessMove – ProcessUp
• IManipulationEvents methods – ManipulationStatred – ManipulationDelta – ManipulationCompleted
• IInertiaProcessor methods – Reset – Process – Complete
• IInertiaProcessor properties – Smooth object animation using the Velocity, Deceleration and
Displacement properties – Controlling object position using elastic bounds
Manipulations/Inertia Flow
Started Delta Inertia
Starting Delta Completed
Touch Down
Touch Move
Touch Up
ProcessDown() ProcessMove() ProcessUp()
Send Touch Event Data to the Manipulation Processor
LRESULT OnTouch(HWND hWnd, WPARAM wParam, LPARAM lParam ) { UINT cInputs = LOWORD(wParam); PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs]; BOOL bHandled = FALSE; if (NULL != pInputs) { if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) { for (UINT i=0; i<cInputs; i++) { if (pInputs[i].dwFlags & TOUCHEVENTF_DOWN){ g_pIManipProc->ProcessDown(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y)); bHandled = TRUE; } if (pInputs[i].dwFlags & TOUCHEVENTF_UP){ g_pIManipProc->ProcessUp(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y)); bHandled = TRUE; } if (pInputs[i].dwFlags & TOUCHEVENTF_MOVE){ g_pIManipProc->ProcessMove(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y)); bHandled = TRUE; } } } else { // GetLastError() and error handling } delete [] pInputs; } else { // error handling, presumably out of memory } ….. }
Implement IManipulationEvents HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationStarted( /* [in] */ FLOAT x, /* [in] */ FLOAT y) { // place your code handler here to initialize any members before starting manipulation return S_OK; } HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationDelta( /* [in] */ FLOAT x, /* [in] */ FLOAT y, /* [in] */ FLOAT translationDeltaX, /* [in] */ FLOAT translationDeltaY, /* [in] */ FLOAT scaleDelta, /* [in] */ FLOAT expansionDelta, /* [in] */ FLOAT rotationDelta, /* [in] */ FLOAT cumulativeTranslationX, /* [in] */ FLOAT cumulativeTranslationY, /* [in] */ FLOAT cumulativeScale, /* [in] */ FLOAT cumulativeExpansion, /* [in] */ FLOAT cumulativeRotation) { // place your code handler here to handle delta values return S_OK; } HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationCompleted( /* [in] */ FLOAT x, /* [in] */ FLOAT y, /* [in] */ FLOAT cumulativeTranslationX, /* [in] */ FLOAT cumulativeTranslationY, /* [in] */ FLOAT cumulativeScale, /* [in] */ FLOAT cumulativeExpansion, /* [in] */ FLOAT cumulativeRotation) { // place your code handler here to do any operations based on the manipulation return S_OK; }
WPF 3.5 SP1 Experiences
demo
Real Time Stylus, Manipulations and Inertia
Windows 7 Multi-Touch .Net Interop Sample Library
• Wrappers for Windows Form and WPF 3.5 SP1 apps
• Wrappers for – Touch Message
– Gesture Message
– ManipulationProcessor
– ManipulationInertiaProcessor
• Can be downloaded from http://code.msdn.microsoft.com/WindowsTouch (PDC 2008)
Windows 7 Multi-Touch .Net Interop Sample Library - Gesture
• Create GestureHandler • Implement events handler
– Pan – PanBegin – PanEnd – Rotate – RotateBegin – RotateEnd – PressAndTapap – Zoom – ZoomBegin – ZoomEnd
Windows 7 Multi-Touch .Net Interop Sample Library - Touch
• Create TouchHandler
• Implement events handler
– TouchDown
– TouchMove
– TouchUp
Windows 7 Multi-Touch .Net Interop Sample Library - Manipulation
• Create TouchHandler or EnableStylusEvents
– TouchDown, TouchMove, TouchUp
– StylusDown, StylusMove, StylusUp
• Create Manipulationprocessor
– Implement events handler
• ManipulationDelta
• ManipulationCompleted
• ManipulationStarted
Windows 7 Multi-Touch .Net Interop Sample Library - Inertia
• Create TouchHandler or EnableStylusEvents
– TouchDown, TouchMove, TouchUp
– StylusDown, StylusMove, StylusUp
• Create ManipulationInertiaProcessor
– Implement events handler
• ManipulationCompleted
• ManipulationStatred
• ManipulationDelta
• BeforeInertia
Related Content and Resources • Development Tools
– Windows 7 SDK - http://www.microsoft.com/downloads/details.aspx?FamilyID=71deb800-c591-4f97-a900-bea146e4fae1&displaylang=en
– Visual Studio 2010 RC - http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx – Microsoft MultiPoint Mouse SDK - http://www.microsoft.com/multipoint/mouse-sdk/
• Windows 7 Multi-Touch .Net Interop Sample Library fro WinForm and WPF 3.5 SP1 http://code.msdn.microsoft.com/WindowsTouch/Release/ProjectReleases.aspx?ReleaseId=2127
• WPF 4 Resources: – http://connect.microsoft.com/wpf – http://blogs.msdn.com/ansont/
• Sessions in PDC 2009 – Windows Touch Deep Dive (Session CL17)
http://blogs.msdn.com/ansont/archive/2009/12/03/multi-touch-in-wpf-4-part-1.aspx
– Multitouch on Microsoft Surface and Windows 7 for .NET Developers (Session CL27)
• Microsoft Surface Manipulations and Inertia Sample for Microsoft Silverlight http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=4b281bde-9b01-4890-b3d4-b3b45ca2c2e4
Contact us: – Forums: http://social.msdn.microsoft.com/Forums/en-US/tabletandtouch/threads/ – Email: [email protected]
Questions ?
Messages & GetMessageExtraInfo()
• GetMessageExtraInfo() returns the extra info associated with a message
• Mouse up and down messages are tagged with a special signature indicating they came from touch or pen:
– Mask extra info against 0xFFFFFF80
– 0xFF515780 for touch, 0xFF515700 for pen
Enable Multi-Touch in WPF 3.5 SP1 by Real Time Stylus
• P/Invoke SetProp Win32 API [DllImport("user32")] public static extern bool SetProp(IntPtr hWnd, string
lpString, IntPtr hData);
• Set the window property to enable Multi-Touch input on inking context. WindowInteropHelper windowInteropHelper = new
WindowInteropHelper((System.Windows.Window) this); SetProp(windowInteropHelper.Handle,
"MicrosoftTabletPenServiceProperty", new IntPtr(0x01000000));
• StylusDown/StylusUp/StylusMove events to handle the touch related events accordingly
Receive WM_TOUCH/WM_GESTURE in Windows Form 3.5 SP1
• P/Invoke Win32 Multi-Touch APIs
• RegisterTouchWindow for WM_TOUCH
• Override WndProc protected override void WndProc(ref Message m)
• Handle WM_TOUCH (or WM_GESTURE which is exclusive with WM_TOUCH)
Row Touch Events in WPF4
Enhancing Manipulation With Inertia
WPF 4.0 • Subscribe to Row Touch events
– TouchDown – TouchMove – TouchUp – TouchEnter – TouchLeave
• Subscribe to Manipulation events – ManipulationStarting – ManipulationStarted – ManipulationDelta – ManipulationCompleted – ManipulationInertiaStarting – ManipulationBoundaryFeedback
• PDC 2009 - http://my/sites/ansont/Shared%20Documents/PDC09/MT%20ChalkTalk%20Slides%20and%20Demo.zip
GetGestureConfig & SetGestureConfig BOOL WINAPI SetGestureConfig(
__in HWND hwnd,
__in DWORD dwReserved,
__in UINT cIDs,
__in PGESTURECONFIG pGestureConfig,
__in UINT cbSize );
BOOL WINAPI GetGestureConfig(
__in HWND hwnd,
__in DWORD dwReserved,
__in DWORD dwFlags,
__in PUINT pcIDs,
__inout PGESTURECONFIG pGestureConfig,
__in UINT cbSize );
typedef struct _GESTURECONFIG { DWORD dwID; DWORD dwWant; DWORD dwBlock; } GESTURECONFIG, *PGESTURECONFIG;
GetGestureConfig & SetGestureConfig Sample Codes
// set up our want / block settings
DWORD dwPanWant = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
DWORD dwPanBlock = GC_PAN_WITH_GUTTER | GC_PAN_WITH_INERTIA;
// set the settings in the gesture configuration
GESTURECONFIG gc[] = {{ GID_ZOOM, GC_ZOOM, 0 },
{ GID_ROTATE, GC_ROTATE, 0},
{ GID_PAN, dwPanWant , dwPanBlock} };
UINT uiGcs = 3;
BOOL bResult = SetGestureConfig(hWnd, 0, uiGcs, gc, sizeof(GESTURECONFIG));
if (!bResult){
DWORD err = GetLastError();
}
GESTURECONFIG gc[3];
UINT uiGcs = 3;
ZeroMemory(&gc, sizeof(gc));
gc[0].dwID = GID_ZOOM;
gc[1].dwID = GID_ROTATE;
gc[2].dwID = GID_PAN;
BOOL bResult = GetGestureConfig(hWnd, 0, 0, &uiGcs, gc, sizeof(GESTURECONFIG));
if (!bResult){
DWORD err = GetLastError();
}
GetGestureInfo BOOL WINAPI GetGestureInfo( __in HGESTUREINFO hGestureInfo,
__out PGESTUREINFO pGestureInfo );
typedef struct _GESTUREINFO {
UINT cbSize;
DWORD dwFlags; // The state of gesture command
DWORD dwID; // The identifier of the gesture command
HWND hwndTarget;
POINTS ptsLocation;
DWORD dwInstanceID;
DWORD dwSequenceID;
ULONGLONG ullArguments;
UINT cbExtraArgs;
}GESTUREINFO, *PGESTUREINFO;
The Identifier of Gesture Command
Name Value Description
GID_BEGIN 1 A gesture is starting.
GID_END 2 A gesture is ending.
GID_ZOOM 3 The zoom gesture.
GID_PAN 4 The pan gesture.
GID_ROTATE 5 The rotation gesture.
GID_TWOFINGERTAP 6 The two-finger tap gesture.
GID_PRESSANDTAP 7 The press and tap gesture.
ptsLocation And ullArguments Gesture ID ullArguments ptsLocation
GID_ZOOM Indicates the distance between the two points.
Indicates the center of the zoom.
GID_PAN Indicates the distance between the two points.
Indicates the current position of the pan.
GID_ROTATE
Indicates the angle of rotation if If the GF_BEGIN flag is set. Otherwise, this is the angle change since the rotation has started. This is signed to indicate the direction of the rotation. Use the GID_ROTATE_ANGLE_FROM_ARGUMENT and GID_ROTATE_ANGLE_TO_ARGUMENT macros to get and set the angle value.
This indicates the center of the rotation which is the stationary point that the target object is rotated around.
GID_TWOFINGERTAP Indicates the distance between the two fingers.
Indicates the center of the two fingers.
GID_PRESS_AND_TAP Indicates the delta between the first finger and the second finger.
Indicates the position that the first finger comes down on.
GetTouchInputInfo BOOL WINAPI GetTouchInputInfo( __in HTOUCHINPUT hTouchInput, __in UINT cInputs, __out PTOUCHINPUT pInputs, __in int cbSize ); typedef struct _TOUCHINPUT { LONG x; LONG y; HANDLE hSource; DWORD dwID; DWORD dwFlags; DWORD dwMask; DWORD dwTime; ULONG_PTR dwExtraInfo; DWORD cxContact; DWORD cyContact; } TOUCHINPUT, *PTOUCHINPUT;
dwFlags of TouchInput Flag Value Description
TOUCHEVENTF_MOVE 0x0001 Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN.
TOUCHEVENTF_DOWN 0x0002 The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP.
TOUCHEVENTF_UP 0x0004 A touch point was removed.
TOUCHEVENTF_INRANGE 0x0008 A touch point is in range. This flag is used to enable touch hover support on compatible hardware.Applications that do not want support for hover can ignore this flag.
TOUCHEVENTF_PRIMARY 0x0010 Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information on primary touch points.
TOUCHEVENTF_NOCOALESCE 0x0020 When received using GetTouchInputInfo, this input was not coalesced.
TOUCHEVENTF_PALM 0x0080 The touch event came from the user's palm.