分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
PS:如果提示WM_TOUCH未定义,那么可以考虑使用消息WM_TOUCHMOVE代替。
另关于消息WM_TOUCHDOWN、WM_TOUCHUP两个消息,Windows7操作系统目前只是作了定义,但未响应...
#ifndef WM_TOUCH // 自定义多点触摸消息
#define WM_TOUCH 0x0240
#endif
来自: http://www.cnblogs.com/yds_amber/articles/1730808.html
一、体系概述
1.Windows Touch Input 和 Gestures消息
Windows Touch消息特性 通过在执行期间的监听和解释来使能。下面的示例展示了Windows7 上消息是怎么从硬件产生并发给应用程序的。
在最左边的那列,touch-sensitive 设备接收用户输入,驱动程序沟通硬件和操作系统,接下来,操作系统产生WM_TOUCH或者WM_GESTURE消息,进而发送给应用程序句柄,然后应用程序通过消息中封装的信息更新UI。
默认情况下应用程序受到的是gesture消息,除非应用程序中通过RegisterTouchWindow函数注册touch输入消息。这样,WM_TOUCH消息就会被发送到这个应用程序窗口。Touch和Gesture消息是“贪婪的”,一旦一个touch消息或者Gesture在应用程序上产生了,所有的消息都会被发送到给窗口中,除非gesture或touch完成。
Windows解释WM_GESTURE消息然后SEND或POST合适的映射到gesture的消息,为了不会造成内存泄漏,确保你没处理的WM_GESTURE消息被DefWindowProc处理。
2.操作和惯性
Windows touch程序员必须能够解释多种来源的手势消息,Microsoft提供操作API去处理这些计算。当您连接到输入数据的操纵处理器,你可以获得用户在对象上做的动作信息,下图显示的一种你可以使用的操作方法。
左上角,用户touch屏幕,屏幕创建touch消息,这些消息包含x和y位置,这个位置被用来决定这个Object in Focus,Object in Focus包含一个操作处理器,接下来,带有TOUCHEVENTF_UP标志的WM_TOUCH消息,选中用户的Object in Focus,引用操作处理器,然后把消息发送到操作处理器,然后和本次触摸关联的WM_TOUCH消息被发送到引用处理器直到TOUCHEVENTF_UP标志被收到,被选择的焦点对象被解引用。上图中的右下角,一个实现了_IManipulationEvents接口的处理事件接收器被用来处理事件,当touch消息被创建时它被加载,这个事件接收器。在windows Touch应用程序中,聚合简单的物理原理使得对象很自然得表现stop,而不是不再被触摸时马上stop,Microsoft提供了惯性API去计算来表现这些简单的物理现象,这样也省去了你要建立这些物理特性的努力,下图显示了如何使用惯性。
你可以注意到惯性和操作之间的相似性,两者唯一的不同是在惯性的情况下,消息被投递到惯性处理器而不是操作处理器,惯性处理器产生事件,touch消息被用来标志一个object in focus 这个object in focus 包含惯性处理器和操作处理器,接下来的WM_TOUCH消息被发送到操作处理器,这个操作处理器来完成应用程序UI的更新,操作完成后,来自于这个操作的向量被用来建立一个惯性处理器,IInertiaProcessor接口的Process和ProcessTime (上图)方法被调用使用一个时间或者其他单独线程的循环知道这些调用表示处理器完成了处理。当这些调用被执行时,操作事件被产生,被基于_IManipulationEvents接口的事件接收器处理。事件接收器来表现这些操作事件所要表现的界面更新。
3.选择正确的途径来响应windows Touch
这个部分解释了你可以使用的处理Windows Touch的不同途径。
你可以通过使用Windows Touch特性来增强你的应用程序,在你做之前你应该明确你想要怎么编写你的应用程序。下面场景就是使用Windows Touch 的典型场景。
l 你想要你的应用程序表现的和在旧版本的windows中一样,但是希望windows touch 消息的行为不变
l 你想要程序中的自定义的对象支持rotation, translation, panning, or zoom 操作。
l 你想要你的应用程序解释windows Touch手势或者解释多点触摸。
l 你有个使用RealTimeStylus对象的应用程序,你想要使它支持windows touch 能力。
第一种情况:
在windows7中,有Windows Touch 特性的情况下,应用程序默认的情况下会产生Touch消息。例如pan 手势会触发WM_*SCROLL消息,除了pan支持,Windows7中的默认WM_GESTURE句柄,支持边界反馈, zoom, and press and tap,边界反馈一直是使能的也是传统的支持,开发者想要这个基本的功能的话不需要直接用Windwos Touch API
注意:Custom Scroll bar句柄必须支持SM_THUMBPOSITION 因为WM_VSCROLL需要这个支持,也必须支持SB_LINELEFT和SB_LINERIGHT 因为WM_HSCROLL需要这个支持。
第二种情况:
如果你想要支持有限的touch,但是windows7默认提供的不足以满足你的程序的需要,你可以使用 gestures 来增强你的程序的功能。通过使用gestures,你可以通过处理WM_GESTURE消息来解释gestures command在Windows Touch Gestures中可以找到更多的相关信息。如果你的应用程序只需要支持 高质量的旋转,zooming,单指panning。gestures是最合适不过的了。除了解释gesture消息,你可以选择性地支持边界反馈,如果你想要了解更多的边界反馈的东西,请阅读BoundaryFeedBack 那部分,在Windows7中,命令提示符和IE利用了边界反馈和gestures。
第三种情况:
如果你想要更具体的控制手势而不是像WM_GESTURE消息那样,或者你想要去解释多个对象的多次手势,你应该使用这个manipulation processor(操作处理器),操纵处理器基本上是一个超手势,使用操作处理器需要你实现一个(event sink)事件接收器来处理原始的触摸数据。
如果除了解释手势,你还想要简单的物理现象,你应该把inertia processor(惯性处理器)和操作处理器关联起来,惯性处理器和操作处理器协同工作,通过采集来自于操作处理器的操作完成时的速度值。
如果你的应用程序想要解释多点触摸消息,你应该创建一个WM_TOUCH的句柄。
windows Touch input部分的内容解释了你如何去解析一个WM_TOUCH消息。
Detecting and Tracking Multiple Touch Points部分的内容演示了如何去创建一个解析多点触摸的例子程序。
Manipulations and Inertia部分解释了如何去使能windows touch 的最灵活的方式。
第四种情况:
如果你想要使能Tablet PC 平台的多点触摸,你必须实现一个自定义的RealTimeStylus plug-in 来解析windows Touch数据。Microsoft介绍了ITablet3和IRealTimeStylus3接口去使能来自于RealTimeStylus plug-in的多点触摸数据。这些接口很简单地扩展了RealTimeStylus plug-in来支持多点触摸。
为了检查是否支持多点触摸,调用IsMultiTouch.为了检查支持的触摸数量,调用GetMaximumCursors,为了使能或者无效多点触摸,调用MultiTouchEnabled。
注意:如果你在RealTimeStylus中不使能多点触摸,你会收到普通的gesture消息,例如pan 或者zoom
二、Troubleshooting Applications疑难解答
一般疑难问题
1、问题:我使用OS是windows server 2008 ,windows touch 特性不工作?
原因:没有使能Desktop Experience。
解决方案:打开Server Manager administrative tool: 单击Start,指向Adiministrative tools,然后单击Server Manager,单击左侧的Features,单击Features 在 Features部分,选择Desktop Experience 单击Next,单击Install。
2、问题:无论我怎么在应用程序上快速地移动我的手指,一个arrow出现,我的手势或操作都不能正确的注册。
原因:当你不需要的时候,使能flicks。
解决方案:当你想要fllicks无效的时候,你应该无效它,看Legacy support for panning with scrollbars这部分获得更多的信息去无效pen flicks。
3、问题:我不能辨别鼠标的单击和windows touch 输入
原因:windows产生鼠标消息为了支持用户clicks在屏幕上的时候
解决方案:可以调用GetMessageExtraInfo来获取消息来源,看下面的代码
4、问题:我怎么才能运行Surface Applications 在windows7上?
原因:windows touch 和Microsoft surface是不兼容的
解决方案:你既需要target windos7平台,也需要target Microsoft Surface平台
Manipulations 和惯性疑难问题
1、问题:我的应用程序不知道什么原因无响应了,当我初始化我的对象接口的时候得到了访问违规的提示
原因:没有为IManipulationProcessor和IInertiaProcessor接口调用CoInitialize
解决方案:这个原因可能是因为没有为windows touch的com对象调用com初始化函数,当你从使用手势的工程转换成使用manipulations or inertia接口的工程时可能会出现这种情况。
2、问题:我的对象不能正常地旋转,单指旋转不工作。
原因:你在这个对象上设置的枢轴不合适。
解决方案:你没有正确地设置枢轴点,设置PivotPointX 和PivotPointY属性作为旋转的中心点,设置PivotRadius属性为对象的半径。
原因:不处理WM_TOUCH消息
解决方案:你可能consuming一个windows touch消息但是没有把它交给DefWindowProc处理,这个会导致不希望的行为,看一下Getting Started with Windows Touch Messages获取更多的信息关于如何合适地处理WM_TOUCH消息。
2、问题:我包含了windows.h文件,为什么报错说WM_TOUCH没定义?
原因:targetver.h中的windows的版本不正确
解决方法:你没有设置正确的windows 版本,下面的代码教你为windows touch设置正确的windows 版本(在targetver.h头文件中)
如果windows.h的版本是正确的,那么使用:
3、问题:我的touch输入的x和y坐标的值不对,有时比期望的大,有时又是负值?
原因:你可能需要把你的touch点转成像素表示,或者你需要转成你的屏幕坐标
解决方法:确保你调用了TOUCH_COORD_TO_PIXEL 和ScreenToClient
4、问题:我收不到WM_TOUCH消息,但是收到了WM_GESTURE消息
原因:没有调用RegisterTouchWindow消息
解决方案:WM_TOUCH和WM_GESTURE消息是互斥的,调用RegisterTouchWindow后就会收到WM_TOUCH消息,否则收到WM_GESTURE消息。
5、问题:在我touch的时候到我的程序收到消息中间有一小段延迟?
原因:平台排斥的关系
解决方案:如果调用RegisterTouchWindow的时候TWF_WANTPALM被设置了,就会使能平台排斥反映,这个就会导致软件探测输入是来自于手指,笔还是用户的平台从而产生大约100ms的延迟,通过调用RegisterTouchWindow的时候设置TWF_WANTPLAM标志就可以无效平台排斥反映。
Windows Touch Gestures疑难问题
1、问题:处理完WM_GESTURE消息后,没有boundary feedback
原因:截获了 WM_GESTURE消息儿没处理它
解决:你可能截获了一个WM_GESTURE消息但是没有处理它也没有交给DefWindowProc处理,这个就可能导致不被期望的行为,看Getting Started with Windows Gestures获得更多的信息去弄明白怎么合适地处理WM_GESTURE消息。
2、问题:我没有看到我所期望的所有的gestures消息,例如,我看到了GID_PAN但是没有GID_ROTATE消息
原因:有些手势,默认的情况下是没有使能的
解决:当收到WM_GESTURENOTIFY消息时需要调用SetGestureConfig来设置,下面的代码演示了如何实现WM_GESTURENOTIFY消息。
3、问题:自定义的scroll bar不能scrolling 当我用pan gesture的时候
原因:没有处理WM_*SCROLL消息
解决:在你的自定义scrollbar中没有处理全部的WM_*SCROLL消息,推荐的行为是,当你处理WM_GESTURE消息而不是通过以往的支持保持自定义scrollbar的功能,更详细的信息看Legacy Support for Panning with Scroll bars
4、问题:我的gestures有延迟
原因:flicks可能会导致延迟
解决:看Legacy Support for Panning with Scrollbars 来明白如何去disable flicks
三、Windows Touch Input
1.Getting Started with windows touch messages
下面的步骤解释了怎么处理windows touch 消息
l 测试输入设备的能力
l 注册接收touch消息的窗口
l 处理touch消息
第一步:测试设备能力
检测硬件是否支持触摸
TABLE_CONFIG_NONE 0x00000000 输入设备没有触摸能力
NID_INTEGRATED_TOUCH 0x00000001 集成的input digitizer
NID_EXTERNAL_TOUCH 0x00000002 扩展的touch digitizer
NID_INTEGRATED_PEN 0x00000004 集成的pen digitizer
NID_EXTERNAL_PEN 0x00000008 扩展的pen digitizer
NID_MULTI_INPUT 0x00000040 支持多点触摸
WM_TOUCH消息是“贪婪的”第一个消息被一个窗口接收到以后,在另一个窗口获得焦点前,所有的touch消息都会被发送到该窗口。
默认的情况下,应用程序会收到WM_GESTURE消息而不是WM_TOUCH消息,如果调用了RegisterTouchWindow函数,就会阻止WM_GESTURE消息而收到WM_TOUCH消息。
第三步:处理touch消息
下面列举一个Win32程序
退出时调用UnRegisterTouchWindow函数。
下面的例子是一个MFC的例子
当你开始收到touch消息后,你可以把这个消息转换成touch input结构体来表现更有意思的操作,下面的代码显示了如何转换这些信息。
另关于消息WM_TOUCHDOWN、WM_TOUCHUP两个消息,Windows7操作系统目前只是作了定义,但未响应...
#ifndef WM_TOUCH // 自定义多点触摸消息
#define WM_TOUCH 0x0240
#endif
来自: http://www.cnblogs.com/yds_amber/articles/1730808.html
一、体系概述
1.Windows Touch Input 和 Gestures消息
Windows Touch消息特性 通过在执行期间的监听和解释来使能。下面的示例展示了Windows7 上消息是怎么从硬件产生并发给应用程序的。
在最左边的那列,touch-sensitive 设备接收用户输入,驱动程序沟通硬件和操作系统,接下来,操作系统产生WM_TOUCH或者WM_GESTURE消息,进而发送给应用程序句柄,然后应用程序通过消息中封装的信息更新UI。
默认情况下应用程序受到的是gesture消息,除非应用程序中通过RegisterTouchWindow函数注册touch输入消息。这样,WM_TOUCH消息就会被发送到这个应用程序窗口。Touch和Gesture消息是“贪婪的”,一旦一个touch消息或者Gesture在应用程序上产生了,所有的消息都会被发送到给窗口中,除非gesture或touch完成。
Windows解释WM_GESTURE消息然后SEND或POST合适的映射到gesture的消息,为了不会造成内存泄漏,确保你没处理的WM_GESTURE消息被DefWindowProc处理。
2.操作和惯性
Windows touch程序员必须能够解释多种来源的手势消息,Microsoft提供操作API去处理这些计算。当您连接到输入数据的操纵处理器,你可以获得用户在对象上做的动作信息,下图显示的一种你可以使用的操作方法。
左上角,用户touch屏幕,屏幕创建touch消息,这些消息包含x和y位置,这个位置被用来决定这个Object in Focus,Object in Focus包含一个操作处理器,接下来,带有TOUCHEVENTF_UP标志的WM_TOUCH消息,选中用户的Object in Focus,引用操作处理器,然后把消息发送到操作处理器,然后和本次触摸关联的WM_TOUCH消息被发送到引用处理器直到TOUCHEVENTF_UP标志被收到,被选择的焦点对象被解引用。上图中的右下角,一个实现了_IManipulationEvents接口的处理事件接收器被用来处理事件,当touch消息被创建时它被加载,这个事件接收器。在windows Touch应用程序中,聚合简单的物理原理使得对象很自然得表现stop,而不是不再被触摸时马上stop,Microsoft提供了惯性API去计算来表现这些简单的物理现象,这样也省去了你要建立这些物理特性的努力,下图显示了如何使用惯性。
你可以注意到惯性和操作之间的相似性,两者唯一的不同是在惯性的情况下,消息被投递到惯性处理器而不是操作处理器,惯性处理器产生事件,touch消息被用来标志一个object in focus 这个object in focus 包含惯性处理器和操作处理器,接下来的WM_TOUCH消息被发送到操作处理器,这个操作处理器来完成应用程序UI的更新,操作完成后,来自于这个操作的向量被用来建立一个惯性处理器,IInertiaProcessor接口的Process和ProcessTime (上图)方法被调用使用一个时间或者其他单独线程的循环知道这些调用表示处理器完成了处理。当这些调用被执行时,操作事件被产生,被基于_IManipulationEvents接口的事件接收器处理。事件接收器来表现这些操作事件所要表现的界面更新。
3.选择正确的途径来响应windows Touch
这个部分解释了你可以使用的处理Windows Touch的不同途径。
你可以通过使用Windows Touch特性来增强你的应用程序,在你做之前你应该明确你想要怎么编写你的应用程序。下面场景就是使用Windows Touch 的典型场景。
l 你想要你的应用程序表现的和在旧版本的windows中一样,但是希望windows touch 消息的行为不变
l 你想要程序中的自定义的对象支持rotation, translation, panning, or zoom 操作。
l 你想要你的应用程序解释windows Touch手势或者解释多点触摸。
l 你有个使用RealTimeStylus对象的应用程序,你想要使它支持windows touch 能力。
第一种情况:
在windows7中,有Windows Touch 特性的情况下,应用程序默认的情况下会产生Touch消息。例如pan 手势会触发WM_*SCROLL消息,除了pan支持,Windows7中的默认WM_GESTURE句柄,支持边界反馈, zoom, and press and tap,边界反馈一直是使能的也是传统的支持,开发者想要这个基本的功能的话不需要直接用Windwos Touch API
注意:Custom Scroll bar句柄必须支持SM_THUMBPOSITION 因为WM_VSCROLL需要这个支持,也必须支持SB_LINELEFT和SB_LINERIGHT 因为WM_HSCROLL需要这个支持。
第二种情况:
如果你想要支持有限的touch,但是windows7默认提供的不足以满足你的程序的需要,你可以使用 gestures 来增强你的程序的功能。通过使用gestures,你可以通过处理WM_GESTURE消息来解释gestures command在Windows Touch Gestures中可以找到更多的相关信息。如果你的应用程序只需要支持 高质量的旋转,zooming,单指panning。gestures是最合适不过的了。除了解释gesture消息,你可以选择性地支持边界反馈,如果你想要了解更多的边界反馈的东西,请阅读BoundaryFeedBack 那部分,在Windows7中,命令提示符和IE利用了边界反馈和gestures。
第三种情况:
如果你想要更具体的控制手势而不是像WM_GESTURE消息那样,或者你想要去解释多个对象的多次手势,你应该使用这个manipulation processor(操作处理器),操纵处理器基本上是一个超手势,使用操作处理器需要你实现一个(event sink)事件接收器来处理原始的触摸数据。
如果除了解释手势,你还想要简单的物理现象,你应该把inertia processor(惯性处理器)和操作处理器关联起来,惯性处理器和操作处理器协同工作,通过采集来自于操作处理器的操作完成时的速度值。
如果你的应用程序想要解释多点触摸消息,你应该创建一个WM_TOUCH的句柄。
windows Touch input部分的内容解释了你如何去解析一个WM_TOUCH消息。
Detecting and Tracking Multiple Touch Points部分的内容演示了如何去创建一个解析多点触摸的例子程序。
Manipulations and Inertia部分解释了如何去使能windows touch 的最灵活的方式。
第四种情况:
如果你想要使能Tablet PC 平台的多点触摸,你必须实现一个自定义的RealTimeStylus plug-in 来解析windows Touch数据。Microsoft介绍了ITablet3和IRealTimeStylus3接口去使能来自于RealTimeStylus plug-in的多点触摸数据。这些接口很简单地扩展了RealTimeStylus plug-in来支持多点触摸。
为了检查是否支持多点触摸,调用IsMultiTouch.为了检查支持的触摸数量,调用GetMaximumCursors,为了使能或者无效多点触摸,调用MultiTouchEnabled。
注意:如果你在RealTimeStylus中不使能多点触摸,你会收到普通的gesture消息,例如pan 或者zoom
二、Troubleshooting Applications疑难解答
一般疑难问题
1、问题:我使用OS是windows server 2008 ,windows touch 特性不工作?
原因:没有使能Desktop Experience。
解决方案:打开Server Manager administrative tool: 单击Start,指向Adiministrative tools,然后单击Server Manager,单击左侧的Features,单击Features 在 Features部分,选择Desktop Experience 单击Next,单击Install。
2、问题:无论我怎么在应用程序上快速地移动我的手指,一个arrow出现,我的手势或操作都不能正确的注册。
原因:当你不需要的时候,使能flicks。
解决方案:当你想要fllicks无效的时候,你应该无效它,看Legacy support for panning with scrollbars这部分获得更多的信息去无效pen flicks。
3、问题:我不能辨别鼠标的单击和windows touch 输入
原因:windows产生鼠标消息为了支持用户clicks在屏幕上的时候
解决方案:可以调用GetMessageExtraInfo来获取消息来源,看下面的代码
#define MOUSEEVENTF_FROMTOUCH 0xFF515700if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) { // Click was generated by wisptis / Windows Touch}else{ // Click was generated by the mouse.}
4、问题:我怎么才能运行Surface Applications 在windows7上?
原因:windows touch 和Microsoft surface是不兼容的
解决方案:你既需要target windos7平台,也需要target Microsoft Surface平台
Manipulations 和惯性疑难问题
1、问题:我的应用程序不知道什么原因无响应了,当我初始化我的对象接口的时候得到了访问违规的提示
原因:没有为IManipulationProcessor和IInertiaProcessor接口调用CoInitialize
解决方案:这个原因可能是因为没有为windows touch的com对象调用com初始化函数,当你从使用手势的工程转换成使用manipulations or inertia接口的工程时可能会出现这种情况。
2、问题:我的对象不能正常地旋转,单指旋转不工作。
原因:你在这个对象上设置的枢轴不合适。
解决方案:你没有正确地设置枢轴点,设置PivotPointX 和PivotPointY属性作为旋转的中心点,设置PivotRadius属性为对象的半径。
Windows Touch Input的疑难问题
1、问题:我处理WM_TOUCH消息后,没有得到boundary feedback(边界反馈)原因:不处理WM_TOUCH消息
解决方案:你可能consuming一个windows touch消息但是没有把它交给DefWindowProc处理,这个会导致不希望的行为,看一下Getting Started with Windows Touch Messages获取更多的信息关于如何合适地处理WM_TOUCH消息。
2、问题:我包含了windows.h文件,为什么报错说WM_TOUCH没定义?
原因:targetver.h中的windows的版本不正确
解决方法:你没有设置正确的windows 版本,下面的代码教你为windows touch设置正确的windows 版本(在targetver.h头文件中)
#ifndef WINVER // Specify that the minimum required platform is Windows 7.#define WINVER 0x0601 #endif
如果windows.h的版本是正确的,那么使用:
#ifndef WM_TOUCH #define WM_TOUCH 0x0240 // 自定义多点触摸消息:来自MSDN#endif
3、问题:我的touch输入的x和y坐标的值不对,有时比期望的大,有时又是负值?
原因:你可能需要把你的touch点转成像素表示,或者你需要转成你的屏幕坐标
解决方法:确保你调用了TOUCH_COORD_TO_PIXEL 和ScreenToClient
POINT ptInput;if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))){ for (int i=0; i < static_cast<INT>(cInputs); i++) { TOUCHINPUT ti = pInputs[i]; if (ti.dwID != 0) { // Do something with your touch input handle. ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x); ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y); ScreenToClient(hWnd, &ptInput); points[ti.dwID][0] = ptInput.x; points[ti.dwID][1] = ptInput.y; } }}
4、问题:我收不到WM_TOUCH消息,但是收到了WM_GESTURE消息
原因:没有调用RegisterTouchWindow消息
解决方案:WM_TOUCH和WM_GESTURE消息是互斥的,调用RegisterTouchWindow后就会收到WM_TOUCH消息,否则收到WM_GESTURE消息。
5、问题:在我touch的时候到我的程序收到消息中间有一小段延迟?
原因:平台排斥的关系
解决方案:如果调用RegisterTouchWindow的时候TWF_WANTPALM被设置了,就会使能平台排斥反映,这个就会导致软件探测输入是来自于手指,笔还是用户的平台从而产生大约100ms的延迟,通过调用RegisterTouchWindow的时候设置TWF_WANTPLAM标志就可以无效平台排斥反映。
Windows Touch Gestures疑难问题
1、问题:处理完WM_GESTURE消息后,没有boundary feedback
原因:截获了 WM_GESTURE消息儿没处理它
解决:你可能截获了一个WM_GESTURE消息但是没有处理它也没有交给DefWindowProc处理,这个就可能导致不被期望的行为,看Getting Started with Windows Gestures获得更多的信息去弄明白怎么合适地处理WM_GESTURE消息。
2、问题:我没有看到我所期望的所有的gestures消息,例如,我看到了GID_PAN但是没有GID_ROTATE消息
原因:有些手势,默认的情况下是没有使能的
解决:当收到WM_GESTURENOTIFY消息时需要调用SetGestureConfig来设置,下面的代码演示了如何实现WM_GESTURENOTIFY消息。
// The message map.BEGIN_MESSAGE_MAP() ON_WM_CREATE() ... ... ... ON_MESSAGE(WM_GESTURENOTIFY, OnWindowsGestureNotify)END_MESSAGE_MAP() LRESULT CTestWndApp::OnWindowsGestureNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){ GESTURECONFIG gc; gc.dwID = GID_ROTATE; // The gesture identifier. gc.dwWant = GC_ROTATE; // The gesture command you are enabling for GID_ROTATE. gc.dwBlock = 0; // Don't block anything. UINT uiGcs = 1; // The number of gestures being set. BOOL bResult = SetGestureConfig(g_hMainWnd, 0, uiGcs, &gc, sizeof(GESTURECONFIG)); if(!bResult) { // Something went wrong, report the error using your preferred logging. } return 0;}
3、问题:自定义的scroll bar不能scrolling 当我用pan gesture的时候
原因:没有处理WM_*SCROLL消息
解决:在你的自定义scrollbar中没有处理全部的WM_*SCROLL消息,推荐的行为是,当你处理WM_GESTURE消息而不是通过以往的支持保持自定义scrollbar的功能,更详细的信息看Legacy Support for Panning with Scroll bars
4、问题:我的gestures有延迟
原因:flicks可能会导致延迟
解决:看Legacy Support for Panning with Scrollbars 来明白如何去disable flicks
三、Windows Touch Input
1.Getting Started with windows touch messages
下面的步骤解释了怎么处理windows touch 消息
l 测试输入设备的能力
l 注册接收touch消息的窗口
l 处理touch消息
第一步:测试设备能力
检测硬件是否支持触摸
int value = GetSystemMetrics( SM_DIGITIZER )if ( value & NID_MULTI_INPUT ){ // 设备支持触摸操作}
Name Value Description
TABLE_CONFIG_NONE 0x00000000 输入设备没有触摸能力
NID_INTEGRATED_TOUCH 0x00000001 集成的input digitizer
NID_EXTERNAL_TOUCH 0x00000002 扩展的touch digitizer
NID_INTEGRATED_PEN 0x00000004 集成的pen digitizer
NID_EXTERNAL_PEN 0x00000008 扩展的pen digitizer
NID_MULTI_INPUT 0x00000040 支持多点触摸
NID_READY 0x00000080 输入设备准备好输入了
检查NID_* 值是一种很有效的检查用户的设备支持touch pen or no-table input的能力。例如,如果你有一个动态的UI,想要动态地配置一些东西,你可以检查NID_INTEGRATED_TOUCH,NID_MULTITOUCH,在用户第一次运行你的应用程序的时候获得最小的上表中的值。
对于SM_GETSYSTEMMETRICS 有一些固有的限制,不支持即插即用,当用这个函数的时候应该注意这一点。
第二步:注册touch窗口
应用程序必须先注册才能收到多点触摸消息,通过函数RegisterTouchWindow函数,退出时必须卸载,通过函数UnRegisterTouchWindow函数。WM_TOUCH消息是“贪婪的”第一个消息被一个窗口接收到以后,在另一个窗口获得焦点前,所有的touch消息都会被发送到该窗口。
默认的情况下,应用程序会收到WM_GESTURE消息而不是WM_TOUCH消息,如果调用了RegisterTouchWindow函数,就会阻止WM_GESTURE消息而收到WM_TOUCH消息。
第三步:处理touch消息
下面列举一个Win32程序
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } RegisterTouchWindow(hWnd, 0); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_TOUCH: ...... // you can either pass this to DefWindowProc or can handle it yourself DefWindowProc(hWnd, message, wParam, lParam); break; }}
退出时调用UnRegisterTouchWindow函数。
下面的例子是一个MFC的例子
// Class implementations within a dialogLRESULT TestDlg::OnTouch( WPARAM wParam, LPARAM lParam ){ //Insert handler code here to do something with the message or uncomment the following line to test //MessageBox(L"touch!", L"touch!", MB_OK); return 0;}// The message mapBEGIN_MESSAGE_MAP() ON_WM_CREATE() ... ... ... ON_MESSAGE(WM_TOUCH, OnTouch)END_MESSAGE_MAP() BOOL TestDlg::OnInitDialog(){ CDialog::OnInitDialog(); RegisterTouchWindow(m_hWnd, 0); ... ... ...}
当你开始收到touch消息后,你可以把这个消息转换成touch input结构体来表现更有意思的操作,下面的代码显示了如何转换这些信息。
LRESULT OnTouchHandled