Win7中多点触控的最佳模型以及处理触控事件的API

处理 Windows 原始触控消息
要开始接收原始触控消息 WM_TOUCH,首先需要请求操作系统开始向应用程序发送触控消息,并停止发送默认手势消息。若要执行此操作,则需要调用  RegisterTouchWindow(HWND hWnd, ULONG uFlags) 函数。调用此函数可将单个  hWnd 元素(通常是一个窗口)注册为启用触控的。

与手势相同,您在应用程序的 WndProc 函数中处理 WM_TOUCH 消息。单条 WM_TOUCH 消息可能包含多条不同的“接触点消息”,需要将它们解包为一个触控输入结构数组。标准做法是将 WM_TOUCH 消息解包为一个 TOUCHINPUT 结构数组,该数组中的每个结构表示来自单个接触点的数据。若要进行解包,需要调用GetTouchInputInfo(HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) 函数,并向其传递 WM_TOUCH 消息的 lParam 以及一个新创建的接触点数组,如图  所示。

对 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 数组。接下来,我们将遍历接触点数组,将逻辑应用于每个接触点 handle ti[i] 注释。最后,我们需要通过调用CloseTouchInputHandle(HTOUCHINPUT hTouchInput) 清除触控句柄,传递原始 WinProc 的 lParam。不这么做将会导致内存泄漏

以上代码表示处理 WM_TOUCH 消息的第一个步骤。单个触控输入结构 TOUCHINPUT 包含了有关您需要使用的单个接触点的所有必需信息:

  • dwID - 接触点标识符,用于区分特定触控输入与其他输入
  • dwFlags - 一组位标志,用于指定接触点的状态
  • 接触点的 X 和 Y 坐标(基本上是每个接触点的位置)
  • dwTime - 事件的时间步长,以毫秒为单位
  • dwMask - 一组位标志,用于指定结构中的哪些可选字段包含有效值

    请务必注意,X 和 Y 坐标的单位是实际屏幕坐标的像素的百分之一(即 centa-pixel)。对于可能需要高分辨率的其他应用程序而言,这种超高分辨率有利于达到高精度,实现更加精确的手写识别。但在大多数情况下,在开始使用这些坐标之前,请务必记住应将接触点的 X 和 Y 坐标除以一百,从而将接触点坐标转换为可用的屏幕坐标。

     接下来让我们利用这些知识来构建一个多点触控画图应用程序,也称为“草稿板”。

    在将触控消息解包为触控输入结构数组 ti 之后,需要检查每个接触点状态,并针对每个接触点状态应用不同的逻辑。在“草稿板”示例中,新接触点由向下状态 TOUCHEVENTF_DOWN 进行标识。您注册新的接触点 ID,并为其指定一种颜色。删除接触点 TOUCHEVENTF_UP 之后,您完成最后的绘图,并注销接触点 ID。在向上和向下事件之间,您很可能会收到大量移动消息 TOUCHEVENTF_MOVE。收到每条移动消息时,您向现有线条添加一个新点,然后绘制新的线段。图 显示了“草稿板”应用程序支持多点触控所需的整个 WM_TOUCH处理程序。

    WM_TOUCH 处理程序

    跟踪各个接触点的关键是使用 dwID,在特定触控笔划的整个过程中,它都保持不变。在OnTouchDownHandler 帮助函数中,您将此 ID 指定给 CStroke 对象,该对象基本上是一个代表线条的点数组。这个线条是您在触敏式设备上拖动手指时形成的轨迹。我们将不再介绍支持应用程序并在屏幕上实际绘制线条的完整代码示例。在前面的代码示例中,您基本上可以找到支持多点触控所需的全部操作。

     在默认的 case 处理程序中,我们保存手势的位置,从两组点(表示当前接触点和前一个接触点)计算缩放中心位置,并将其存储在 ptZoomCenter 中。我们还通过计算两个点之间的比例来计算出缩放系数。调用ProcessZoom 帮助函数可以更新新的坐标,以反映缩放系数和中心点。

    处理其他 Windows 7 默认手势与以上所述的特定缩放手势处理非常相似。所有手势都遵循相同的流程,只是在每个使用案例场景中,每个手势的内部逻辑实现有所不同。接下来,我们将了解最佳模型,并深入探讨让您能够接收和处理原始触控事件的 API。

    处理 Windows 原始触控消息

    要开始接收原始触控消息 WM_TOUCH,首先需要请求操作系统开始向应用程序发送触控消息,并停止发送默认手势消息。若要执行此操作,则需要调用  RegisterTouchWindow(HWND hWnd, ULONG uFlags) 函数。调用此函数可将单个  hWnd 元素(通常是一个窗口)注册为启用触控的。
    与手势相同,您在应用程序的  WndProc 函数中处理 WM_TOUCH 消息。单条 WM_TOUCH 消息可能包含多条不同的“接触点消息”,需要将它们解包为一个触控输入结构数组。标准做法是将 WM_TOUCH 消息解包为一个 TOUCHINPUT 结构数组,该数组中的每个结构表示来自单个接触点的数据。若要进行解包,需要调用 GetTouchInputInfo(HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) 函数,并向其传递 WM_TOUCH 消息的  lParam 以及一个新创建的接触点数组,
    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值