Integrating Gestures in Windows Embedded Compact 7 Douglas Boling Boling Consulting Inc.
About Douglas Boling Independent consultant specializing in Windows Mobile and Windows Embedded Compact (Windows CE) On-Site Instruction Consulting and Development Author Programming Embedded Windows CE Fourth Edition
Agenda Introducing Gestures Basic Gesture Input AutoGesture support Physics Engine
Historic Touch Model Touch panel produced mouse message WM_LBUTTONDOWN WM_LBUTTONUP WM_MOUSEMOVE Only while touching panel Gestures used for right click Tap and Shift Key Tap and Hold These still work
Gestures Gesture support enhances basic mouse interpretation Nothing more than could be done before but done for you Provides consistent look and feel across all applications All Windows controls enhanced to use gestures Only need to use for custom windows where mouse manipulation was used before
Basic Gesture API Gestures are interpreted touch input Either single or multiple touch input Allows flick, pan, select gestures by default Custom gestures can be registered Windows Embedded Compact Gesture API is Win32-based Follows Windows 7 format
Gesture Actions Pan User presses moves finger and lifts Scroll (flick) User presses, moves, then lifts finger while moving Select User presses and lifts Rotate Two finger press and rotate Zoom Two finger pinch or spread
Enabling Gesture Support To enable gesture support call: EnableGestures (HWND hwnd, ULONGLONG ullflags, UINT wscope); Parameters: hwnd Handle of window that supports gestures ullflags Flags indicating which gestures you would like» Pan» Hold» Select» DoubleSelect» <Custom gestures>» All uscope Flags indicating gestures for specific window or entire application EnableGestures typically called in WM_CREATE of main window
Using EnableGestures Calling GetGesutureInfo returns a GESTUREINFO structure //------------------------------------------------- // DoCreateMain - Process WM_CREATE message // LRESULT DoCreateMain (HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM lparam) { EnableGestures (hwnd, TGF_GID_ALL, TGF_SCOPE_PROCESS); } return 0;
The WM_GESTURE Message Sent to a window when a gesture is recognized by the system wparam Contains gesture command (Pan, Scroll, Select ) lparam Contains handle to gesture information In CE6R3, if WM_GESTURE not passed to DefWindowProc, you must call CloseGestureInfoHandle while processing the message Deprecated in Windows Embedded Compact 7 DefWindowProc handles WM_GESTURE by passing to parent window DON T forward WM_GESTURE to one of your child windows!
GetGestureInfo Calling GetGesutureInfo returns a GESTUREINFO structure typedef struct taggestureinfo { UINT cbsize; DWORD dwflags; DWORD dwid; HWND hwndtarget; POINTS ptslocation; DWORD dwinstanceid; DWORD dwsequenceid; ULONGLONG ullarguments; UINT cbextraarguments; } GESTUREINFO, *PGESTUREINFO; // Size of structure // GF_BEGIN, GF_INERTIA, // GF_END // Gesture ID // Target Window handle // Location of gesture // Reserved // Timestamp of Gesture // Args. See next slide // Possible extra data
GESTUREINFO dwflags dwflags GF_BEGIN Beginning of gesture GF_END End of gesture GF_INERTIA Indicates Flick has happened at end of Pan Flags can be combined or zero Multiple End flags can occur One for each gesture recognized
GESTUREINFO ularguments ullarguments Depends on message Notification: Interim Pan notifications HIWORD () X delta from previous message LOWORD () Y delta from previous message Notification: GF_END + Pan or Scroll GID_SCROLL_ANGLE() GID_SCROLL_DIRECTION() GID_SCROLL_VELOCITY() Angle of gesture in radians Direction of gesture (Up/Down/Left/Right) Speed in Pixels per second
WM_GESTURE messages DEMO
AutoGesture Simple way to enable window scrolling by pan/flick gestures Enable by adding Horizontal and/or Vertical scroll bars to your window No need to handle WM_GESTURE Simply respond to WM_VSCROLL and WM_HSCROLL messages OS needs to be built with AutGesture component
AutoGesture in Embedded Compact 7 AutoGesture was quite configurable in CE 6 R3 But the defines were in pwinuser.h In Compact 7, only flick to scroll is supported To support other gestures, you will need to subclass the control This allows the control to act the way you want AutoGesture API in CE 6 R3 removed! If you used it, you ll need to remove those calls
The Physics Engine Makes movement look natural Things bounce, spring back, and slow down naturally How is this done? Physics! The physics engine computes a series of point/time combinations to allow the application to animate movement in a natural looking way
Using the Physics Engine The physics engine is controlled by 4 functions CreatePhysicsEngine Create and initialize the engine QueryPhysicsEngine Query position and motion parameters given a time SetPhysicsEngineUserTime Set time for query DestroyPhysicsEngine Destroy engine and free resources
Initializing the Physics Engine typedef struct tagphysicsengineinit { DWORD cbsize; // Size of the structure DWORD dwenginetype; // Reserved, set to zero DWORD dwflags; // Specifies system or User time base LONG linitialvelocity; // Initial velocity in Pixels/sec DWORD dwinitialangle; // Angle in radians BYTE bxaxismovementmode; // Horz movement action (Decelerate only opt) BYTE bxaxisboundarymode; // Horz boundary action. Bounce/rubber band/none BYTE byaxismovementmode; // Vert movement action (Decelerate only opt) BYTE byaxisboundarymode; // Vert boundary action. Bounce/rubber band/none RECT rcboundary; // Entire movement rectangle SIZE sizeview; // Rectangle of visible region POINT ptinitialposition; // Initial position in region SIZE sizeitem; // Size of item. Used to snap to item boundary } PHYSICSENGINEINIT; HRESULT CreatePhysicsEngine (PHYSICSENGINEINIT* pengineinit, HPHYSICSENGINE* phresult);
Using the Physics Engine Initialize Physics engine with values returned by Flick (Scroll) gesture Units match so easily done Create timer to send messages back to window to animate SetTimer() When WM_TIMER message received, query physics information Use QueryPhysicsEngine() Redraw with returned Physics position data When physics status indicates complete, kill timer message
Using the Physics Engine if (gi.dwflags & (GF_INERTIA GF_END)) { PHYSICSENGINEINIT pei; } memset (&pei, 0, sizeof (pei)); pei.cbsize = sizeof (pei); pei.dwflags = 0; pei.linitialvelocity = GID_SCROLL_VELOCITY (gi.ullarguments); pei.dwinitialangle = GID_SCROLL_ANGLE (gi.ullarguments); pei.bxaxismovementmode = PHYSICSENGINE_MOVEMENT_MODE_DECELERATE; pei.bxaxisboundarymode = PHYSICSENGINE_BOUNDARY_MODE_RUBBERBAND; pei.byaxismovementmode = PHYSICSENGINE_MOVEMENT_MODE_DECELERATE; pei.byaxisboundarymode = PHYSICSENGINE_BOUNDARY_MODE_RUBBERBAND; pei.rcboundary = g_rcwork; pei.sizeview.cx = rectimg.right; pei.sizeview.cy = rectimg.bottom; pei.ptinitialposition.x = gi.ptslocation.x; pei.ptinitialposition.y = gi.ptslocation.y; pei.sizeitem.cx = 1; pei.sizeitem.cy = 1; hr = CreatePhysicsEngine (&pei, &g_hpeanimate); SetTimer (hwnd, ID_ANIMATE, 100, NULL);
WM_TIMER with Physics Engine case WM_TIMER: if (wparam == ID_ANIMATE) { // Query physics engine PHYSICSENGINESTATE state; memset (&state, 0, sizeof (state)); state.cbsize = sizeof (state); QueryPhysicsEngine (g_hpeanimate, &state); // Update image MoveImg (hwnd, state.ptposition); // If animation complete, clean up if (state.fcomplete) { DestroyPhysicsEngine (g_hpeanimate); KillTimer (hwnd, 1); } } break;
Managed Support No direct support through managed class library AutoGesture works by default Physics is a simply P/Invoke
Summary Gesture support fairly straightforward Model consistent with desktop API Autogesture gives simple gesture support for most controls Flick to scroll only Customization done through subclassing the control Physics engine pretty simple to use Cool effects
Questions Doug Boling Boling Consulting Inc. www.bolingconsulting.com dboling @ bolingconsulting.com
2011 Microsoft Corporation. All All rights reserved. This This presentation is for informational is informational purposes purposes only. Microsoft only. makes Microsoft no warranties, makes no express warranties, or implied, express in this or summary. implied, in this summary.