MFC 视频播放器实现局部放大功能

这里介绍一种从MFC获取视频播放框并拉大的方法(还可以用一种在渲染部分拉大画布的方法)
其原理其实很简单,就是使用MoveWindow()的方法来进行放大和移动。
这里用的是鼠标双击后放大鼠标当前位置的一个小矩形框。所以可以获取鼠标的point。

1.在播放视频的DIALOG里面获取当前播放框

		CRect curRect;
		GetClientRect(&curRect);

2.确定当前需要放大的倍数,确定放大后的框长和宽(z为倍数)。

		normalWidth = curRect.right;
		normalHeight = curRect.bottom;
		amplifyWidth = curRect.right * z;
		amplifyHeight = curRect.bottom * z;

3.这里就需要考虑到,如果我放大的是视频画面的边缘,那么就要做判断,放大的地方超过一个范围就只移动放大到边框。
在这里插入图片描述

在红色框范围内,可以直接放大移动到当前鼠标位置,若超出红色框且在黑色框内,那么就以黑色框(当前视频框)为边界,具体是哪个边界,就看是点击的点靠近视频框的哪一条边。如:点击的在红色框的上方,那么我放大后的视频框的上边界就是原视频框的上边界。

		if (point.x>normalWidth / 2*z && point.x<normalWidth - normalWidth / 2*z && point.y>normalHeight / 2*z && point.y<normalHeight - normalHeight / 2*z)
		{
			MoveWindow(-point.x * z + 0.5*normalWidth, -point.y * z+0.5*normalHeight, amplifyWidth, amplifyHeight);
		}

在这里插入图片描述

这里为何normalWidth除以倍数z后还要除以2:因为我们如果仅仅除以倍数z其实是绿色的框内(蓝色的框是需要我们放大的小矩形框),因为鼠标点的那个point是在需要放大的矩形框的正中间。所以除了蓝色框的左上角1/4的部分是我们真正需要做边界处理的,如果没有除以2就不够精确。
在这里插入图片描述

MoveWindow()里point.x*z是负数,并且normalWidth要乘以0.5:这里就需要大家先了解MoveWindow()函数所需要的参数是什么。
MoveWindow(a,b,c,d):a和b代表着移动到相对于对话框左上角的位置(注意是相对位置)。
c和d代表着移动后框的长和宽。

所以其实我们所做的操作是使得画面是这样的:
在这里插入图片描述

所以就是把整个画面拉大了,并且因为有父窗口(父对话框)的存在,使得黑色框之外的画面无法显示出来。黑色框的左上角就是相对位置(0,0)。我们的操作是先放大,后移动。放大后(0,0)位置也是在放大后的视频框的左上角。移动的是放大后的视频框,所以视频框要往左或上或左上方向移动。所以是负的。(逻辑比较复杂,个人文笔一般只能靠大家理解加想象,画个图出来会更好)

4.边界处理我们可以用线来划分区域:
在这里插入图片描述

所以我们需要对8块区域做边界处理(除了正中间那一块)。

代码也是一样的逻辑:

		else 
		{
			if (point.x<normalWidth / 2*z)
			{
				if (point.y < normalHeight / 2*z || point.y>normalHeight - normalHeight / 2*z)
				{
					if (point.y<normalHeight / 2*z)
					{
						MoveWindow(0, 0, amplifyWidth, amplifyHeight);
					}
					else
					{
						MoveWindow(0, -(amplifyHeight - normalHeight), amplifyWidth, amplifyHeight);
					}
				}
				else
				{
					MoveWindow(0, -point.y * z+0.5*normalHeight, amplifyWidth, amplifyHeight);
				}
			}
			else if (point.x>normalWidth - normalWidth / 2*z)
			{
				if (point.y < normalHeight / 2*z || point.y>normalHeight - normalHeight / 2*z)
				{
					if (point.y<normalHeight / 2*z)
					{
						MoveWindow(-(amplifyWidth - normalWidth), 0, amplifyWidth, amplifyHeight);
					}
					else
					{
						MoveWindow(-(amplifyWidth - normalWidth), -(amplifyHeight - normalHeight), amplifyWidth, amplifyHeight);
					}
				}
				else
				{
					MoveWindow(-(amplifyWidth - normalWidth), -point.y * z+0.5*normalHeight, amplifyWidth, amplifyHeight);
				}
			}
		else if (point.y<normalHeight / 2*z) 
		{
			MoveWindow(-point.x * z+0.5*normalWidth, 0, amplifyWidth, amplifyHeight);
		}
		else 
		{
			MoveWindow(-point.x * z+0.5*normalWidth, -(amplifyHeight - normalHeight), amplifyWidth, amplifyHeight);
		}

5.到这里逻辑性的代码基本上就结束了。如果要进行放大,以及放大还原。那就在外面套一层if判断。

	if (isZoom==false)
	{
	isZoom=true;
	········
	}
	else
	{
		MoveWindow(0,0,normalWidth,normalHeight);
		isZoom = false;
	}

6.最后如果进度条、按钮等做在父对话框窗口A,而拉大后可能会盖住父窗口A的一些控件,那么这时候就需要再做一个对话框窗口B(原放视频的是对话框窗口C),使得A为B的父窗口,B为C的父窗口。B的大小为放置C的窗口大小。
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值