public ulong ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
public uint cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture }
通过GetGestureInfo(lParam, ref gestureInfo);可以得到存储以上结构体信息的变量gestureInfo,但分析此结构体中具体变量,发现此结构体是用来记录一个手势操作,没有具体的触摸点信息。而窗口过程其他参数也不能得到需要信息,故如使用GestureHandler无法获取触摸点数。 后者核心函数为:
WindowProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
第一个参数为窗口句柄,第二个为触摸类型,第三个存储第几个触摸点,第四个用来获取触摸消息。
如果在此函数中设置一个变量就可以获得到触摸点数。单此中处理方法和win7中WM_TOUCH一样需要自己编写手势判断。 综上所述,开是尝试同时在一个窗口挂载两个handle,但调试后发现同一个窗口不能同时挂载两个handle,所以这两种只能选择一种,而TouchHandler明显不能选择,故保留GestureHandler。
? 为OSG窗口设置两个窗口过程一个获取触摸点数信息一个获取手势信息
在上一种解决方案研究过程中发现了之前使用子类化不能接受触摸消息的原因是没有将窗口注册为触摸窗口(RegisterTouchWindow),由此又有了以下想法,在使用GestureHandler接收触摸手势的同时使用子类化来接收WM_TOUCH消息来获得触摸点数,于是编写了新的窗口回调函数并将窗口注册为触摸窗口,但发现手势消息又不能接收了。反复查看代码后发现在win7默认是接收手势消息的,如果注册为触摸窗口后就会改为接收触摸消息,两者为互斥关系。
于是做了新的尝试,在接受完WM_TOUCH消息并存储当前点数信息后马上取消触摸窗口的注册(UnregisterTouchWindow),让其接收手势消息。此方法经过实际调试发现,WM_TOUCH并不是调用一次就会把触摸点数记录下来,二是有几个触摸点数就会调用几次,这就无法知道他到底什么时候会调用完毕。再者当WM_TOUCH处理完后此次触摸消息就不再被手势接收,也就是会丢失touchdown瞬间的手势信息,使手势节后不再准确。
? 屏蔽单点拖动的触摸消息,交给漫游器去处理
在以上方法都行不通的情况下,开始寻找别的出路,继续研究代码,发现有在接收手势之前会有一个手势接收参数的设置:
SetGestureConfig()这里来设置需要接收什么样的手势,而这里涉及到一个结构体:
public struct GESTURECONFIG {
public uint dwID; // gesture ID
public uint dwWant; // settings related to gesture ID that are to be turned on public uint dwBlock; // settings related to gesture ID that are to be turned off }
此结构体是用来设置具体需要接收和屏蔽的手势,于是做以下尝试,把单点拖动的手势屏蔽掉,而利用漫游器可以处理单点拖动来实现单点和多点拖动的区分,具体代码如下:
GESTURECONFIG[] gestureConfig = new[] {
new GESTURECONFIG { dwID = User32.GID_PAN , dwWant = User32.GC_ALLGESTURES, dwBlock
=User32.GC_PAN_WITH_SINGLE_FINGER_VERTICALLY|User32.GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY } ,
new GESTURECONFIG{dwID = User32.GID_ROTATE , dwWant = User32.GC_ALLGESTURES,dwBlock =0 } };
SetGestureConfig(ControlHandle, 0, 2, gestureConfig, (uint)Marshal.SizeOf(typeof(GESTURECONFIG)));
经测试此方法可行。
解决了平移问题之后进行旋转功能的实现,需要做的是定轴旋转 可以通过以下公式来获得:MxNew = MxOld*(-tran*rotate*tran);tran的大小就是旋转轴的位置,比如轴位于(x,y,0),那么就需要maketraslate(x,y,0);
缩放相对来说易于解决这里就不做具体分析。
七、 测试阶段