每当用户触摸触敏式 Windows 7 设备时,Windows 7 多点触控平台都会向您的应用程序发送手势消息 WM_GESTURE。这是现成的免费行为,如果您希望停止接收此类消息,则需要选择退出。
手势被视为单指或双指触控输入,可以转换为用户执行的某种预定义操作(手势)。一旦检测到手势(操作系统为您进行所有检测),操作系统就会向应用程序发送手势消息。此消息包含解码和进行操作所需的全部信息。Windows 7 支持下列手势:

  • 缩放
  • 单指和双指平移
  • 旋转
  • 双指点击
  • 按下并点击
处理 WM_Gesture 消息 要使用手势,必须处理发送到应用程序的 WM_GESTURE 消息。如果您是 Win32 程序员,可以在应用程序的 WndProc 函数中检查 WM_GESTURE 消息。
WM_GESTURE 是用于所有手势的通用消息。因此,要确定需要处理的手势,您首先需要对手势消息进行解码。有关手势的信息可在 lParam 参数中找到,您需要使用一个特殊函数 GetGestureInfo 来解码手势消息,如下面的代码片段中所示。
  1. GESTUREINFO gi;
  2. ZeroMemory(&gi, sizeof(GESTUREINFO));
  3. gi.cbSize = sizeof(gi);
  4. BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
GESTUREINFO gi;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(gi);
BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
获取 GESTUREINFO 结构后,可以检查 dwID 以确定执行了哪个手势。GESTUREINFO 结构包含几个其他重要成员:
  • cbSize - 结构大小(以字节为单位)
  • ptsLocation - 一个 POINTS 结构,其中包含与手势相关的坐标。这些坐标始终都相对于屏幕的原点
  • dwFlags - 手势的状态,例如开始、延时和结束
  • ullArguments - 一个 64 位无符号整数,其中包含手势的参数,组合为八字节。这是额外信息,对于每个手势类型都是唯一的

继续操作并编写用于处理所有手势的完整 switch-case 方法

  1. void CMTTestDlg::DecodeGesture(WPARAM wParam, LPARAM lParam)
  2. {
  3. GESTUREINFO gi;
  4. ZeroMemory(&gi, sizeof(GESTUREINFO));
  5. GetGestureInfo((HGESTUREINFO)lParam, &gi);
  6. switch (gi.dwID){
  7. case GID_ZOOM:
  8. // Code for zooming goes here
  9. break;
  10. case GID_PAN:
  11. break;
  12. case GID_ROTATE:
  13. break;
  14. case GID_TWOFINGERTAP:
  15. break;
  16. case GID_PRESSANDTAP:
  17. break;
  18. default:
  19. // You have encountered an unknown gesture
  20. break;
  21. CloseGestureInfoHandle((HGESTUREINFO)lParam);
  22. }
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 消息,则您要确保使用此函数来关闭句柄。不这么做可能会导致内存泄漏。
处理手势消息具有一个固定流程,包括配置、解码手势消息以及根据应用程序的需要处理特定手势。正如您在以上代码中看到的那样,执行这个流程并不很难。
现在,让我们来详细了解缩放手势,通过这种手势,您也可以大致了解所有其他手势的工作原理。
使用缩放手势缩放对象

缩放手势通常被用户视为两个接触点之间的“挤压”运动,您可以将手指相互靠近以缩小内容显示,或者将手指分开以放大内容显示。使用缩放手势,您可以缩放对象的大小。图  说明了缩放手势的使用方式

现在,我们将了解需要在 GID_ZOOM switch 中实现什么代码才能达到所需的缩放效果。
手势信息结构包括 dwFlags 成员,该成员用于确定手势的状态,而且可以包括以下任何值:
  • GF_BEGIN - 指示手势即将开始,在第一个 WM_Gesture 消息中收到
  • GF_INERTIA - 指示手势已经触发了延时
  • GF_END - 指示手势已经完成
  • switch 的默认值 - 指示手势消息的剩余部分,通常称为变化量
我们将使用 GF_BEGIN 标志将接触点的初始开始坐标保存在变量中,并将其作为以下步骤的引用。我们将ptsLocation 保存在 _ptFirst 变量中。对于缩放手势,ptsLocation 表示缩放的中心。
收到的以下缩放消息由 default case 进行处理。我们将坐标保存在 _ptSecond 变量中。接下来,我们将计算缩放中心点和缩放比例。最后,我们还将更新矩形(我们的图形对象)以反映缩放中心点和缩放比例。显示了这些参数。

GID_ZOOM Switch:

  1. case GID_ZOOM:
  2. switch(gi.dwFlags)
  3. {
  4. case GF_BEGIN:
  5. _dwArguments = LODWORD(gi.ullArguments);
  6. _ptFirst.x = gi.ptsLocation.x;
  7. _ptFirst.y = gi.ptsLocation.y;
  8. ScreenToClient(hWnd,&_ptFirst);
  9. break;
  10. default:
  11. // We read here the second point of the gesture. This is middle point between fingers.
  12. _ptSecond.x = gi.ptsLocation.x;
  13. _ptSecond.y = gi.ptsLocation.y;
  14. ScreenToClient(hWnd,&_ptSecond);
  15. // We have to calculate zoom center point
  16. ptZoomCenter.x = (_ptFirst.x + _ptSecond.x)/2;
  17. ptZoomCenter.y = (_ptFirst.y + _ptSecond.y)/2;
  18. // The zoom factor is the ratio between the new and the old distance.
  19. k = (double)(LODWORD(gi.ullArguments))/(double)(_dwArguments);
  20. // Now we process zooming in/out of the object
  21. ProcessZoom(k,ptZoomCenter.x,ptZoomCenter.y);
  22. InvalidateRect(hWnd,NULL,TRUE);
  23. // Now we have to store new information as a starting information for the next step
  24. _ptFirst = _ptSecond;
  25. _dwArguments = LODWORD(gi.ullArguments);
  26. break;
  27. }
  28. break;
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;
在默认的 case 处理程序中,我们保存手势的位置,从两组点(表示当前接触点和前一个接触点)计算缩放中心位置,并将其存储在 ptZoomCenter 中。我们还通过计算两个点之间的比例来计算出缩放系数。调用ProcessZoom 帮助函数可以更新新的坐标,以反映缩放系数和中心点。
处理其他 Windows 7 默认手势与以上所述的特定缩放手势处理非常相似。所有手势都遵循相同的流程,只是在每个使用案例场景中,每个手势的内部逻辑实现有所不同。

windows7触屏编程的更多相关文章

  1. windows7触屏操作API

    每当用户触摸触敏式 Windows 7 设备时,Windows 7 多点触控平台都会向您的应用程序发送手势消息 WM_GESTURE.这是现成的免费行为,如果您希望停止接收此类消息,则需要选择退出. ...

  2. 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)

    本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...

  3. JavaScript触屏滑动API介绍

    随着触屏手机.平板电脑的普及和占有更多用户和使用时间,触屏的触碰.滑动等事件也成为javaScript开发不可避免的知识,现在何问起就和大家一起学习js的触屏操作,js的触屏touchmove事件,为 ...

  4. jQuery flickity 滑动触屏

    flickity是一款自适应手机触屏滑动插件,它的API参数很丰富,包括对齐方式.循环滚动.自动播放.是否支持拖动.是否开启分页.是否自适应窗口等. 在线实例 实例演示 使用方法 <div cl ...

  5. 触屏touchstart 与 click

    设计效果:当手指点击或触摸红框线menuList之外的部分时,弹框menuList消失. 问题:在优化触屏版的时候发现如图问题,当menuList弹出,手指触摸屏幕向下滑动时,menuList弹框不消 ...

  6. touch移动触屏滑动事件

    移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件 ...

  7. 朋友圈常见单页面触屏滑动上下翻屏功能jQuery实现

    翻页插件:实现原理,用margin-top来控制页面容器位置来实现上下翻页.margin这属性很好用,可以用来制作侧栏动画滑出菜单(左菜单,右内容,控制两者的margin实现):或者head下滑菜单 ...

  8. 触屏手机3G网站设计

    随着智能手机iphone和Android的热潮,衍生出基于Safari和Chrome浏览器的触屏手机网站Touch Screen Mobile Website. 触屏手机网站在中国还属于起步阶段,从行 ...

  9. Unity学习疑问记录之触屏

    当将Unity游戏运行到ios或android设备上时,桌面系统中的鼠标左键操作可以自动变为手机屏幕上的触屏操作,但鼠标操作无法实现一些特有的触屏操作,比如多点触屏. 触控对于Android移动设备来 ...

随机推荐

  1. GDI+ 和GDI

    GDI:Graphics Device Interface,即图形设备接口,是Windows API的一个重要组成部分.它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具 ...

  2. Linq 集合处理(Union)

    关于Union的两种情况 一.简单值类型或者string类型处理方式(集合需要实现IEnumerable接口) #region int类型 List<, , , , , }; List<, ...

  3. ERROR 1045 (28000): Access denied for user 'mycat'@'localhost' (using password: YES)

    创建用户: mysql> grant all on db1.* to mycat@'%' identified by '123456'; Query OK, 0 rows affected (0 ...

  4. 九度OJ小结2

    由于安排问题,距离上次小结时间已经过去很久.导致这次小结的内容很多. 本次小结涉及到主要内容如下所示: 基于并查集操作的最小生成树问题(prime算法或者kruskal算法): 最短路径问题(Floy ...

  5. POJ 1117 Pairs of Integers

    Pairs of Integers Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4133 Accepted: 1062 Des ...

  6. 关于sizeof和strlen

    已知 char *str1="absde"; char str2[]="absde"; char str3[8]={'a',}; char ss[] = &qu ...

  7. kafka 的quick start(windows平台)

    h1, h2, h3, h4, h5, h6, p, blockquote { margin: 5px; padding: 5; } body { font-family: "Helveti ...

  8. Modelsim SE 仿真 ALTERA FPGA IP

    Modelsim SE 仿真 ALTERA FPGA IP 最近,有几个朋友问过我是不是有新版本的Modelsim altera,其原因是 Qii 升级为新版本的,但是没配套的modelsim,没办法 ...

  9. 安装 SQL SERVER MsiGetProductInfo 无法检索 Product Code 1605错误 解决方案

    重装数据库服务器上的SQL SERVER 2008 上遇到了以下问题 标题: SQL Server 安装程序失败. SQL Server 安装程序遇到以下错误: MsiGetProductInfo 无 ...

  10. 【CF873F】Forbidden Indices 后缀自动机

    [CF873F]Forbidden Indices 题意:给你一个串s,其中一些位置是危险的.定义一个子串的出现次数为:它的所有出现位置中,不是危险位置的个数.求s的所有子串中,长度*出现次数的最大值 ...