[MFC]OnMouseMove移动位置和OnMouseWheel缩放实现
(参考: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. 参数说明
nFlags说明:指示虚拟按键是否按下 ,此参数可以是任何下列值的组合
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]
综述:从图形学的这些计算上来看,我们实现的平移,鼠标点为中心放大 也或 旋转 的算法部分都属于比较基础的应用。还算比较简单,毕竟是二维的。
如果希望深入掌握这些的话,可以阅读下《计算机图形学》这本书。
Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源
[MFC]OnMouseMove移动位置和OnMouseWheel缩放实现相关推荐
- 高德地图根据点标记位置自动调整地图缩放级别
项目场景: 高德地图根据点标记位置自动改变地图缩放 解决方案: 主要是map.setFitView()方法, 官方代码如下: 自适应显示多个点标记-点标记-示例中心-JS API 2.0 示例 | 高 ...
- mfc控件位置随对话框窗口移动
ControlPos.h代码 //------------------------------------------------------------------------------ // C ...
- 【VS开发】MFC学习之 解决StretchBlt()图片缩放绘图失真
vc中位图伸缩函数StretchBlt在对图片进行缩放时会造成严重的图片失真.在了解解决方法前先巩固下StretchBlt的用法: StretchBlt 函数功能:函数从源矩形中复制一个位图到目标矩形 ...
- ubuntu 外接显示器设置 鼠标指针闪烁 屏幕缩放 相对位置设置 分辨率设置 -xrandr
配置:通过 xrandr 直接查看 笔记本电脑 最高分辨率 2880x1800 外接的显示器 最高分辨率 1920x1200 场景:笔记本电脑外接显示器,左边为外接显示器,右边为笔记本电脑 #! /b ...
- vue内解决可视化大屏内百度地图在css transform下缩放位置偏移的问题
vue内解决可视化大屏内百度地图在css transform下缩放位置偏移的问题* 最近在写可视化大屏的时候发现使用百度地图,在缩放的缩放的时候视角总是往红色框位置缩放,并不在鼠标位置进行视角缩放,查 ...
- 【Java AWT 图形界面编程】使用鼠标滚轮缩放 Canvas 画布中绘制的背景图像 ( 绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例 )
文章目录 一.鼠标滚轮缩放的中心点设置为当前鼠标中心点 - 要点分析 1.保存当前鼠标指针指向的位置 2.根据鼠标指针指向的位置以及比例重新计算图片位置 二.绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩 ...
- windows应用(vc++2022)MFC基础到实战(4)-画线程序
目录 CWnd 对象 画图程序 新建MFC项目 鼠标位置成员变量 类向导增加消息处理函数 扩展画线功能 LineTo 函数 (wingdi.h) 两种常用画线方式 移动鼠标擦除和绘制线 继续扩展 CW ...
- 类型缩放Google map 地图类型
上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家一起学习一下类型缩放 舆图类型 基本舆图类型 45° 图像 启用和停用 45° 图像 旋转 45° 图像 修改舆图类型注册表 样 ...
- 两种方法查看MFC源代码
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 第一种- ...
最新文章
- Subversion权限详解
- linux驱动导出文件属性,linux驱动入门——模块参数和导出符号
- python subprocess_python subprocess - 刘江的python教程
- lamp黄金组合apache+mysql+php的安装
- ubuntu14.04中 gedit 凝视能显示中文,而source insight中显示为乱码的解决的方法
- Matlab optimtool优化(Optimization)工具箱
- 110-简单类型之整数类型和小数类型
- [专栏精选]Unity中动态构建NavMesh
- java中contains_Java contains用法示例
- 搏一搏,单车变摩托!华为天才少年耗时四月将自行车强势升级为自动驾驶
- Ubuntu常用软件推荐,图文详细说明及下载
- 关于使用开源版urule决策引擎优化性能和配置客户端集群同步生效的问题
- 模电笔记之共射放大电路
- win7文件夹共享 服务器,windows7共享文件夹怎么设置
- FaceNet2ExpNet: Regularizing a Deep Face Recognition Net for Expression Recognition论文个人解读
- [转载]徐文兵:梦与健康
- matlab中lms m,LMS算法仿真(Matlab)
- 用迭代法求 a 的平方根。求平方根的迭代公式为····
- 02 BGP地址聚合
- 人生就像微信,迭代才有机会
热门文章
- SmartScreen 筛选器带来的麻烦
- A2DP音频流在安卓系统中的实现
- 【算法】求解钱币兑换问题
- R语言按照城市取样(一个城市有多行观测,想筛选一些城市)
- python两张图片无缝合成一张_Python将多张图片进行合并拼接
- 基于Excel的VDS记录数据文件查看及转换工具(转MDA格式)
- 阿里云与海底捞合作QA
- 聊聊什么是探索式测试
- iOS Swift RxSwift 的使用(二)
- python特别是anaconda环境下安装库时报错需要Microsoft Visual C++ 14.0 or greater is required的终极解决方案