2009/05/20

Programming with Windows 7 Multitouch & Gesture 續

軟體與硬體需求

當然要有硬體與作業系統及 SDK:
A multi-touch monitor
A PC or NB installed Windows 7
Installed Windows 7 SDK
Visual Studio(我用的是 Visual Studio 2008)

環境設定

設定Win7 SDK的路徑, 包含include與library都要設定:
Header :Declared in Winuser.h; include Windows.h.
Library:Include User32.lib

接下來請參考前一篇的資料結構,因為微軟的開發模式都差不多,在寫 Multitouch 與寫 Mouse 的方式很像,就是收 Message, 定義自己得 event handler, 底下就列出相關的 Message:


WM_GESTURE Message

Passes information about a gesture.

Parameters

wParam


Provides information identifying the gesture command and gesture-specific argument values. This information is retrieved by calling GetGestureInfo.

lParam

Provides information identifying the gesture command and gesture-specific argument values. This information is retrieved by calling GetGestureInfo.

Return Value

If an application processes this message, it should return 0.

If the application does not process the message, it must call DefWindowProc. Not doing so will cause the application to leak memory because the touch input handle will not be closed and associated process memory will not be freed.

WM_GESTURENOTIFY Message

Indicates that a gesture message is about to be received.

Parameters

wParam


Unused.

lParam

A pointer to a GESTURENOTIFYSTRUCT.

Return Value

If an application processes this message, it should return 0.

Remarks

When the WM_GESTURENOTIFY message is received, the application can use SetGestureConfig to specify the gestures to receive.

Examples

switch (message)
{
case WM_GESTURENOTIFY:
{
GESTURECONFIG gc = {0,GC_ALLGESTURES,0};
BOOL bResult = SetGestureConfig(hWnd,0,1,&gc,sizeof(GESTURECONFIG));

if(!bResult)
{
// an error
}
}

break

GESTUREINFO Structure

Stores information about a gesture.
Syntax

typedef struct _GESTUREINFO {
UINT cbSize;
DWORD dwFlags;
DWORD dwID;
HWND hwndTarget;
POINTS ptsLocation;
DWORD dwInstanceID;
DWORD dwSequenceID;
ULONGLONG ullArguments;
UINT cbExtraArgs;

} GESTUREINFO, *PGESTUREINFO;

Members

cbSize

The size of the structure, in bytes. The caller must set this to sizeof(GESTUREINFO).

dwFlags

The state of the gesture. For additional information, see Remarks.

dwID

The identifier of the gesture command.

hwndTarget

A handle to the window that is targeted by this gesture.

ptsLocation

A POINTS structure containing the coordinates associated with the gesture. These coordinates are always relative to the origin of the screen.

dwInstanceID

An internally used identifier for the structure.

dwSequenceID

An internally used identifier for the sequence.

ullArguments

An unsigned long long that contains the arguments for gestures that fit into 8 bytes.

cbExtraArgs

The size, in bytes, of extra arguments that accompany this gesture.

Remarks

The GESTUREINFO structure is retrieved by passing the handle to the gesture information structure to the GetGestureInfo function.

The following flags indicate the various states of the gestures and are stored in dwFlags.
Name Value Description
GF_BEGIN 0x00000001 Indicates a gesture is starting
GF_INERTIA 0x00000002 Indicates a gesture has triggered inertia
GF_END 0x00000004 Indicates a gesture has finished

Note Most applications should ignore the GID_BEGIN and GID_END messages and pass them to DefWindowProc. These messages are used by the default gesture handler and application behaviour is undefined when the GID_BEGIN and GID_END messages are consumed by a third party application.

The following table indicates the various identifiers for gestures.


Name Value Description
GID_BEGIN 1 Indicates a gesture is starting.
GID_END 2 Indicates a gesture is ending.
GID_ZOOM 3 Indicates the zoom gesture.
GID_PAN 4 Indicates the pan gesture.
GID_ROTATE 5 Indicates the rotation gesture.
GID_TWOFINGERTAP 6 Indicates the two-finger tap gesture.
GID_ROLLOVER 7 Indicates the rollover gesture.
Examples

GESTUREINFO gestureInfo = {0};

gestureInfo.cbSize = sizeof(gestureInfo);

BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gestureInfo);


dwCommand dwArguments ptsLocation
Pan Distance between contacts Current center of gesture
Zoom Distance between contacts Current center of gesture
Rotate Absolute angle on rotate start, delta on updates Current center of gesture
Two-finger tap NA Current center of gesture

GESTURENOTIFYSTRUCT Structure

When transmitted with WM_GESTURENOTIFY messages, passes information about a gesture.

Syntax

typedef struct tagGESTURENOTIFYSTRUCT {
UINT cbSize;
DWORD dwFlags;
HWND hwndTarget;
POINTS ptsLocation;
DWORD dwInstanceID;

} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;

Members

cbSize

The size of the structure.

dwFlags

Reserved for future use.

hwndTarget

The target window for the gesture notification.

ptsLocation

The location of the gesture.

dwInstanceID

A specific gesture instance with gesture messages starting with GID_START and ending with GID_END.

GESTURECONFIG Structure

Gets and sets the configuration for enabling gesture messages and the type of this configuration.

Syntax

typedef struct _GESTURECONFIG {
DWORD dwID;
DWORD dwWant;
DWORD dwBlock;

} GESTURECONFIG, *PGESTURECONFIG;

Members

dwID

The identifier for the type of configuration that will have messages enabled or disabled. For more information, see Remarks.

dwWant

The messages to enable.

dwBlock

The messages to disable.

Remarks

When you pass this structure, the dwID member contains information for a set of gestures. This determines what the other flags will mean. If you set flags for pan messages, they will be different from those flags that are set for rotation messages.

The following table indicates the various identifiers for gestures that are supported by the dwID member of the GESTURECONFIG structure. Note that setting dwID to 0 indicates that global gesture configuration flags are set.

GetGestureInfo Function

Retrieves a gesture information structure given a handle to the gesture information.

Syntax

BOOL WINAPI GetGestureInfo(

__in HGESTUREINFO hGestureInfo,

__out PGESTUREINFO pGestureInfo

);

Parameters

hGestureInfo [in]

The gesture information handle.

pGestureInfo [out]

A pointer to the gesture information structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Examples

GESTUREINFO gestureInfo = {0};

gestureInfo.cbSize = sizeof(gestureInfo);

BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gestureInfo);

SetGestureConfig Function

Configures the messages that are sent from a window for multitouch gestures.

Syntax

BOOL WINAPI SetGestureConfig(
__in HWND hwnd,
__in DWORD dwReserved,
__in UINT cIDs,
__in PGESTURECONFIG pGestureConfig,
__in UINT cbSize
);

Parameters

hwnd [in]

A handle to the window to set the gesture configuration on.

dwReserved [in]

This value is reserved and must be set to 0.

cIDs [in]

A count of the gesture configuration structures that are being passed.

pGestureConfig [in]

An array of gesture configuration structures that specify the gesture configuration.

cbSize [in]

The size of the array of gesture configuration structures.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Programming with Windows 7 Multitouch & Gesture

請參考Microsoft MSDN Windows Touch for Developer一文,以及微軟「阿倫」的部落格的說明。

我這邊先直接貼一些資料結構的定義:


#if(WINVER >= 0x0601)

/*
* Gesture defines and functions
*/

/*
* Gesture information handle
*/
DECLARE_HANDLE(HGESTUREINFO);


/*
* Gesture flags - GESTUREINFO.dwFlags
*/
#define GF_BEGIN 0x00000001
#define GF_INERTIA 0x00000002
#define GF_END 0x00000004

/*
* Gesture IDs
*/
#define GID_BEGIN 1
#define GID_END 2
#define GID_ZOOM 3
#define GID_PAN 4
#define GID_ROTATE 5
#define GID_TWOFINGERTAP 6
#define GID_PRESSANDTAP 7
#define GID_ROLLOVER GID_PRESSANDTAP

/*
* Gesture information structure
* - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the
* GetGestureInfo function to retrieve this information.
* - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE
* message lParam into the GetGestureExtraArgs function to retrieve extended
* argument information.
*/
typedef struct tagGESTUREINFO {
UINT cbSize; // size, in bytes, of this structure (including variable length Args field)
DWORD dwFlags; // see GF_* flags
DWORD dwID; // gesture ID, see GID_* defines
HWND hwndTarget; // handle to window targeted by this gesture
POINTS ptsLocation; // current location of this gesture
DWORD dwInstanceID; // internally used
DWORD dwSequenceID; // internally used
ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
} GESTUREINFO, *PGESTUREINFO;
typedef GESTUREINFO const * PCGESTUREINFO;


/*
* Gesture notification structure
* - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
* - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
* in progress and a gesture will be generated if one is recognized under the
* current gesture settings.
*/
typedef struct tagGESTURENOTIFYSTRUCT {
UINT cbSize; // size, in bytes, of this structure
DWORD dwFlags; // unused
HWND hwndTarget; // handle to window targeted by the gesture
POINTS ptsLocation; // starting location
DWORD dwInstanceID; // internally used
} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;

/*
* Gesture argument helpers
* - Angle should be a double in the range of -2pi to +2pi
* - Argument should be an unsigned 16-bit value
*/
#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0))
#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265)

/*
* Gesture information retrieval
* - HGESTUREINFO is received by a window in the lParam of a WM_GESTURE message.
*/
WINUSERAPI
BOOL
WINAPI
GetGestureInfo(
__in HGESTUREINFO hGestureInfo,
__out PGESTUREINFO pGestureInfo);

/*
* Gesture extra arguments retrieval
* - HGESTUREINFO is received by a window in the lParam of a WM_GESTURE message.
* - Size, in bytes, of the extra argument data is available in the cbExtraArgs
* field of the GESTUREINFO structure retrieved using the GetGestureInfo function.
*/
WINUSERAPI
BOOL
WINAPI
GetGestureExtraArgs(
__in HGESTUREINFO hGestureInfo,
__in UINT cbExtraArgs,
__out_bcount(cbExtraArgs) PBYTE pExtraArgs);

/*
* Gesture information handle management
* - If an application processes the WM_GESTURE message, then once it is done
* with the associated HGESTUREINFO, the application is responsible for
* closing the handle using this function. Failure to do so may result in
* process memory leaks.
* - If the message is instead passed to DefWindowProc, or is forwarded using
* one of the PostMessage or SendMessage class of API functions, the handle
* is transfered with the message and need not be closed by the application.
*/
WINUSERAPI
BOOL
WINAPI
CloseGestureInfoHandle(
__in HGESTUREINFO hGestureInfo);


/*
* Gesture configuration structure
* - Used in SetGestureConfig and GetGestureConfig
* - Note that any setting not included in either GESTURECONFIG.dwWant or
* GESTURECONFIG.dwBlock will use the parent window's preferences or
* system defaults.
*/
typedef struct tagGESTURECONFIG {
DWORD dwID; // gesture ID
DWORD dwWant; // settings related to gesture ID that are to be turned on
DWORD dwBlock; // settings related to gesture ID that are to be turned off
} GESTURECONFIG, *PGESTURECONFIG;

/*
* Gesture configuration flags - GESTURECONFIG.dwWant or GESTURECONFIG.dwBlock
*/

/*
* Common gesture configuration flags - set GESTURECONFIG.dwID to zero
*/
#define GC_ALLGESTURES 0x00000001

/*
* Zoom gesture configuration flags - set GESTURECONFIG.dwID to GID_ZOOM
*/
#define GC_ZOOM 0x00000001

/*
* Pan gesture configuration flags - set GESTURECONFIG.dwID to GID_PAN
*/
#define GC_PAN 0x00000001
#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
#define GC_PAN_WITH_GUTTER 0x00000008
#define GC_PAN_WITH_INERTIA 0x00000010

/*
* Rotate gesture configuration flags - set GESTURECONFIG.dwID to GID_ROTATE
*/
#define GC_ROTATE 0x00000001

/*
* Two finger tap gesture configuration flags - set GESTURECONFIG.dwID to GID_TWOFINGERTAP
*/
#define GC_TWOFINGERTAP 0x00000001

/*
* PressAndTap gesture configuration flags - set GESTURECONFIG.dwID to GID_PRESSANDTAP
*/
#define GC_PRESSANDTAP 0x00000001
#define GC_ROLLOVER GC_PRESSANDTAP

#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included
// in a single call to SetGestureConfig / GetGestureConfig

WINUSERAPI
BOOL
WINAPI
SetGestureConfig(
__in HWND hwnd, // window for which configuration is specified
__in DWORD dwReserved, // reserved, must be 0
__in UINT cIDs, // count of GESTURECONFIG structures
__in_ecount(cIDs) PGESTURECONFIG pGestureConfig, // array of GESTURECONFIG structures, dwIDs will be processed in the
// order specified and repeated occurances will overwrite previous ones
__in UINT cbSize); // sizeof(GESTURECONFIG)


#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration
// for the specified window and it's parent window chain

WINUSERAPI
BOOL
WINAPI
GetGestureConfig(
__in HWND hwnd, // window for which configuration is required
__in DWORD dwReserved, // reserved, must be 0
__in DWORD dwFlags, // see GCF_* flags
__in PUINT pcIDs, // *pcIDs contains the size, in number of GESTURECONFIG structures,
// of the buffer pointed to by pGestureConfig
__inout_ecount(*pcIDs) PGESTURECONFIG pGestureConfig,
// pointer to buffer to receive the returned array of GESTURECONFIG structures
__in UINT cbSize); // sizeof(GESTURECONFIG)