(参考:http://baike.baidu.com/view/3036069.htm,http://technet.microsoft.com/zh-cn/library/aa249914) Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源 1. 基本作用 OnMouseMove响应鼠标移动事件 OnMouseWheel响应鼠标中键的滚动 2. 参数说明 afx_msgvoidOnMouseMove(UINTnFlags, CPointpoint); nFlags说明:指示虚拟按键是否按下 ,此参数可以是任何下列值的组合 MK_CONTROL 当CTRL键按下时 MK_LBUTTON 当鼠标左键按下时 MK_MBUTTON 当鼠标中键按下时(滚动不属于按下) MK_RBUTTON 当鼠标右键按下时. MK_SHIFT 当SHIFT按下时。 point说明:鼠标的X,Y坐标:该坐标为鼠标相对所在窗口左上角为基点的位置,是一个相对位置而不是在屏幕像素上的绝对位置。 afx_msg BOOL OnMouseWheel( UINT nFlags, shortzDelta, CPointpt ); nFlags同上 zDelta:大于0时为向上滚动,小于0时为向下滚动。A value less than zero indicates rotating back (toward the user) while a value greater than zero indicates rotating forward (away from the user). Windows下通常向上滚动缩小/窗口上移,反之放大/下移 pt::鼠标的X,Y坐标,是以其父窗口的左上角为基点的。Specifies the x- and y-coordinate of the cursor. These coordinates are always relative to the upper-left corner of the window. 3. 移动的效果实现 要实现移动,例如鼠标左键拖动butoon/图片在窗口上移动,实现的结果附加要求:鼠标放在button/图片的A点,移动之后,鼠标点依然在A点上 我们通过 a. 检测鼠标已在button/图片上(确保不是在哪都可以移动图标),并且左键按下 b. 记录鼠标当前点和上个点,计算两个的偏移值,然后使用这个偏移值来移动button/图片(MoveWindows) (记录上个点的方法可以使用静态变量,移动完毕后,把当前点赋值给静态变量)(具体实现可以灵活处理) 实现原理是:相对静止---鼠标和对象相对位置不变,鼠标的偏移量,就是我们对象的偏移量 4. 缩放的效果实现(以鼠标点为中心缩放) 要实现缩放,例如中件滑轮向上滑动缩小,向下滑动放大button/图片,实现附加要求:鼠标放在button/图片的A点,缩放之后,鼠标点依然在A点上,缩放是以鼠标点为中心 a. 同样检测鼠标已在button/图片上(确保不是在哪都可以缩放button/图片) b. 获取当前button/图片的高和宽(使用getClientRect) c. 获取当前pt点x,y相对于button/图片位置,然后计算该位置相对于宽和高的比值 d. 判断zDelta正负确定放大缩小(按比例调整图片高度和宽度),并调整图片左上点(left,top)的位置,确保c中的比值不变(---确保了以鼠标所在点为中心放大或缩小) 实现原理是:相对移动---鼠标和所在对象点位置不变,鼠标所在对象点的周围 长和宽 成比例的缩放 5. 进阶-算法 对于移动与缩放来说,如果看过计算机图形学,或是接触过matrix变换距阵操作的同学,可以基于这一点来理解这一块的操作。 已知 translate 是平移的操作 scale是缩放操作 平移操作: translate(vector) vector-偏移量 假设坐标原值为 [X.src Y.src] 对于二维平面来说,在平移时,平移量 [X.move, Y.move], 平移后的坐标新值为 [X.src + X.move, Y.src + Y.move] 缩放操作: scale(vector, point) vector-缩放量 point-缩放的基点 假设坐标原值为 [X.src Y.src] 对于二维平面来说,缩放量,因为我们当前缩放比例x/y轴使用相同量,所以X.scale = Y.scale,统一使用scale [scale, scale] a. 对于以原心(0,0)为基础的缩放的话,缩放结果为 [X.src * scale Y.src * scale] b. 考虑到以指定点为缩放基点,设指定基点为 [X.base, Y.base] 则缩放齐次方程为 [scale, 0, X.base(1-scale) 0, scale, Y.base(1-scale) 0, 0, 1] 计算结果(X.src, Y.src)坐标新值为: [X.src * scale + X.base*(1-scale), Y.src * scale + Y.base*(1-scale)] 对于中心点的位置,会随着缩放靠近或远离基点,可以根据偏移量定位 X.newcenter = X.base - (X.base - X.oldcenter) * scale Y.newcenter = Y.base - (Y.base - Y.oldcenter) * scale 旋转操作:rotate(angle, point) angle-旋转角度 point-旋转基点 假设坐标原值为 [X.src Y.src] 对于二维平面来说,设旋转角度为@度,逆时针旋转, a. 如果绕着圆心(0,0)旋转的话, X.dest = R * Cos(OrgAngle + @) = R * sin(OrgAngle) * sin(@) + R * cos(OrgAngle) * cos (@) = X.src * Sin@ + Y.src * cos@ Y.dest = R * Sin(OrgAngle + @) = X.src * -Sin(@) + Y.src * cos(@) 相当于乘以矩阵 [ sin@, cos@ -sin@, cos@] b. 考虑到绕特定点旋转,设指定基点为 [X.org, Y.org] 则相当于,偏移特定点为(0,0)点,旋转后再偏移回来 X.dest = X.org + (X.src - X.org) * sin@ + (Y.src-Y.org)*cos@ Y.dest = Y.org - (X.src - X.org) * sin@ + (Y.src-Y.org)*cos@ 齐次方程为 [ sin@, cos@, X.org - X.org * sin@ - Y.org * cos@ -sin@, cos@, Y.org + X.org * sin@ - Y.org * cos@ 0, 0, 1] 综述:从图形学的这些计算上来看,我们实现的平移,鼠标点为中心放大 也或 旋转 的算法部分都属于比较基础的应用。还算比较简单,毕竟是二维的。 如果希望深入掌握这些的话,可以阅读下《计算机图形学》这本书。 --------------------- 作者:春夜喜雨 来源:CSDN
|
|