MFC之实现无边窗口移动

说明

  • 演示环境: Vs2015 + MFC 基于对话框程序

效果图

方法1

  • 注意: 此方法存在缺陷: 无法响应LButtonUp消息

添加消息处理函数

函数代码

void CMFCApplication1Dlg::OnLButtonDown( UINT nFlags , CPoint point )
{
	PostMessage( WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARAM( point.x , point.y ) );
	CDialogEx::OnLButtonDown( nFlags , point );
}

方法2

  • 使用movewindow函数移动窗口, 下面的示意图以为了得到窗口相对屏幕的起点坐标

原理

画了一个示意图

代码

保存offset

CMFCApplication1Dlg 类中定义了以下变量, 保存offset

	int x_offset = 0;
	int y_offset = 0;

添加OnLButton函数

void CMFCApplication1Dlg::OnLButtonDown( UINT nFlags , CPoint point )
{
	SetCapture();
	CRect rW;
	GetWindowRect( rW );

	/// 得到屏幕坐标
	CPoint ptW = point;
	ClientToScreen( &ptW );
	
	/// -----------------------------------------------------------------
	/// 保存offset

	x_offset			= ptW.x - rW.left;
	y_offset			= ptW.y - rW.top;
	CDialogEx::OnLButtonDown( nFlags , point );
}

添加OnMouseMove函数

void CMFCApplication1Dlg::OnMouseMove( UINT nFlags , CPoint point )
{
	if ((nFlags & MK_LBUTTON) && this == GetCapture())
	{
		CPoint ptW = point;
		ClientToScreen( &ptW );
		

		ptW.x -= x_offset;
		ptW.y -= y_offset;

		CRect rW;
		GetWindowRect( rW );
		//TRACE("\n\nxxx=%d, yyy=%d", rW.left, rW.top);

		///  得到屏幕分辨率
		int nWidth	= GetSystemMetrics( SM_CXSCREEN );  
		int nHeight = GetSystemMetrics( SM_CYSCREEN ); 

		/// 得到当前窗口的绝对坐标系的起点坐标
		int cur_xxx = ptW.x + rW.Width();
		int cur_yyy = ptW.y + rW.Height();

		/// 保证 X在屏幕中间
		if ((1 >= ptW.x) || (cur_xxx >= nWidth))
		{
			if (1 >= ptW.x)
				ptW.x = 1;
			else
				ptW.x = nWidth - rW.Width();
		}

		/// 保证Y在屏幕中间
		if ((1 >= ptW.y) ||(cur_yyy >= nHeight) )
		{
			if (1 >= ptW.y)
				ptW.y = 1;
			else
				ptW.y = nHeight - rW.Height();

		}

		/// 移动窗口到指定位置
		MoveWindow(ptW.x, ptW.y, rW.Width(), rW.Height());
	}

	CDialogEx::OnMouseMove( nFlags , point );
}

OnLButtonUp函数

void CMFCApplication1Dlg::OnLButtonUp( UINT nFlags , CPoint point )
{

	ReleaseCapture();

	CDialogEx::OnLButtonUp( nFlags , point );
}

posted @ 2021-06-01 23:41  mohist  阅读(517)  评论(2编辑  收藏  举报