在Windows Mobile中使用手势 - [Using Gestures in Windows Mobile 6.5]
原文为:MSDN的 Using Gestures in Windows Mobile 6.5
Using Gestures in Windows Mobile 6.5
2.2.1 TKGetAnimateMessageInfo
2.2.2 TKGetGestureExtraArguments
2.2.3 TKGetGestureInfo
2.2.4 TKGetGestureMetrics
2.2.5 TKGetWindowAutoGesture
2.2.6 TKSetWindowAutoGesture
2.3.1 GID_ROTATE_ANGLE_FROM_ARGUMENT
2.3.2 GID_ROTATE_ANGLE_TO_ARGUMENT
2.3.3 GID_SCROLL_ANGLE
2.3.4 GID_SCROLL_DIRECTION
2.3.5 GID_SCROLL_VELOCITY
2.4.1 WM_GESTURE
2.5.1 ANIMATEMESSAGEINFO
2.5.2 GESTUREINFO
2.5.3 GESTUREMETRICS
2.5.4 WAGINFO
4. Physics Engine Reference (DTK)
4.1 Physics Engine Functions (DTK)
4.1.1 TKCreatePhysicsEngine
4.1.2 TKDestroyPhysicsEngine
4.1.3 TKQueryPhysicsEngine
4.1.4 TKSetPhysicsEngineUserTime
4.3.1 PHYSICSENGINEINIT
4.3.2 PHYSICSENGINESTATE
Using Gestures in Windows Mobile 6.5
它包含针对触摸事件、手势和手势动画的表述。
触摸APIs分成两部分:手势APIs,用于管理触摸输入;手势物理引擎(the Gesture Physics Engine)APIs,用于控制显示区字段如何对用户触摸做出反应。
触摸函数、消息和结构体和鼠标共享,因为应用程序把光笔事件作为鼠标左键点击处理。更多触摸参考信息,参见Mouse Reference 。
本文的讨论包括:
Touch Gestures:介绍窗口手势并且讨论怎样在你的应用程序中实现手势接口。
Gesture Reference (DTK):该API允许程序监控和响应触摸输入。
Physics Engine Overview:介绍物理引擎以及在实现手势接口时如何使用物理引擎。
Physics Engine Reference (DTK):该API控制屏幕如何响应触摸输入以及如何使你的应用程序象shell(操作系统外壳)一样响应触摸。
该段介绍触摸手势,你可以用手指或光笔队按照某种手势对屏幕上的控件或对象做短距离有向运动。大多数手势是单独的点击,它相当于一次手指按下(WM_LBUTTONDOWN)和一次手指抬起(WM_LBUTTONUP)事件对。双击是个例外,它相当于连续两次手指按下和手指抬起事件对。手势的识别根据:手指按下和抬起事件加上方向、位置和由手势识别器计算出的速度。Windows Mobile支持5种手势:
手势 |
描述 |
Tap |
代表一次鼠标左键点击。 当手机按下和抬起事件发生在一个已定义的时间段和距离内时,程序只接收一次GID_SELECT 手势消息。在WM_LBUTTONDOWN 事件后和GID_SELECT 消息前可能会有几次WM_MOUSEMOVE消息。 |
Double Tap |
代表2次鼠标左键点击。 当手指抬起事件发生在一个已定义的时间段和距离内时,程序接收一次GID_DOUBLESELECT 手势消息。 |
Hold |
用户按下并一直按住屏幕代表鼠标右键点击。 当手指按下并一直按住超过了一个预定义的时间段,而且这段时间内按下的点都在一个指定的距离范围内时,程序会只接收一次GID_HOLD消息。 一旦手指抬起或在按住时间临界值后,程序会接收到一个GID_END 消息然后紧接着收到一个GID_HOLD 消息。 |
Flick |
用户移动手指划过屏幕来启动每个像素移动。 如果移动足够快,滚动在手指抬起后仍会继续。 当手指移动结束抬起后,程序会接收一次GID_SCROLL 手势消息。 Flick经常发生在Pan之后(即一个或多个GID_PAN 手势消息,紧接着是GID_SCROLL ,然后是GID_END 消息)。 |
Pan |
用户按下并按住屏幕,然后在任意方向拖动手指来代表鼠标移动事件。 位置发生改变时程序接收一个或多个GID_PAN 手势消息,当手指抬起时接收一个GID_END 消息。鼠标消息和手势消息交错出现。 |
更多关于GID_*手势的消息参见:GESTUREINFO。
手势识别引擎的系统构架由一个手势识别状态机和现有的触摸事件发送程序构成。触摸事件由触摸屏驱动(Touch Screen Drivers)发送到状态机。当手势被识别后,一个手势窗口消息将被发送到目标进程消息队列。
手势事件通常总是在手指抬起前发送以便接收者能够调用TKGetGestureInfo处理手势消息并通过鼠标抬起事件来取消任何动作。
Window Auto Gestures:
自动手势使窗口内的控件和程序能够自动地处理Flick和Pan手势。可以通过 TKSetWindowAutoGesture 和 TKGetWindowAutoGesture 函数来控制手势处理。自动手势使动画消息被发送到窗口过程来管理和Flicks和Pans相关的动画。可以调用TKGetAnimateMessageInfo函数来取到那些消息。
窗口自动手势能够使窗口中的内容自动响应Flick和Pan手势滚动。
本部分包括:
Gesture Functions (DTK):提供触摸手势相关函数的概述。
Gesture Structures (DTK):提供触摸手势相关结构体的概述
Gesture Macros (DTK):提供触摸手势相关宏的概述
Gesture Constants (DTK):提供触摸手势相关常量的概述
Gesture Messages (DTK):提供触摸手势相关消息的概述
下面的常量为在 GESTUREINFO 结构体中使用的命令。
名称 |
值 |
描述 |
GID_BEGIN |
1 |
包含标记每个手势开始点的坐标。当触摸屏幕时发送。 |
GID_END |
2 |
包含标记每个手势结束点的坐标。当手指或光笔从屏幕抬起后发送。 当接收该命令后,GESTUREINFO 的 ullArguments 字段总是被设置为0。 |
GID_PAN |
4 |
an在当用户在窗口上按下而且在任意方向移动(该过程手指保持和屏幕一直接触)时发生。 识别引擎发送GID_PAN消息,该消息包含手势的开始点和当前点。在手指或光笔从窗口屏幕抬起前,会为每次窗口移动消息发送一次GID_PAN消息。GID_END 用来标记Pan移动的结束。 程序根据连续两次Pan手势间的差异计算移动增量。 如果设置GF_INERTIA标志,GESTUREINFO 的 ullArguments 值和GID_SCROLL 时一样。 |
GID_SCROLL |
8 |
用户按下窗口(或者也可能在窗口上Pan),然后手指或光标在任意方向迅速移动,当移动结束抬起手指或光笔前发生Scroll。识别引擎在Flick手势后发送GID_SCROLL消息。GID_SCROLL会被发送到接收当前触摸过程第一个手势消息的窗口,可能是一个Pan消息或一个Hold消息。GESTUREINFO 的ullArguments 字段包含关于角度、方向和Flick速度的信息。 主要的方向常量值如下: ARG_SCROLL_NONE ARG_SCROLL_RIGHT ARG_SCROLL_UP ARG_SCROLL_LEFT ARG_SCROLL_DOWN 当设备旋转时,手势自动调整匹配旋转。 Flick的角度值以从0至65535范围值计量。 可以使用下面的宏从GID_SCROLL手势消息的ullArguments 字段来提取出角度、方向和速度。 GID_SCROLL_ANGLE GID_SCROLL_DIRECTION GID_SCROLL_VELOCITY 可以使用下面的宏在角度和弧度间相互转换。 GID_ROTATE_ANGLE_TO_ARGUMENT GID_ROTATE_ANGLE_FROM_ARGUMENT |
GID_HOLD |
9 |
用户按下窗口并保持手指或光笔按住超过指定的超时时间,此时发生Hold。 识别引擎发送一个GID_HOLD消息,然后当手指或光笔抬起时发送一个GID_END 消息。 Hold 手势后可能会跟着Pan移动(移动过程会生成许多GID_PAN消息),但是,在生成GID_PAN消息后绝不会再生成GID_HOLD消息 |
GID_SELECT |
10 |
当用户用手指或光笔敲击屏幕,敲击过程时间小于系统指定的SELECT超时时间,此时发生Select。GESTUREINFO 的ullArguments 字段不会在该命令中使用。 |
GID_DOUBLESELECT |
11 |
当用户用手指或光笔敲击两次屏幕,两次敲击过程时间小于系统指定的DOUBLESELECT超时时间,此时发生Double Select。DOUBLESELECT超时时间是指连续两次鼠标抬起事件发生的间隔时间。 GESTUREINFO 的ullArguments 字段不会在该命令中使用。 |
下表显示支持手势的函数及其用途。
函数 |
描述 |
TKGetAnimateMessageInfo |
该函数取回由窗口自动手势发送的所有动画消息的移动信息。 |
TKGetGestureExtraArguments |
该函数用来获得手势消息配备的额外信息。 |
TKGetGestureInfo |
该函数使用传递到WM_GESTURE消息的触摸手势的内容填充GESTUREINFO结构。 |
TKGetGestureMetrics |
用来给指定手势取回触摸手势识别的尺寸(比如,触摸手势引擎使用的距离和时间公差)。 |
TKGetWindowAutoGesture |
为指定窗口句柄取回当前自动手势配置设置。 |
TKSetWindowAutoGesture |
为指定窗口指定自动手势配置设置。 |
该函数取回由窗口自动手势发送的所有动画消息的移动信息。该特性使窗口中的内容响应Flick和Pan手势自动滚动。要自动处理手势滚动,目标窗口一定要包含WS_VSCROLL 或 WS_HSCROLL(或者两者都包含)类型并且设置正确的范围。
该函数在WindowAutoGesture.h头文件中。
程序调用TKSetWindowAutoGesture并指定WAGIF_OWNERANIMATE 标志后,当内容动起来时,消息被发送至窗口过程。程序应该为每个动画消息调用该函数来取回正确的值。
声明:
HWND hWnd,
WPARAM wParam,
LPARAM lParam,
LPANIMATEMESSAGEINFO pAnimateMessageInfo
);
参数:
hWnd:目标窗口句柄。
wParam、lParam:动画消息参数。
pAnimateMessageInfo:指向 ANIMATEMESSAGEINFO 结构指针,该结构由移动信息组成。
返回值:
成功返回TRUE;失败返回FALSE。调用GetLastError获取扩展错误信息。
备注:
必须调用TKSetWindowAutoGesture函数并且在目标窗口收到任何动画消息前为窗口设置WAGIF_OWNERANIMATE 标志。
该函数用来获得手势消息配备的额外信息,在Gesture.h头文件中。
声明:
HGESTUREINFO hGestureInfo,
UINT cbExtraArguments,
PBYTE pExtraArguments
);
参数:
hGestureInfo:[in]手势信息句柄,HGESTUREINFO,从 WM_GESTURE 窗口消息的lparam 参数获得。
cbExtraArguments: [in]客户端传递的缓冲大小,用来取回手势详细内容,从GESTUREINFO的cbExtraArguments 值获得。
pExtraArguments:[out]指向大小为cbExtraArguments 的BYTE数组的指针,用来接收而外信息。
返回值:
成功返回TRUE;失败返回FALSE。调用GetLastError取回更多信息。下表显示GetLastError可能获取的返回值。
值 |
描述 |
ERROR_NO_DATA |
没有数据返回。也可能是由于没有足够缓冲造成。 |
ERROR_INVALID_PARAMETER |
如果pExtraArguments为空或hGestureInfo 无效。 |
备注:
客户端程序检测GESTUREINFO 的cbExtraArguments 值来决定是否需要调用TKGetGestureExtraArguments。
程序通常先检查cbExtraArguments 值,如果值为非0,将填充BYTES数组。客户端程序需要按照文档描述那样为某个手势消息解析该内存缓冲。
该函数使用传递到WM_GESTURE消息的触摸手势的内容填充GESTUREINFO结构,该函数在Gesture.h头文件中。
声明:
HGESTUREINFO hGestureInfo,
PGESTUREINFO pGestureInfo
);
参数:
hGestureInfo:GESTUREINFO结构句柄。
pGestureInfo:指向GESTUREINFO结构的指针,该结构由传递到WM_GESTURE消息的触摸手势的内容填充。结构的cbSize值必须在调用函数前正确地初始化。
备注:
根据手势ID,程序直接翻译 WM_GESTURE 消息的参数,或者传递参数给GetGestureInfo,如下代码:
memset(&gi, 0, sizeof(gi));
gi.cbSize = sizeof(GESTUREINFO);
if (TKGetGestureInfo((HGESTUREINFO)lParam, &gi))
{
// Handle gesture indicated by wParam
}
else
{
// Error handling.
}
用来给指定手势取回触摸手势识别的尺寸(比如,触摸手势引擎使用的距离和时间公差)。该函数在Gesture.h头文件中。
声明:
LPGESTUREMETRICS lpGestureMetricsInfo
);
参数:
lpGestureMetricsInfo:[in/out]GESTUREMETRICS结构指针。该值不能为NULL。调用者必须设置dwID 值为下面的一个:
GID_PAN
GID_ SCROLL
GID_HOLD
GID_SELECT
GID_DOUBLESELECT
所有其他的字段会按照需要根据dwID的值重写。
调用该函数时cbSize字段需要被设置正确的值。
返回值:
成功返回TRUE;失败返回FALSE。调用GetLastError获取扩展错误信息。
成功返回TRUE;失败返回FALSE。
为指定窗口句柄取回当前自动手势配置设置。窗口自动手势能够使窗口中的内容自动响应Flick和Pan手势滚动。
要自动处理手势滚动,目标窗口一定要包含WS_VSCROLL 或 WS_HSCROLL(或者两者都包含)类型并且设置正确的范围。
该函数包含在WindowAutoGesture.h头文件中。
声明:
HWND hWnd,
LPWAGINFO lpAutoGestureInfo
);
参数:
hWnd:[in]目标窗口句柄。
lpAutoGestureInfo:[out] 指向WAGINFO结构的指针。
返回值:
成功返回TRUE;失败返回FALSE。调用GetLastError获取扩展错误信息。
备注:
在使用 TKSetWindowAutoGesture 或 TKGetWindowAutoGesture函数前必须要设置目标窗口的滚动类型。
为指定窗口指定自动手势配置设置。窗口自动手势能够使窗口中的内容自动响应Flick和Pan手势滚动。
要自动处理手势滚动,目标窗口一定要包含WS_VSCROLL 或 WS_HSCROLL(或者两者都包含)类型并且设置正确的范围。
该函数包含在WindowAutoGesture.h头文件中。
声明:
HWND hWnd,
LPWAGINFO lpAutoGestureInfo
);
参数:
hWnd:[in]目标窗口句柄。
lpAutoGestureInfo:[in]指向WAGINFO结构的指针。
返回值:
成功返回TRUE;失败返回FALSE。调用GetLastError获取扩展错误信息。
备注:
在使用 TKSetWindowAutoGesture 或 TKGetWindowAutoGesture函数前必须要设置目标窗口的滚动类型。
必须在lpAutoGestureInfo的dwflags成员中包含WAGIF_OWNERANIMATE 标志。
SDK提供的例子:
{
WAGINFO wagInfo = {sizeof(WAGINFO)};
wagInfo.dwFlags = WAGIF_OWNERANIMATE |
(g_fHScrollable ? WAGIF_HSCROLLABLE : 0) |
(g_fVScrollable ? WAGIF_VSCROLLABLE : 0) |
(g_fAllowPAN ? 0 : WAGIF_IGNOREPAN) |
(g_fAllowSCROLL ? 0 : WAGIF_IGNORESCROLL) |
(g_fLockAxis ? WAGIF_LOCKAXES : 0);
wagInfo.nOwnerAnimateMessage = (g_fUseWMSCroll ? 0 : WM_PRIVATEANIMATEMSG);
wagInfo.nItemHeight = g_nVertItemSize;
wagInfo.nItemWidth = g_nHorizItemSize;
wagInfo.bHorizontalExtent = (BYTE)g_nHorizExtent;
wagInfo.bVerticalExtent = (BYTE)g_nVertExtent;
if (!TKSetWindowAutoGesture(hWnd, &wagInfo))
{
MessageBox( hWnd,
TEXT("Failure from SetWindowAutoGesture()"),
TEXT("Error"),
MB_OK);
}
// Make sure the item sizes are at least 1 for now - i.e. calculated size is 1 pixel
g_nHorizItemSize = max(1,g_nHorizItemSize);
g_nVertItemSize = max(1,g_nVertItemSize);
}
下表显示支持手势的宏和用途。
名称 |
描述 |
GID_ROTATE_ANGLE_TO_ARGUMENT |
从原始角度转换为弧度。 |
GID_ROTATE_ANGLE_FROM_ARGUMENT |
从弧度转换为原始角度。 |
GID_SCROLL_ANGLE |
从ullArguments 字段提取Flick手势角度。 |
GID_SCROLL_DIRECTION |
从ullArguments 字段提取Flick手势方向。 |
GID_SCROLL_VELOCITY |
从ullArguments 字段提取Flick手势速度。 |
GID_ROTATE_ANGLE_FROM_ARGUMENT
使用下面的宏在原始角度和弧度之间转换。该宏在Gesture.h头文件中。
声明:
GID_ROTATE_ANGLE_TO_ARGUMENT(Arg)
Arg为要转换参数。
在头文件定义为:
* 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)) * 65536.0))
#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65536.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265)
备注:
To convert the raw angle to radians, divide the raw angle by 32768, then multiply that value by 360/32768. 32768 units represent one full circle.
(要转换原始角度到弧度,原始角度除以32768,然后再乘以(360/32768)。32768 代表一个整圆。)
原始角度和当前系统方向有关(设备是横向还是纵向并不可知)。当系统旋转,手势方向和角度自动调整匹配旋转。
这些宏分别从ullArguments 字段提取Flick手势的角度、方向和速度。该宏在Gesture.h头文件中。
声明:
GID_SCROLL_DIRECTION(Arg)
GID_SCROLL_VELOCITY(Arg)
Arg为要转换的原始角度。
在头文件定义为:
#define GID_SCROLL_ANGLE(x) ((LONG)(HIWORD(((ULONGLONG)(x)) >> 32) & 0xFFF0))
#define GID_SCROLL_DIRECTION(x) ((LONG)(HIWORD(((ULONGLONG)(x)) >> 32) & 0x000F))
#define GID_SCROLL_VELOCITY(x) ((LONG)((short)(LOWORD(((ULONGLONG)(x)) >> 32))))
备注:
原始角度和当前系统方向有关(设备是横向还是纵向并不可知)。当系统旋转,手势方向和角度自动调整匹配旋转。
下表显示支持手势的消息和用途。
名称 |
说明 |
WM_GESTURE |
WM_GESTURE消息被发送至某个窗口过程代表一个手势已经发送或正在发送中。 |
WM_GESTURE消息被发送至某个窗口过程代表一个手势已经发送或在Pan情况下,代表正在发送中。
WM_GESTURE消息可以从WndProc使用SendMessage(), SendMessageTimeout() 或 SendNotifyMessage() APIs同步发送。
窗口过程可以调用TKGetGestureInfo来检测手势的状态。
窗口通过WndProc 函数来接收消息。
语法:
WPARAM wParam
LPARAM lParam
参数:
wParam:包含手势命令ID。
lParam:包含手势命令的HGESTUREINFO 句柄。
返回值:
如果程序处理了手势,它返回一个非0值。如果程序没有处理手势,应该把它传递给DefWindowProc ,返回值为DefWindowProc 的返回值。
备注:
根据手势ID,你要决定程序是否自己处理该手势或着是否传递该手势到DefWindowProc。GID_BEGIN 和 GID_END应该总被传给DefWindowProc。如果程序处理手势,那么它就不能把消息传递给默认窗口过程。
下面的代码显示如何根据手势ID来处理该手势。
memset(&gi, 0, sizeof(gi));
gi.cbSize = sizeof(GESTUREINFO);
if (GetGestureInfo((HGESTUREINFO)lParam, &gi))
{
// Handle gesture indicated by wParam or gi.dwID
}
else
{
// Error handling
}
HGESTUREINFO 句柄在WndProc调用前被创建,窗口过程返回时销毁。记住,程序不能为以后使用该句柄而保存HGESTUREINFO句柄。WM_GESTURE的lParam值在窗口过程外毫无意义,因为HGESTUREINFO 句柄直到DispatchMessage发送消息到窗口过程时才有效。因此,下面的代码不会正常工作:
{
if (msg.msg == WM_GESTURE)
{
GetGestureInfo(msg.lParam,...)
}
}
一个传送到DefWindowProc的未处理的WM_GESTURE消息将被传送至父窗口。当在窗口键传送手势消息时,避免从父窗口发送消息至子窗口以避免在发生错误时关闭循环。
下表显示支持手势的结构体及其用途。窗口自动手势能够使窗口中的控件和程序自动处理Flick和Pan手势。
名称 |
说明 |
ANIMATEMESSAGEINFO |
该结构描述和窗口自动手势相关的动画数据。 |
GESTUREINFO |
调用TKGetGestureInfo填充该结构,并且提供手势的全部详细信息。 |
GESTUREMETRICS |
该结构包含有关时间和距离极限值的信息,这些值在触摸手势引擎识别某种手势类型时使用。该结构在TKGetGestureMetrics中使用。 |
WAGINFO |
该结构为某个窗口描述其窗口自动手势配置。 |
该结构描述和窗口自动手势相关的动画。该特性能够使窗口中的控件和程序自动处理Flick和Pan手势。
在 TKGetAnimateMessageInfo 函数中使用该结构体。
声明:
size_t cbSize;
DWORD dwAnimationID;
int nVPixelPosition;
int nHPixelPosition;
} ANIMATEMESSAGEINFO
参数:
cbSize: 结构体的大小。必须要指定。
dwAnimationID: 引起移动的动画类型。dwAnimationID必须设置为AMI_ANIMATION_TYPE_MOVE。
nVPixelPosition:垂直高度位置,按像素计算。
nHPixelPosition:水平宽度位置,按像素计算。
备注:
移动中的动画由Pan和Flick手势引起。
调用TKGetGestureInfo填充该结构,并且提供手势的全部详细信息。
声明:
UINT cbSize;
DWORD dwFlags;
DWORD dwID;
HWND hwndTarget;
POINTS ptsLocation;
DWORD dwInstanceID;
DWORD dwSequenceID;
ULONGLONG ullArguments;
UINT cbExtraArguments;
} GESTUREINFO, *PGESTUREINFO;
参数:
cbSize:结构体大小。必须在调用TKGetGestureInfo前初始化为sizeof(GESTUREINFO)。
dwFlags:包含手势标志,可能为这些值值:GF_BEGIN 、GF_END 、GF_END | GF_INERTIA 。
dwID:手势命令。更多的手势定义,参见下面的备注。
hwndTarget:接收手势消息的目标窗口句柄。
ptsLocation:POINTS结构,包含和手势相关的屏幕坐标信息。
dwInstanceID:不使用。
dwSequenceID:手势时间戳。程序可以使用该值表示手势间的潜在时间(尤其在Flick和Pan之间)。
ullArguments:和命令相关的信息。封装到该字段的参数值依赖于手势命令。
cbExtraArguments:GetGestureExtraArguments函数返回的额外信息的大小。
备注:
下面的手势可以通过手势引擎识别。
GID_BEGIN
- 包含标记每个手势开始点的坐标。当触摸屏幕时发送。
GID_END
- 包含标记每个手势结束点的坐标。当手指或光笔从屏幕抬起后发送。 当接收该命令后,GESTUREINFO 的 ullArguments 字段总是被设置为0。
GID_PAN
-
Pan在当用户在窗口上按下而且在任意方向移动(该过程手指保持和屏幕一直接触)时发生。 识别引擎发送GID_PAN消息,该消息包含手势的开始点和当前点。在手指或光笔从窗口屏幕抬起前,会为每次窗口移动消息发送一次GID_PAN消息。GID_END 用来标记Pan移动的结束。
程序根据连续两次Pan手势间的差异计算移动增量。
如果设置GF_INERTIA标志,GESTUREINFO 的 ullArguments 值和GID_SCROLL 时一样。
GID_SCROLL
-
用户按下窗口(或者也可能在窗口上Pan),然后手指或光标在任意方向迅速移动,当移动结束抬起手指或光笔前发生Scroll。
识别引擎在Flick手势后发送GID_SCROLL消息。GID_SCROLL会发送到接收当前触摸过程第一个手势消息的窗口,第一个手势消息可能是一个Pan消息或一个Hold消息。GESTUREINFO 的 ullArguments 字段包含关于角度、方向和Flick速度的信息。
主要的方向常量值如下:
ARG_SCROLL_NONE
ARG_SCROLL_RIGHT
ARG_SCROLL_UP
ARG_SCROLL_LEFT
ARG_SCROLL_DOWN
当设备旋转时,手势自动调整匹配旋转。
Flick的角度值以从0至65535范围值计量。
可以使用下面的宏从GID_SCROLL手势消息的ullArguments 字段来提取出角度、方向和速度。
GID_SCROLL_ANGLE
GID_SCROLL_DIRECTION
GID_SCROLL_VELOCITY
可以使用下面的宏在角度和弧度间相互转换。
GID_ROTATE_ANGLE_TO_ARGUMENT
GID_ROTATE_ANGLE_FROM_ARGUMENT
To convert the raw angle to radians, divide the raw angle by 32768, then multiply that value by 360/32768. 32768 units represent one full circle.
(要转换原始角度到弧度,原始角度除以32768,然后再乘以(360/32768)。32768 代表一个整圆。)
原始角度和当前系统方向有关(设备是横向还是纵向并不可知)。当系统旋转,手势方向和角度自动调整匹配旋转。
GID_SCROLL会被发送到接收当前触摸过程第一个手势消息的窗口,可能是一个Pan消息或一个Hold消息。
GID_HOLD
-
用户按下窗口并保持手指或光笔按住超过指定的超时时间,此时发生Hold。
识别引擎发送一个GID_HOLD消息,然后当手指或光笔抬起时发送一个GID_END 消息。
Hold 手势后可能会跟着Pan移动(移动过程会生成许多GID_PAN消息),但是,在生成GID_PAN消息后绝不会再生成GID_HOLD消息。
ullArguments 字段不会在该命令中使用。
GID_SELECT
- 当用户用手指或光笔敲击屏幕,敲击过程时间小于系统指定的SELECT超时时间,此时发生Select。GESTUREINFO 的ullArguments 字段不会在该命令中使用。
GID_DOUBLESELECT
-
当用户用手指或光笔敲击两次屏幕,两次敲击过程时间小于系统指定的DOUBLESELECT超时时间,此时发生Double Select。
DOUBLESELECT超时时间是指连续两次鼠标抬起事件发生的间隔时间。
GESTUREINFO 的ullArguments 字段不会在该命令中使用。
该结构包含有关时间和距离极限值的信息,这些值在触摸手势引擎识别某种手势类型时使用。该结构在TKGetGestureMetrics中使用。该结构包含在Gesture.h头文件中。
声明:
UINT cbSize;
DWORD dwID;
DWORD dwTimeout;
DWORD dwDistanceTolerance;
DWORD dwAngularTolerance;
DWORD dwExtraInfo;
} GESTUREMETRICS, *LPGESTUREMETRICS;
参数:
cbSize:结构体大小,按字节计算。必须设置该值。
dwID:包含手势识别ID,dwID 必须被设置为下面的一种:
GID_PAN
GID_ SCROLL
GID_HOLD
GID_SELECT
GID_DOUBLESELECT
所有其他的字段会按照需要根据dwID的值重写。
dwTimeout:毫秒值。按照下面的方式,根据dwID中的值翻译该值。
GID_SCROLL 从触摸屏幕到维持该接触到Scroll手势被识别的最大时间。该值为250。
GID_HOLD 从触摸屏幕某点后到Hold手势识别经过的时间。该值为250。
GID_SELECT 从触摸开始到离开屏幕,直到Select手势被识别的最大时间。该值为901。
GID_DOUBLESELECT 连续两次Select手势能够被Double Select识别的最大间隔时间。如果连续两次Select手势的间隔时间大于Double select手势的超时时间,那么第二次手势会被识别为Select手势。 该值为350。
GID_PAN 该值不被使用。
dwDistanceTolerance: 一英尺的1/1000。按照下面的方式,根据dwID中的值翻译该值。
GID_SCROLL:如果一个Scroll手势被识别,触摸接触移动的最小距离。该值为198。
GID_HOLD:触摸接触在屏幕上移动能够被识别为Hold手势的最大距离公差(手指接触点的边界半径)。该值为197。
GID_SELECT:触摸接触在屏幕上移动能够被识别为Select手势的最大距离公差(手指接触点的边界半径)。该值为197。
GID_DOUBLESELECT:识别为Double Select手势的连续两个Select手势的最大距离公差(从第一个接触点到第二个接触点)。如果距离超过,第二个手势被识别为Select手势。 该值为197。
GID_PAN:一个触摸接触能够被识别为Pan手势必须移动的最小距离公差(从第一个接触点到第二个接触点)。 返回值为198。
dwAngularTolerance:弧度值。按照下面的方式,根据dwID中的值翻译该值。
GID_SCROLL:
The maximum amount of angular tolerance that a touch contact can diverge within for a scroll gesture to be recognized. The return value is 0.34586 (in radians).
(Scroll手势被识别时,触摸接触分向(diverge)被识别的最大角度公差。该值为0.34586,按弧度值计算。)
GID_HOLD 、GID_SELECT 、GID_DOUBLESELECT 、GID_PAN 不被使用。
dwExtraInfo:指定手势依赖的值。按照下面的方式,根据dwID中的值翻译该值。
GID_SCROLL:水平或垂直轴上角度分向的最大允许值。一个有效的滚动手势根据该值被分为四个主要的预定义方向:上、下、左、右。该参数被称为是滚动手势方向公差。该值为0.50000,按弧度值计算。
GID_HOLD 、GID_SELECT 、GID_DOUBLESELECT 、GID_PAN 不被使用。
该结构为某个窗口描述其窗口自动手势配置。窗口自动手势能够使窗口中的内容自动响应Flick和Pan手势滚动。该结构在TKSetWindowAutoGesture 和TKGetWindowAutoGesture结构中使用。
声明:
size_t cbSize;
DWORD dwFlags;
UINT nOwnerAnimateMessage;
UINT nAnimateStatusMessage;
HBRUSH hExtentBrush;
UINT nItemHeight;
UINT nItemWidth;
BYTE bHorizontalExtent;
BYTE bVerticalExtent;
} WAGINFO
参数:
cbSize:结构体大小,按字节计算。
dwFlags:位掩码,有下列属性组成:
WAGIF_OWNERANIMATE |
该标志是必需的。它表示由nOwnerAnimateMessage识别的动画消息被发送到窗口过程。当设置该标志时,窗口过程负责管理滚动条位置并绘制控件内容。 |
WAGIF_VSCROLLABLE |
使垂直滚动支持Pan和Flick。如果未设置,Pan和Flick的垂直分量将被取消。该标志和WAGIF_HSCROLLABLE 组合为全向滚动。 |
WAGIF_HSCROLLABLE |
使水平滚动支持Pan和Flick。如果未设置,Pan和Flick的水平分量将被取消。该标志和WAGIF_VSCROLLABLE 组合为全向滚动。 |
WAGIF_LOCKAXES |
除非WAGIF_VSCROLLABLE和WAGIF_HSCROLLABLE都被设置,否则取消该标志。设置该标志意味着退出启动任意方向滚动。相反,滚动将沿着水平或垂直轴发生。记住,对Windows Mobile 6.5,该标志仅适用于Flick消息。Pan消息处理不受影响,除非设置WAGIF_IGNOREPAN标志。 |
WAGIF_IGNOREPAN |
关闭Pan消息自动手势处理。 |
WAGIF_IGNORESCROLL |
关闭Flick消息自动手势处理。 |
|
nOwnerAnimateMessage:动画消息ID。该消息在一个触摸交互后被发送至窗口过程来重绘窗口内容。消息ID必须为WM_USER或更大值。关于该消息内容的更多信息,参见TKGetAnimateMessageInfo。
或者,设置该值为0来取回WM_HSCROLL 或 WM_VSCROLL(或者全部)消息,代替取回WAG动画消息。
当nOwnerAnimateMessage设置为0,HorizontalExtent和bVerticalExtent被取消。
nAnimateStatusMessage:消息被发送至窗口过程来表示动画的一个状态改变,比如开始或结束。该消息必须为 WM_USER或更大值。
该值为0代表没有动画状态消息要被发送。
lParam 值包含标识动画状态的信息,可能为如下值:
-
WAG_STATUS_ANIMATION_START
WAG_STATUS_ANIMATION_END
WAG_STATUS_ANIMATION_CHANGE
WAG_STATUS_ANIMATION_CHANGE 表示滚动输入模式发生了改变。
wParam 值包含更多关于lParam 值的信息。
- 如果lParam值是WAG_STATUS_ANIMATION_START 或 WAG_STATUS_ANIMATION_CHANGE,有效的wParam值是WAG_STATUS_ANIMATION_CONTINUOUS(表示持续的输入或Pan)或WAG_STATUS_ANIMATION_DISCRETE(一个单独的输入事件,比如Flick)。
- 如果lParam值是WAG_STATUS_ANIMATION_END,那么wParam值是WAG_STATUS_ANIMATION_ FINISHED(动画终止,没有任何中断)或 WAG_STATUS_ANIMATION_INTERRUPTED(动画被中断,比如点击由上次Flick引起的正在滚动的列表)。
nItemHeight:滚动范围内每项的高度,按像素计算。滚动范围指的是支持滚动的区域。如果该值为0,项高度使用下面的公式自动计算:
nItemHeight = <window client height> / <vertical scroll bar page size>.
当该值为0,如果窗口大小发生改变,高度被重新计算。
nItemWidth:滚动范围内每项的宽度,按像素计算。滚动范围指的是支持滚动的区域。如果该值为0,项高度使用下面的公式自动计算:
nItemWidth = <window client width> / <horizontal scroll bar page size>.
当该值为0,如果窗口大小发生改变,宽度被重新计算。
bHorizontalExtent:The percentage of the viewable window height that can be extended beyond the scroll range in the horizontal axis, from 0 to 100. The default bHorizontalExtent value is 0.
一旦达到扩展极限值,将不会再处理Pan消息。
如果nOwnerAnimateMessage设置为0,bHorizontalExtent 和 bVerticalExtent 都被取消。
bVerticalExtent:The percentage of the viewable window width that can be extended beyond the scroll range in the vertical axis, from 0 to 100. The default bVerticalExtent value is 0.
一旦达到扩展极限值,将不会再处理Pan消息。
如果nOwnerAnimateMessage设置为0,bHorizontalExtent 和 bVerticalExtent 都被取消。
备注:
如果dwFlags标志不包含WAGIF_OWNERANIMATE标志,那么TKSetWindowAutoGesture 将会调用失败!
物理引擎给触摸手势计算好明确的动画点。因为动画在中央引擎中计算,因此手势动画能够始终如一的贯穿系统。该引擎仅仅为和二维滚动相关的手势计算动画。
当给定动画信息,比如动画初始速度和角度以及有关动画应该如何处理边界条件,物理引擎会生成一连串动画点。在动画生命周期的任何时间内都可以请求获得动画点。
如果想预先构造一个动画,需要给引擎提供一组时间戳然后接收和这些时间戳对应的一组动画点集合。也可以使用该方法进行你的动画测试。
当使用物理引擎时,必须分别为每组动画点集合创建一个独立的物理引擎对象实例。
边界和可见区域:
物理引擎基于边界和可见区域概念。边界是一个逻辑矩形,代表整个控件。可见区域是控件的一部分,它是在任何时间都可见的部分。
动画有速度和方向,它们决定可见区域如何做移动,这需要考虑边界。动画会引起可见区域移动至边界极限。当移动至边界极限时,如何指定,将发生边界动画。边界动画可能为下面一种类型:
- 橡皮筋。 可见区域临时移除边界,然后迅速返回至边界,就好像是橡皮筋效果一样。
- 什么都没有。 可见区域在到达边界边缘时立即停止。
动画停止点:
在动画结束后,有可能出现摸个控件内的项出现被截断的现象,这依赖于动画在哪里停止。
如果控件内的所有项都是固定大小,你可以在创建物理引擎的时候指定每项的大小。物理引擎将根据每项的固定大小计算动画的停止点,以便在动画结束时可见区域能够对准每项的边界。
Physics Engine Reference (DTK)
该部分包含对支持手势物理引擎的编程元素的描述。包括:
Physics Engine Functions (DTK):提供使用手指或光笔控制设备交互的可用函数的概述。
Physics Engine Structures:提供使用手指或光笔控制设备交互的可用结构体的概述。
Physics Engine Constants:提供使用手指或光笔控制设备交互的可用消息的概述。
Physics Engine Functions (DTK)
下表显示支持物理引擎的函数及其用途:
名称 |
说明 |
TKCreatePhysicsEngine |
创建物理引擎 |
TKDestroyPhysicsEngine |
销毁物理引擎 |
TKSetPhysicsEngineUserTime |
该函数可以手动为物理引擎设置时间。 |
TKQueryPhysicsEngine |
该函数取回物理引擎的当前状态。 |
创建物理引擎并返回新物理引擎的句柄。必须创建一个PHYSICSENGINEINIT结构来指定物理引擎的参数并传递给该函数。
该函数包含在GesturePhysicsEngine.h头文件中。
声明:
__in const PHYSICSENGINEINIT* pEngineInit,
__out HPHYSICSENGINE* phResult
);
参数:
pEngineInit:指向PHYSICSENGINEINIT结构的指针。该结构指定物理引擎的配置参数。
phResult:指向HPHYSICSENGINE类型变量的的指针,用来接收新创建的物理引擎的句柄。
返回值:
返回值可能为下面的值,它也可能返回其他值,应该使用SUCCEEDED和FAILED宏来测试。
S_OK:表示物理引擎创建成功。
E_INVALIDARG:表示参数无效。
E_OUTOFMEMORY:表示系统没有足够的内存来创建物理引擎。
销毁物理引擎。该函数包含在GesturePhysicsEngine.h头文件中。
声明:
HPHYSICSENGINE hEngine
);
参数:
hEngine:物理引擎对象句柄。
返回值:
S_OK:表示物理引擎销毁成功。
Indicates that the physics engine is successfully destroyed.
E_INVALIDARG:传入的hEngine句柄无效。
取回物理引擎的状态。如果引擎模式是默认模式,引擎状态基于当前系统时钟的时间。如果系统模式为PHYSICSENGINE_FLAG_USERTIME,那么引擎状态将基于最近调用的TKSetPhysicsEngineUserTime函数中指定的时间。.
该函数包含在GesturePhysicsEngine.h头文件中。
声明:
HPHYSICSENGINE hEngine,
__out PHYSICSENGINESTATE* pState
);
参数:
hEngine:物理引擎对象句柄。
pState:指向PHYSICSENGINESTATE结构的指针,该结构指示物理引擎的状态。
返回值:
返回值可能为下面的值,它也可能返回其他值,应该使用SUCCEEDED和FAILED宏来测试。
S_OK:表示获取物理引擎状态成功。
E_INVALIDARG:表示某个参数无效。
E_UNEXPECTED:表示物理引擎对象没有被初始化。
在动画开始时,设置物理引擎对象的当前时间戳。可以使用该函数模拟限时的有序步骤,例如,检测动画过程或重现指定的测试情形。
使用该函数,物理引擎必须是创建在PHYSICSENGINE_FLAG_USERTIME 模式下。
该函数包含在GesturePhysicsEngine.h头文件中。
声明:
HPHYSICSENGINE hEngine,
DWORD dwTime
);
参数:
hEngine:物理引擎对象句柄。
dwTime:和动画开始相关的时间戳,按毫秒计算。
返回值:
返回值可能为下面的值,它也可能返回其他值,应该使用SUCCEEDED和FAILED宏来测试。
S_OK:表示物理引擎时间设置成功。
E_INVALIDARG:物理引擎句柄无效。
E_UNEXPECTED:物理引擎不是PHYSICSENGINE_FLAG_USERTIME 模式。
备注:
当物理引擎在PHYSICSENGINE_FLAG_USERTIME 模式下创建,时间设置为0。
必须调用TKSetPhysicsEngineUserTime函数并指定比物理引擎当前时间戳值大的时间戳,否则,物理引擎可能会为动画计算错误的停止点。
下表的常量被用于物理引擎API:
名称 |
值 |
说明 |
PHYSICSENGINE_BOUNDARY_MODE_NONE |
0 |
表示当手势动画到达边界时,没有指定的动画发生。 |
PHYSICSENGINE_BOUNDARY_MODE_RUBBERBAND |
1 |
表示当手势动画到达边界时,会产生橡皮筋动画。 |
|
|
|
PHYSICSENGINE_MOVEMENT_MODE_DECELERATE |
0 |
表示动画速度随着时间减慢。 |
PHYSICSENGINE_FLAG_USERTIME |
1 |
表示引擎时间由用户指定。 |
备注:
可以使用这些常量构造PHYSICSENGINEINIT结构来配置物理引擎。
下面显示支持物理引擎的结构体及其用途:
PHYSICSENGINEINIT:该结构体定义了用于创建物理引擎的初始化参数。
PHYSICSENGINESTATE:该结构体描述了在当前引擎时间戳下物理引擎的状态。
描述初始化物理引擎对象的参数。要创建物理引擎,必须给TKCreatePhysicsEngine传递指向该结构体的指针。
该结构体在GesturePhysicsEngine.h头文件中。
声明:
DWORD cbSize;
DWORD dwEngineType;
DWORD dwFlags;
LONG lInitialVelocity;
DWORD dwInitialAngle;
BYTE bXAxisMovementMode;
BYTE bXAxisBoundaryMode;
BYTE bYAxisMovementMode;
BYTE bYAxisBoundaryMode;
RECT rcBoundary;
SIZE sizeView;
POINT ptInitialPosition;
SIZE sizeItem;
} PHYSICSENGINEINIT;
成员:
cbSize:指定结构体大小,按字节计算。必须设置为sizeof(PHYSICSENGINEINIT)。
dwEngineType:保留,设置为0。
dwFlags:指定控制引擎行为的标志,可用值有:
- 0 :默认模式。
- PHYSICSENGINE_FLAG_USERTIME:用户指定的时间模式。
默认模式下,物理引擎从系统时钟读取时间。
用户指定时间模式下,必须调用TKSetPhysicsEngineUserTime设置时间
lInitialVelocity:指定触摸手势动画的初始化速度,单位为“像素每秒(in pixels per second)”。
dwInitialAngle:动画的初始化角度。该值的范围是:0至65536。0代表-2pi弧度,指向东部;65536代表+2pi。角度按照逆时针方向增加。
bXAxisMovementMode:指定X轴移动模式。必须设置为PHYSICSENGINE_MOVEMENT_MODE_DECELERATE。
bXAxisBoundaryMode:指定当边界到达X轴时的动画行为。有效值有:
-
PHYSICSENGINE_BOUNDARY_MODE_NONE:没有动画
PHYSICSENGINE_BOUNDARY_MODE_RUBBERBAND:橡皮筋动画
bYAxisMovementMode:指定Y轴移动模式。必须设置为PHYSICSENGINE_MOVEMENT_MODE_DECELERATE。
bYAxisBoundaryMode:指定当边界到达Y轴时的动画行为。有效值有:
-
PHYSICSENGINE_BOUNDARY_MODE_NONE:没有动画
PHYSICSENGINE_BOUNDARY_MODE_RUBBERBAND:橡皮筋动画
rcBoundary:指定定义内容边界的矩形。边界包含所有内容,包括整个用户控件。
sizeView:指定可见区域的尺寸。
ptInitialPosition:指定可见区域左上角的初始位置。
sizeItem:指定每项大小,主要用于动画突然停止时。二维方向中小于1的项都被当成1。物理引擎只在项边界停止动画。如果项的大小为1,物理引擎可以在任一点停止。
备注:
如果该结构任何成员包含无效数据, TKCreatePhysicsEngine都将返回E_INVALIDARG。
该结构描述在当前引擎时间下的物理引擎状态。该结构在调用TKQueryPhysicsEngine函数时生成。
该结构体在GesturePhysicsEngine.h头文件中。
声明:
DWORD cbSize;
DWORD dwTime;
POINT ptPosition;
LONG lVelocityX;
LONG lVelocityY;
BOOL fComplete;
} PHYSICSENGINESTATE;
成员:
cbSize:指定该结构体的大小,按字节计算。必须设置为sizeof(PHYSICSENGINESTATE)。
dwTime:指定当前引擎时间,按毫秒计算。
ptPosition:指定当前动画位置,按像素计算。
lVelocityX:指定X轴方向的速度,单位为“像素每秒”(in pixels per second)。
lVelocityY:指定Y轴方向的速度,单位为“像素每秒”(in pixels per second)。
fComplete:指定动画是否完成。
备注:
如果cbSize 没有设置为sizeof(PHYSICSENGINESTATE),TKQueryPhysicsEngine将返回E_INVALIDARG。
posted on 2010-01-30 16:17 listenlisten 阅读(2843) 评论(0) 编辑 收藏 举报