您的位置:首页 > 其它

基于MFC对话框的图片触摸控制

2017-07-31 10:35 676 查看

基于MFC对话框的图片触摸控制

最近项目需要用到触摸屏来实现人机交互,简单描述一下就是用户触摸一下客户端的图片控件中的图片元素,系统给出相应响应。查找了一下资料发现有不少基于MFC的触摸屏实现,其中写得比较好的有Augusdi的博文多点触控 - MFC。下面结合我个人的理解,简单说说触摸的实现。

触摸实现简要分析

触摸主要分为三个步骤,即为查询设备是否支持触摸输入(确认支持的情况下可以省略此步骤)、注册触摸输入响应事件、接收触摸事件。下面分别给出这三个步骤的实现

1、查询设备是否支持触摸输入

要实现触摸控制,首先你得有个触摸输入装置,也就是说你的屏幕得支持多点触摸。用下面的方法可以查询你硬件的触摸支持情况:

BYTE digitizerStatus = (BYTE)GetSystemMetrics(SM_DIGITIZER);
if ((digitizerStatus & (0x80 + 0x40)) == 0) //堆栈就绪+多触点
{
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;


官方文档给出的GetSystemMetrics函数说明如下:

GetSystemMetrics function

Retrieves the specified system metric or system configuration setting.

Note that all dimensions retrieved by GetSystemMetrics are in pixels.

2、注册触摸输入

在MFC中是没有触摸输入事件的,因此我们要注册个触摸输入事件。注册用RegisterTouchWindow函数实现即可:

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


注意:RegisterTouchWindow函数有两个版本,一个是系统自带的RegisterTouchWindow,其定义如下

BOOL WINAPI RegisterTouchWindow(
_In_ HWND  hWnd,
_In_ ULONG ulFlags
);


hWnd是窗口句柄,它可以注册指定的窗口接收触摸事件。

另一个是CWnd窗口类实现的CWnd::RegisterTouchWindow函数,用于注册当前窗口。

BOOL RegisterTouchWindow(
BOOL bRegister = TRUE,
ULONG ulFlags = 0
);


3、接收触摸事件

注册了触摸事件后,所有的触摸消息都会默认传入到OnTouchInput函数中,因此我们在OnTouchInput函数中处理触摸消息即可。这里我们将触摸事件分为触摸按下,移动,离开三种:

BOOL CChildView::OnTouchInput(CPoint pt, int nInputNumber, int nInputsCount, PTOUCHINPUT pInput)
{
if ((pInput->dwFlags & TOUCHEVENTF_DOWN) == TOUCHEVENTF_DOWN) // 触摸按下事件
{
return OnTouchInputDown(pt, pInput);
}
else if ((pInput->dwFlags & TOUCHEVENTF_MOVE) == TOUCHEVENTF_MOVE) // 触摸移动事件
{
return OnTouchInputMove(pt, pInput);
}
else if ((pInput->dwFlags & TOUCHEVENTF_UP) == TOUCHEVENTF_UP) // 触摸离开事件
{
return OnTouchInputUp(pt, pInput);
}
return false;
}


CChildView对应你对话框类的名称。

图片控件的触摸实现

回到我一开始提的基于对话框的图片控件触摸。关于对话框及相应控件的建立这里就不介绍了,不懂的朋友可以搜搜MFC的入门教程,这里主要讲讲触摸实现部分。

实现流程和上节介绍的一致,只是把查询和注册函数放在对话框xxxDlg.cpp文件的OninitDialog函数中,然后再在xxxDlg.cpp文件中实现接收函数xxxDlg::OnTouchInput即可,xxx对应你对话框的名字。注意要记得在xxxDlg.h头文件中声明OnTouchInput函数。

但是,按照上流程实现后你可能会发现对话框窗口可以响应触摸,而图片控件却不行?!!我一开始也被这问题困扰了很久,后来才发现问题:触摸只在注册的窗口才能响应,而我们注册是在对话框窗口注册的,所以图片控件包括对话框中的其他控件都不会产生触摸事件。有两种解决思路:

1、为控件也注册触摸接收。实验测试失败(程序运行出错),初步认为是控件是窗口,不可以注册触摸事件。

2、disable掉控件。禁用掉控件,这样控件不接受输入,此时触摸控件实际上是触摸对话框窗口,触摸得以实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息