在 Windows 7
Windows 7 中 multiTouch 功能
Yochay Kiriaty
鏈 枃璁 ㄨ :
|
本文使用以下技术: Windows 7 |
本文基于 Windows 7 的预发布版本。 详细信息会有所变动。
内容
Windows 7 Multitouch 简介
Windows 7 Multitouch 编程模型的平台
使用笔势
使用 Windows 触摸原始消息
摘要
这是有关 Windows 7 文章的第三个文章系列中。 该系列重点介绍的开发人员可以使应用程序在 Windows 7 shine 点击到新的用户体验。 第 1 部分介绍的库。 第 2 部分涉及任务栏 API。 第 3 部分介绍了 Windows 7 中的 multitouch 功能。 下载 Windows 7 发布候选现在可帮助您充分利用这篇文章中获取。
Windows 7 Multitouch 简介
Windows 7 中 我们有 enriched 触摸,Windows 熟悉进行接触是头等公民,作为另一个方法与您的计算机旁边鼠标和键盘进行交互。 最近几年,我们有 witnessed 广泛的 multitouch 生成一个非常积极的用户体验的设备。 因此,是只介绍 Windows 7 中的作为一个核心功能,这样 multitouch 支持 Windows 自然。
使用 Windows 7 Multitouch 平台中,可以自由地直接与您的计算机进行交互。 渚嬪的方式 就能够到达出和缓慢滚动直接从 Windows 资源管理器中,图片或 flick 和快速移动它们。 很重要的了解我们 didn’t 创建一个特殊的 Windows 7 Multitouch Shell。 没有任何特殊留只能在 multitouch 设备上可用的。 在最简单的示例是 Windows 7 任务栏跳转列表。 当您使用鼠标右键单击任务栏上的任何图标时,您会看到其相应的跳转列表。 例如,右击 Windows Live Messenger 图标上显示了实时消息已经跳转列表。 但是,如何可以您右键单击使用 multitouch 呢? 只需按实时消息图标拖出用手指中, 所示 图 1
图 1 使用 Multitouch 上的实时消息已经跳列表
执行该拖动笔势显示实时消息已经跳转列表。 可以看到在 图 2 ,触摸触发跳列表显示为标准用鼠标右键单击跳转列表中相同的内容。 右边的图显示了使用触摸的实时消息已经跳转列表。 已启用 multitouch 的跳转列表中每个项间距大于间距每项左边的图像是默认右键单击跳转的列表。
图 2 Multitouch 和标准视图的跳转列表
在 Windows Live Messenger 是一个示例,在 Windows 7 doesn’t 创建一组新的 UI 仅用于联系的方案,但而使得混合到现有的基础结构。 任务栏是只有一个示例附带 Windows 7,如 XPS 查看器、 Windows 图片查看器和 IE8 许多 multitouch 优化体验。
Windows 7 Multitouch 编程模型的平台
若要提供的应用程序的所有类型 well-rounded Windows 接触解决方案,接触 Windows 平台提供支持各种的等级)。 有几种方案的可增强应用程序使用 Windows 接触平台功能。 您可以采用一种特定的方法之前,您应考虑什么完全您想与您的应用程序。
旧的支持 let’s 假定已有现有应用程序使用较大的安装基础。 您可能会问自己,什么我 multitouch 用户的经验时,将 Windows 7 multitouch 启用计算机上运行应用程序? 好消息是 Windows 7 Multitouch 平台提供的应用程序不支持触摸的并不是设计来支持 multitouch 可用出的体验。 特别,它提供了免费的-在的现成的支持。 几个基本的笔势 换而言您可能需要几个基本的笔势工作,并使应用程序中的所需的效果。 基本的笔势包括单个接头程序或两个手指缩放和 Windows Vista 时间框架中引入的光标笔势中平移的两个手指。
添加基本 Multitouch 支持 此处我们重点介绍添加直接笔势,其他的行为以及支持和用户界面更改为使多触摸易于超出简单笔势支持应用程序。
我们已 ’ve 审阅这篇文章的开头附近的例如,触摸的优化任务栏跳转列表。 通过 getMessageExtraInfo 方法任务栏可以跟踪输入消息的来源以及确定它是否按消息,然后相应地作出响应。
鍙 ﹀ 的方式 您可以使用笔势来增强您的应用程序,并提供更好地 multitouch 支持。 笔势直接响应的应用程序具有对用户接触启用触摸的设备时它们的行为方式的全部控制权。 渚嬪的方式 Windows 7 附带 Windows 照片查看器。 在将图片查看器应用程序中查看器接收缩放笔势所来自的位置的特定信息。 也就是缩放笔势包含有关中心点--X 的特定信息,并重 Y 坐标--将缩放比例笔势,然后在图片查看器可以将精力集中周围笔势的中心。 Windows 图片查看器应用程序还使用移动和旋转笔势提供很好图像查看熟悉,相对较小的努力。
使用笔势,可以还重写默认的平移行为。 渚嬪的方式 默认触摸滚动设计用于在主要垂直,滚动 (如网页或文档的文本为中心窗口中 ; 水平拖动选定文本而不是滚动。 在大多数的应用程序中,这适用一切正常。 但是,如果您的应用程序实际需要支持水平滚动吗? 此外,某些应用程序会臃肿太快或太慢将默认滚动。 笔势的支持可以覆盖默认值平移行为和优化您的应用程序已经需要它。
为 Multitouch 优化的体验 最多可支持 multitouch 从头设计应用程序时,最佳方案。 这些应用程序生成 Windows 消息接触消息,WM_TOUCH 的顶部。 此消息提供原始接触该的应用程序数据并且可以使用这些消息和处理多个联系点。 我们前面提到的大多数笔势是两个的接头程序的手势 WM_TOUCH 邮件可以收到时为您的基础的多个同时的接触点按敏感的硬件支持。
Windows 7 Multitouch 平台还提供了操作和可帮助您解释接触邮件习惯处理器。 将一个接收作为输入时所涉及的对象的黑色框以及相关的触摸的所有邮件的操作。 结果是表示转换的接头程序移动发生了一个二维仿射变换矩阵。 例如,如果您正在编写一个照片编辑应用程序,您可以获取两个在同一时间使用但您想要旋转,许多触摸调整大小,翻译该的照片和操作过程中提供您需要在对象上反映所做更改的照片。
习惯为应用程序提供了非常基本的物理学模型,并为您提供继续顺利过渡的对象,即使您创建一个简单的切换效果,而不停止点上的对象选取手指从该区分触摸的设备的简便方法。
使用笔势
只要用户接触触摸敏感 Windows 7 启用设备,Windows 7 Multitouch 平台就将 WM_GESTURE 的笔势消息发送到默认情况下应用程序中。 这是免费的-在的现成的行为,您将需要退出如果您想停止接收这些消息。
笔势都与一个或两个手指触摸输入转换为某种类型的预定义操作 (笔势) 的用户执行的。 一次检测到 (操作系统正在进行的所有工作的),操作系统会将笔势消息发送到您的应用程序。 此邮件包含解码,并使其工作所需的所有信息。 Windows 7 支持以下的笔势:
- 缩放
- 单个接头程序和两个手指平移
- 旋转
- 两个手指点击
- 按下并点击
处理 WM_Gesture 消息 要使用笔势,您将需要处理 WM_GESTURE 消息发送到您的应用程序的。 濡傛灉鎮 ㄦ 槸 Win32 程序员可以检查 WM_GESTURE 中的邮件应用程序已经 WndProc 函数。
在 WM_GESTURE 一般消息用于所有的笔势。 因此,以确定您需要处理的笔势,您需要先解码笔势消息。 笔势的信息位于在 lParam 参数,并且需要使用一个特殊函数 GetGestureInfo,解码该笔势消息,如下面的代码段中所示。
GESTUREINFO gi;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(gi);
BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
获得 GESTUREINFO 结构后, 可以检查以确定哪些笔势执行 dwID。 GESTUREINFO 结构包含多个其他重要的成员:
- cbSize -结构,以字节为单位) 的大小
- ptsLocation -A 点结构包含与笔势坐标。 这些坐标都相对于屏幕的原点
- dwFlags -笔势的状态如开始,习惯和结束
- ullArguments 的 64 位无符号整数,其中包含 8 个字节中容纳的笔势的参数。 这是唯一的每个笔势类型的额外信息
这一知识与我们现在向前移动并且可以写入完整的开关的情况下方法处理所有的手势中所示 图 3 .
图 3 开关写的方法
void CMTTestDlg::DecodeGesture(WPARAM wParam, LPARAM lParam)
{
GESTUREINFO gi;
ZeroMemory(&gi, sizeof(GESTUREINFO));
GetGestureInfo((HGESTUREINFO)lParam, &gi);
switch (gi.dwID){
case GID_ZOOM:
// Code for zooming goes here
break;
case GID_PAN:
break;
case GID_ROTATE:
break;
case GID_TWOFINGERTAP:
break;
case GID_PRESSANDTAP:
break;
default:
// You have encountered an unknown gesture
break;
CloseGestureInfoHandle((HGESTUREINFO)lParam);
}
请注意,我们调用 CloseGestureInfoHandle 函数关闭与笔势的信息处理程序相关联的资源的函数的末尾。 如果您处理 WM_GESTURE 消息,则负责关闭句柄使用此功能。 未能执行此操作可能会导致内存泄漏。
处理笔势消息具有固定的流,其中包括配置,解码该笔势邮件和处理到您的应用程序需要根据在特定的笔势。 在前面的代码中可以看到,不困难要这样做。
现在 let’s 审阅详细缩放笔势,这将使您了解了所有其他笔势的可能外观。
使用缩放笔势来缩放对象
缩放笔势通常由用户作为一个 “ pinch ” 移动位置到每个其他缩小,移动手指更接近,并移动手指放大以扩大内容远离分开的两个联系点之间。 缩放笔势使您可以调整对象的大小。 图 4 说明了缩放笔势的工作原理。
图 4 缩放摆放
现在,let’s 看到您需要在您 GID_ZOOM 开关,以获得所需的缩放效果中实现哪些代码。
笔势的信息的结构包括 dwFlags 成员用于确定笔势的状态,并且可以包含任何以下值:
- GF_BEGIN – 指示的笔势正在启动,在第一个 WM_Gesture 邮件中接收
- GF_INERTIA – 指示笔势的已触发习惯
- GF_END – 指示已完成的笔势
- 在 默认值 开关-的笔势邮件的其余部分并且通常称为增量
我们将使用 GF_BEGIN 标志保存为一个引用下面的步骤的初始启动到变量接触点的坐标。 我们将在 ptsLocation 保存到 _ptFirst 变量。 对于缩放笔势,在 ptsLocation 表示缩放的中心。
默认情况下处理下面的缩放消息到达的。 我们将保存到 _ptSecond 变量坐标。 下一步中,我们计算缩放中心点的缩放和最后一次我们将更新矩形 (我们图形对象) 以反映缩放中心点和缩放比例。 图 5 展示这些参数。
图 5 GID_ZOOM 开关
case GID_ZOOM:
switch(gi.dwFlags)
{
case GF_BEGIN:
_dwArguments = LODWORD(gi.ullArguments);
_ptFirst.x = gi.ptsLocation.x;
_ptFirst.y = gi.ptsLocation.y;
ScreenToClient(hWnd,&_ptFirst);
break;
default:
// We read here the second point of the gesture. This is middle point between fingers.
_ptSecond.x = gi.ptsLocation.x;
_ptSecond.y = gi.ptsLocation.y;
ScreenToClient(hWnd,&_ptSecond);
// We have to calculate zoom center point
ptZoomCenter.x = (_ptFirst.x + _ptSecond.x)/2;
ptZoomCenter.y = (_ptFirst.y + _ptSecond.y)/2;
// The zoom factor is the ratio between the new and the old distance.
k = (double)(LODWORD(gi.ullArguments))/(double)(_dwArguments);
// Now we process zooming in/out of the object
ProcessZoom(k,ptZoomCenter.x,ptZoomCenter.y);
InvalidateRect(hWnd,NULL,TRUE);
// Now we have to store new information as a starting information for the next step
_ptFirst = _ptSecond;
_dwArguments = LODWORD(gi.ullArguments);
break;
}
break;
在默认的大小写处理我们保存的笔势,位置和我们可以从两个集的磅值 (表示当前的接触点和前一) 计算缩放中心位置以及将其存储在 ptZoomCenter。 我们还计算通过计算比在两个点之间的缩放系数。 ProcessZoom 帮助器函数对调用更新以反映缩放系数和中心点新坐标。
处理 Windows 7 默认笔势的其余部分是非常类似到特定缩放笔势处理以上所述。 笔势,每个用例方案的每个不同的只是内部逻辑的实现和所有的笔势遵守相同的流。 下一步中,我们检查最佳模型,并了解到可以接收和处理原始 API 接触事件。
使用 Windows 触摸原始消息
为了开始接收原始触摸消息,WM_TOUCH,您需要先要求操作系统将按邮件发送到您的应用程序的启动和停止发送默认笔势邮件。 涓烘 需要调用 RegisterTouchWindow(HWND hWnd, ULONG uFlags) 函数。 调用此函数注册一个 hWnd 作为所接触的元素 (通常为一个窗口)。
使用笔势,您处理您的应用程序中已经 WndProc WM_TOUCH 邮件为函数。 单个 WM_TOUCH 消息可以包含几个不同 “ 接触点 ” 需要的邮件将被 unpacked 触摸的数组输入结构。 要为标准的做法到数组中的该数组中的每个结构从单个联系点表示数据的位置的 TOUCHINPUT 结构解压缩 WM_TOUCH 消息。 若要解压缩,您需要调用 GetTouchInputInfo(HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) 函数并将该 lParam WM_TOUCH 邮件的传递和一个新创建的接触点数组,如 图 6 所示。
图 6 Unpacking WM_TOUCH
case WM_TOUCH:
{
unsigned int numInputs = (unsigned int) wParam;
TOUCHINPUT* ti = new TOUCHINPUT[numInputs];
if(GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT)))
{
// Handle each contact point
for(unsigned int i=0; i< numInputs; ++i)
{
/* handle ti[i] */
}
}
CloseTouchInputHandle((HTOUCHINPUT)lParam);
delete [] ti;
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
您可以看到我们如何填充该 TOUCHPOINT ti 与数据的每个接触点的数组。 下一步中,我们循环接触点数组,我们逻辑对每个联系点,句柄 ti [i] 注释。 我们需要清除触摸句柄最后,通过调用 CloseTouchInputHandle(HTOUCHINPUT hTouchInput),传递原始 WinProc 已经 lParam。 未能执行此操作将导致内存泄漏。
前面的代码表示第一步中处理 WM_TOUCH 消息。 一个单一的触摸输入结构,TOUCHINPUT,包含您所要使用的单个接触点的所有必需信息:
- dwID – 是接触点标识符区分从另一个特定的触摸输入
- dwFlags – 是一组指定接触点的状态的位标志
- X 和 Y 接触点 (基本上每个接触点的位置) 的坐标
- dwTime – 是毫秒,事件将时间步
- dwMask – 一组可选字段的结构中指定的位标志包含有效的值
请注意在 X 和 Y 坐标以物理的屏幕坐标 (即,centa 像素) 的一个像素的百分之一至关重要。 此 extra-fine 分辨率提高了高精度和准确的手写识别其他应用程序,可能需要这样很好的解决方法。 但大多数情况下,您需要接触点 X 和 Y 坐标除以一个 100 转换到可用的屏幕坐标接触点坐标在开始使用这些坐标之前,请记住。
现在知道如何处理触摸的邮件,转并添加到上述我们 WM_TOUCH 处理程序的实际逻辑的所有信息。 let’s 使用这一知识,并生成也称为草稿填充一个 multitouch 绘制应用程序。
跟踪接触点的 ID 若要创建草稿板应用程序,您需要跟踪每一次接触点的移动和路径该窗体,然后绘制一条线沿该路径。 若要区分不同的接触点,并确保您真正处理每个联系点正确,我们会将不同的颜色分配给每个联系点。
之后的触摸的输入结构数组解压缩接触邮件 ti,您需要检查每个接触点的状态,并应用不同的逻辑,每个触摸状态。 新的接触点 indentified 按向下的状态,在草稿板的示例 TOUCHEVENTF_DOWN。 您注册新的接触点 ID,然后分配一种颜色。 一旦已接触点,TOUCHEVENTF_UP,您完成最后一次的绘制,并注销该接触点的 ID。 之间向下和事件,设置很可能是您将获得大量移动的邮件 TOUCHEVENTF_MOVE。 为每个移动消息到现有行添加一个新的点,并绘制新行的段。 图 7 显示了整个 WM_TOUCH 支持 multitouch 草稿板应用程序所需的处理程序。
图 7 WM_TOUCH 处理程序
case WM_TOUCH:
{
unsigned int numInputs = (unsigned int) wParam;
TOUCHINPUT* ti = new TOUCHINPUT[numInputs];
if(GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT)))
{
// For each contact, dispatch the message to the appropriate message handler.
for(unsigned int i=0; i< numInputs; ++i)
{
if(ti[i].dwFlags & TOUCHEVENTF_DOWN)
{
OnTouchDownHandler(hWnd, ti[i]);
}
else if(ti[i].dwFlags & TOUCHEVENTF_MOVE)
{
OnTouchMoveHandler(hWnd, ti[i]);
}
else if(ti[i].dwFlags & TOUCHEVENTF_UP)
{
OnTouchUpHandler(hWnd, ti[i]);
}
}
}
CloseTouchInputHandle((HTOUCHINPUT)lParam);
delete [] ti;
}
break;
密钥用于跟踪各个接触点正在使用该 dwID 的一样通过特定的触摸笔划的持续时间。 在 OnTouchDownHandler 的 Helper 函数您可以将此 ID 分配给一个 CStroke 对象,该基本行表示点的数组对象。 这行时,拖动手指触摸区分的设备路径窗体。 我们将不会覆盖整个代码示例,支持应用程序实际绘制到屏幕上的行。 基本上,所有您需要执行以支持 multitouch 可以找到在前面的代码示例。
您可以查看草稿板应用程序中的输出 图 8 .
图 8 草稿应用程序的输出
在默认的大小写处理我们保存的笔势,位置和我们可以从两个集的磅值 (表示当前的接触点和前一) 计算缩放中心位置以及将其存储在 ptZoomCenter。 我们还计算通过计算比在两个点之间的缩放系数。 ProcessZoom 帮助器函数对调用更新以反映缩放系数和中心点新坐标。
处理 Windows 7 默认笔势的其余部分是非常类似到特定缩放笔势处理以上所述。 笔势,每个用例方案的每个不同的只是内部逻辑的实现和所有的笔势遵守相同的流。 下一步中,我们检查最佳模型,并了解到可以接收和处理原始 API 接触事件。
使用 Windows 触摸原始消息
为了开始接收原始触摸消息,WM_TOUCH,您需要先要求操作系统将按邮件发送到您的应用程序的启动和停止发送默认笔势邮件。 涓烘 需要调用 RegisterTouchWindow(HWND hWnd, ULONG uFlags) 函数。 调用此函数注册一个 hWnd 作为所接触的元素 (通常为一个窗口)。
使用笔势,您处理您的应用程序中已经 WndProc WM_TOUCH 邮件为函数。 单个 WM_TOUCH 消息可以包含几个不同 “ 接触点 ” 需要的邮件将被 unpacked 触摸的数组输入结构。 要为标准的做法到数组中的该数组中的每个结构从单个联系点表示数据的位置的 TOUCHINPUT 结构解压缩 WM_TOUCH 消息。 若要解压缩,您需要调用 GetTouchInputInfo(HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) 函数并将该 lParam WM_TOUCH 邮件的传递和一个新创建的接触点数组,如 图 6 所示。
摘要
Windows 7 Multitouch 平台是一个非常强大的开发平台。 从实现默认笔势支持更高级的原始接触邮件,它使您大量的电源使用相对简单的实现。
该平台还包括操作和习惯的处理器。 操作都在很多方法,笔势类似,但它们得更强大。 操作用于简化转换任何给定数目对象的操作。 可以执行的特定组件笔势 (如旋转,缩放,组合,并同时缩放特定对象上。 操作处理器会产生一个两维 “ 转换 ” 表示矩阵在 X 中的转换和 Y 坐标、 在小数位数更改和随时间的接触点的执行移动发生对该对象的旋转角度。 一次最多请求在最后一个联系点,可能要向对象应用简单物理学以便顺利地涉及到停止,而不是它突然停止点上。 要支持的平滑动作,Windows 7 multitouch 平台提供习惯 API。
这些 API 将下一个 MSDN 文章的主题。
在 Microsoft,侧重于 Windows 7 一个技术 Evangelist Yochay Kiriaty 。 在软件开发过程中,他有不止一个十年的经验。 他已编写和 taught 学术计算机科学课程是将一个活动讨论参与者 Windows 日志.