概述

Windows 7 支持用户通过手指接触来管理应用程序,无需使用中间设备。这扩展了平板 PC 基于触笔的功能。与其他指针设备不同,这种新功能允许多个输入事件在不同指针位置同时发生,它还支持复杂的场景,比如通过十个手指或多个并发用户来管理应用程序。但是,要实现这些功能,我们必须调整应用程序的用户界面和行为,以支持这种新的输入模型。

Visual Studio 2010 的 MFC 增加了检查多点触控硬件就绪情况的功能,还简化了接收触控事件的流程。

目标

在本次动手实验中,您将学习如何管理多点触控事件,包括:

•              处理 Windows Touch 的输入

•              理解同时操作多个触控事件的含义

•              查看多点触控硬件是否存在及其就绪情况

系统要求

您必须拥有以下工具才能完成本实验:

•             Windows 7

•              Microsoft Visual Studio 2010 Beta 2(或更高版本)

•              多点触控硬件设备

简介

要创建一个多点触控驱动的应用程序,您可以选择以下 3 种方法之一:“好”、“出色”和“最佳”。

“好” 方法是这三种方法中最简单的一种。您应该将触控功能设计到应用程序的用户界面中。使用较大而整洁的基于 Win32 的控件来保证界面的自然,提供更佳的用户体验。滚动之类的触控功能来自 Win32 控件。不需要其他工作。例如,尝试使用手指滚动您现在正在阅读的文档!这是一个“好”方法。

“出色”方法允许系统接收各种低级触控事件,并将系统执行这些事件的启发结果作为“手势”传递给您的应用程序。例如,如果用户在屏幕上进行旋转移动,系统将根据旋转角度发出一个旋转手势事件。尽管“出色”方法很容易使用,但它也存在不足。使用笔势,我们不可能同时进行旋转、平移和缩放。您也不能同时处理多个基于触控的不同动作。例如,两名用户操作窗口的不同区域。

“最佳”方法是读取低级触控事件作为应用程序的输入。“Piano”或多滑块之类可以同时操作的复杂控件就是两个很好的例子。例如,运行 MS Paint,从库中选择绘制工具并使用四个手指进行绘制:

在本手动实验中,您将使用“最佳”方法模拟新的 MS Paint 多点触控绘图功能。我们将读取并使用原始触控事件。

关于 Multitouch Scratchpad 应用程序

Multitouch Scratchpad 应用程序展示了一个简单的窗口,它允许使用手指同时绘制线条。文件夹 Source/MFC_WMTouchSource/Starter 包含练习所需的文件,Source/MFC_WMTouchSource/Final 包含完成的解决方案。

练习 1:构建多点触控应用程序

任务 1 –准备应用程序

1.            启动 Visual Studio 2010

2.            新建一个 MFC 应用程序项目,并将其命名为 ScratchPad:

3.       在 Application Type 中选择 Single Document。为了保持应用程序简单,不选择对话框(如以下屏幕截图所示)中的其他选项:

4.            继续单击 Next 直到单击 Finish:

任务 2 –向应用程序添加触控支持

1.            我们正在构建的应用程序需要支持触控的硬件,因此我们需要在应用程序中查看这一点。

2.            在 Scratchpad.cpp 中,在 CScratchPadApp::InitInstance(): 后添加以下检查代码:

BYTE digitizerStatus = (BYTE) GetSystemMetrics(SM_DIGITIZER);

if ((digitizerStatus & (0x80 + 0x40)) == 0) //Stack Ready + MultiTouch

{

AfxMessageBox(L"No touch input is currently available.");

return false;

}

BYTE nInputs = (BYTE) GetSystemMetrics(SM_MAXIMUMTOUCHES);

CString str;

str.Format(L"Touch input available with %d touch points.", nInputs);

AfxMessageBox(str);

return true;

3.            您可以看到,除了查看触控可用性和就绪情况以外,我们还可以发现硬件支持的触控输入数量。

4.            编译并运行。

5.            根据机器上触控输入的数量,您应该看到类似下图的输出:

6.       为了注册应用程序客户端视图窗口来接收触控消息,我们需要调用 MFC 函数 CWnd::RegisterTouchWindow()。我们将在视图创建之后执行该操作,即在 OnCreate() 事件处理程序中完成。

切换到 Class View 并选择 CChildView 类。

在 Properties 页面中,转到 Message 属性表并导航到 WM_CREATE,然后从下拉框中添加 OnCreate() 消息处理程序:

7.            在 CChildView::OnCreate() 处理程序中添加以下代码,注册视图窗口的触控输入:

if (!RegisterTouchWindow()){
ASSERT(FALSE);}

注意:调用 CWnd::RegisterTouchWindow() 注册(和注销)窗口,使其具有触控功能,允许接收低级 WM_TOUCH 消息。

8.       因为我们注册了视图来接收触控输入,我们必须重写接收每个触控消息的处理程序:CWnd::OnTouchInput()。

该处理程序接收来自 Windows Touch 的单个输入,并在应用程序处理该消息时返回 TRUE;否则返回 FALSE。

9.            在 ChildView.h 中添加该方法声明:

// Overrides
protected:
virtual BOOL OnTouchInput(CPoint pt, int nInputNumber, int nInputsCount, PTOUCHINPUT pInput);

10.          在 ChildView.cpp 中提供相应的实现:

BOOL CChildView::OnTouchInput(CPoint pt, int nInputNumber, int nInputsCount, PTOUCHINPUT pInput)
{
// TODO:Handle Tocuh input messages here
return false;
}

任务 3 –向项目添加笔画源和头文件,并使用手指绘制线条

我们希望将手指作为多输入设备。我们希望为每个触摸屏幕的手指绘制一条线。为此,我们将使用两个笔画集合。一个集合保存完成的笔画(线条),另一个集合保存正在绘制的线条。触摸屏幕的每个手指都指向 m_StrkColDrawing 集合中的笔画。当我们从屏幕拿开手指时,我们将手指的笔画从m_StrkColDrawing 移动到 m_StrkColFinished 集合。此外,如果用户在多点触控监视器上使用两个以上的手指,我们希望笔画有不同的颜色。

1.            在 Starter 文件夹中,您将找到两个文件:Stroke.h 和 Stroke.cpp。将它们复制到项目文件夹下并使用“Add Existing item…”将其添加到项目中。

2.            类似地,向项目添加 StrokeCollection.h 和 StrokeCollection.cpp。

3.            将 "Stroke.h" 和 "StrokeCollection.h" 放在 StdAfx.h 头文件结束处。

#include "Stroke.h"
#include "StrokeCollection.h"

4.            将这些私有成员变量定义添加到 ChildView.h 中:

private:
int m_iCurrColor;                    // The current stroke color
CStrokeCollection m_StrkColFinished; // The user finished entering strokes // after user lifted his or her finger.
CStrokeCollection m_StrkColDrawing;  // The Strokes collection the user is// currently drawing.

5.            重要:我们必须初始化当前颜色。我们将在 ChildView.cpp 的 CChildView 构造函数中完成该操作:

CChildView::CChildView() :m_iCurrColor(0)
{
}

6.            要绘制完成的集合,我们将以下调用添加到 CChildView::OnPaint() 处理程序的末尾。它将绘制所有已完成的笔画。

m_StrkColFinished.Draw(&dc);

7.            我们需要处理所有接收到的触控输入消息,因此我们处理感兴趣的所有事件:touch input down、move 和 up。

8.            在 CChildView.h 中,声明以下方法,我们将用来处理不同的触控输入事件:

protected:// Handlers for different touch input eventsBOOL OnTouchInputDown(CPoint pt, PTOUCHINPUT pInput);BOOL OnTouchInputMove(CPoint pt, PTOUCHINPUT pInput);BOOL OnTouchInputUp(CPoint pt, PTOUCHINPUT pInput);

9.            在 CChildView.cpp 中,添加每个触控输入处理程序的实现:

BOOL CChildView::OnTouchInputDown(CPoint pt, PTOUCHINPUT pInput)
{// Create new stroke and add point to it.COLORREF strokeColor = GetTouchColor((pInput->dwFlags & TOUCHEVENTF_PRIMARY) != 0);CStroke* pStrkNew = new CStroke(pInput->dwID, strokeColor);pStrkNew->Add(pt);// Add new stroke to the collection of strokes in drawing.m_StrkColDrawing.Add(pStrkNew);   return true;
}BOOL CChildView::OnTouchInputMove(CPoint pt, PTOUCHINPUT pInput)
{// Find the stroke in the collection of the strokes in drawing.int strokeIndex = m_StrkColDrawing.FindStrokeById(pInput->dwID);if (strokeIndex >= 0){CStroke* pStrk =  m_StrkColDrawing[strokeIndex];// Add contact point to the strokepStrk->Add(pt);// Draw the last strokepStrk->Draw(GetDC());}return true;
}BOOL CChildView::OnTouchInputUp(CPoint pt, PTOUCHINPUT pInput)
{// Find the stroke in the collection of the strokes in drawing.int strokeIndex = m_StrkColDrawing.FindStrokeById(pInput->dwID);if (strokeIndex >= 0){CStroke* pStrkCopy = m_StrkColDrawing[strokeIndex];// Remove this stroke from the collection of strokes in drawing.m_StrkColDrawing.RemoveAt(strokeIndex);// Add this stroke to the collection of finished strokes.m_StrkColFinished.Add(pStrkCopy);}return true;
}

10.          在 CChildView.cpp 中,修改 CChildView::OnTouchInput() 的实现,以根据需要调用每个触控输入处理程序:

BOOL CChildView::OnTouchInput(CPoint pt, int nInputNumber, int nInputsCount, PTOUCHINPUT pInput)
{    if ((pInput->dwFlags & TOUCHEVENTF_DOWN) == TOUCHEVENTF_DOWN) // Touch Down event{return OnTouchInputDown(pt, pInput);}else if ((pInput->dwFlags & TOUCHEVENTF_MOVE) == TOUCHEVENTF_MOVE) // Touch Move event{return OnTouchInputMove(pt, pInput);}else if ((pInput->dwFlags & TOUCHEVENTF_UP) == TOUCHEVENTF_UP) // Touch Move event{return OnTouchInputUp(pt, pInput);}return false;
}

11.          注意,调用了 GetTouchColor() 方法,但它尚未实现。当用户移动应用程序窗口上的多个手指时,该方法负责处理钢笔的颜色。在 CChildView.h 中添加该方法的声明:

private:
COLORREF GetTouchColor(bool bPrimaryContact);

12.          以下是 CChildView.cpp 的实现:

COLORREF CChildView::GetTouchColor(bool bPrimaryContact)
{
static COLORREF c_arrColor[] =  // Secondary colors array{
RGB(255, 0, 0),             // Red
RGB(0, 255, 0),             // Green
RGB(0, 0, 255),             // Blue
RGB(0, 255, 255),           // Cyan
RGB(255, 0, 255),           // Magenta
RGB(255, 255, 0)            // Yellow};COLORREF color;
if (bPrimaryContact){
// The primary contact is drawn in black.
color = RGB(0,0,0);         // Black}
else{
// Take current secondary color.
color = c_arrColor[m_iCurrColor];// Move to the next color in the array.
m_iCurrColor = (m_iCurrColor + 1) % (sizeof(c_arrColor)/sizeof(c_arrColor[0]));}return color;
}

13.          最后,由于我们已经动态创建了许多笔画,我们需要确保每个笔画在应用程序退出之前都被销毁,因此我们在 CChildView‘ 的析构函数中包含以下内容:

CChildView::~CChildView()
{for (int i = 0; i < m_StrkColDrawing.GetCount(); ++i){delete m_StrkColDrawing[i];}for (int i = 0; i < m_StrkColFinished.GetCount(); ++i){delete m_StrkColFinished[i];}
}

14.          现在编码部分已经全部完成,可以开始实验刚才实现的应用程序了。

15.          编译并运行应用程序。它应该如下所示:

总结

在本实验中,您学习了如何在 MFC 应用程序中处理触控输入。您学习了如何测试多点触控硬件是否存在,以及如何配置窗口来接收触控输入。同样,您还看到了如何从消息中提取输入,以及系统如何关联触控 id 与触控输入。

多点触控 - MFC相关推荐

  1. 基于Visual C++ 2010开发Windows7应用 开发多点触控MFC应用程序

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 当下计算 ...

  2. Android多点触控详解

    本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...

  3. 基于windows7的usb多点触控设备

    前段时间,朋友要做一个windows7的usb多点触控设备,我就帮了个小忙,负责搞定了设备 与PC通信相关的这块.整个项目我做了两个东西,一是下位机的usb设备描述符,一个是上位机的测试软件,下面我会 ...

  4. android怎么监听多点触摸_什么是多点触控技术,有哪些用途

    自从乔布斯将触控技术用于苹果手机上,很多的手机厂商纷纷效仿,触控技术几乎成为手机的"标配".其实,触控技术早就存在,只是一直未能大面积用于各种设备中,本文将带您认识神奇的触控技术. ...

  5. Android 多点触控 MotionEvent详解

    相关API 介绍 MotionEvent.getY() 和 MotionEvent.getRawY() 的区别 getY 表示触摸事件在当前的View内的Y 坐标, getRawY表示触摸事件在整个屏 ...

  6. 【Android 应用开发】多点触控 ( 多点触控事件 | PointerId | PointerIndex | 坐标获取 | 触摸点个数 )

    文章目录 I . 多点触控事件 II . PointerId 与 PointerIndex 简介 III . 本次 PointerId 与 PointerIndex 获取 IV . PointerId ...

  7. Windows Phone 7范例游戏Platformer实战5——多点触控编程

    即使是再有经验的XNA程序员,在开始Windows Phone 7上的游戏开发时也不得不学习下多点触控这个新的实现方法.虽然目前有些Windows Phone 7手机附带了键盘,但是为了对所有WP7手 ...

  8. android 关闭多点触控_Cocos Creator关闭多点触摸的问题

    一. 方案一:改写Node的派发事件 方法:改写node的派发事件,当有多个响应的时候不去进行dispatch. 在游戏开启的时候把node原来的方法: cc.Node.prototype.dispa ...

  9. Android多点触控MultiTouch浅析

    申明: 参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0226/914.html 下面实现如何通过应用层支持多点触控操作, ...

最新文章

  1. 342.基于高通量技术的微生物组研究实验设计
  2. 当超级智能崛起时……
  3. 信号通路怎么读_奥利给~~代谢通路富集分析原来还可以这么做?
  4. CHM文件显示目录无法显示内容的解决方案
  5. 华为:跨过时艰,向未来
  6. 快报:Python 被爆重大“黑料”!程序员:劲爆!
  7. Makefile 函数
  8. 数学_一文搞懂极大似然估计
  9. 如何使用Java进行网络爬虫
  10. OpenCV-camShift 算法
  11. 计算机软件 退货,如何在在电脑收银系统中实现商品退货
  12. jquery的blockUI遮罩层的使用
  13. RS-485半双工延时问题
  14. PHP爬虫遇到incapsula
  15. 练字格子纸模板pdf_十字田字格模板空格40格-练字用书十字格a4打印版下载最新excel版-西西软件下载...
  16. “Bluetooth keeps stopping“
  17. 云耀服务器切换系统,云耀云服务器切换操作系统
  18. SSM电影点播系统02-数据字典
  19. 计算机基础知识判断题答案,计算机基础知识试题及答案判断题
  20. 推荐几款不错的企业站点,前端设计师寻求设计灵感!

热门文章

  1. 【WEB】HTML标签自带属性title样式修改
  2. 2022张宇考研基础30讲 第十五讲 数一数二专题
  3. 广州租房提取住房公积金攻略
  4. 国产数据库岁末大盘点
  5. 鸿蒙系统与nblot,华为:今年不会推出鸿蒙系统手机,除非谷歌彻底禁止华为使用安卓...
  6. Certificate Vending Machine – Amazon IoT 设备接入 Amazon IoT 平台解决方案
  7. Nginx--secure_link和geoip_module
  8. Redis分布式中间件TwemProxy
  9. 英语学习-索贝斯演讲学习摘要
  10. 怎么重装电脑系统,小熊一键重装电脑系统教程