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 );
}