zoukankan      html  css  js  c++  java
  • windows7触屏编程

    每当用户触摸触敏式 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.       
    19.     // The zoom factor is the ratio between the new and the old distance.    
    20.     k = (double)(LODWORD(gi.ullArguments))/(double)(_dwArguments);  
    21.     // Now we process zooming in/out of the object   
    22.     ProcessZoom(k,ptZoomCenter.x,ptZoomCenter.y);  
    23.     InvalidateRect(hWnd,NULL,TRUE);  
    24.   
    25.     // Now we have to store new information as a starting information for the next step   
    26.     _ptFirst = _ptSecond;  
    27.     _dwArguments = LODWORD(gi.ullArguments);  
    28.     break;  
    29. }  
    30. 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 默认手势与以上所述的特定缩放手势处理非常相似。所有手势都遵循相同的流程,只是在每个使用案例场景中,每个手势的内部逻辑实现有所不同。
  • 相关阅读:
    重排列
    最多分成多少块
    后面第一个大于
    走格子
    硬币游戏
    还是01串
    戴德兰
    个人所得税
    最长高地
    执行Commit时Oracle做哪些工作
  • 原文地址:https://www.cnblogs.com/Dennis-mi/p/3414700.html
Copyright © 2011-2022 走看看