一种简单的方法使对话框“可拖动”, 而不使用标题栏





2.00/5 (13投票s)
2004 年 3 月 30 日
1分钟阅读

70849
一种简单的方法使对话框“可拖动”,
引言
我经常在项目中创建各种形状的对话框。 这会导致对话框缺少标题栏,或者说,我是故意省略标题栏的(呵呵)。 默认情况下,只能通过拖动标题栏来移动对话框。 但是,如果没有标题栏,该怎么办? 这篇简短的文章将向您展示如何实现。
工作原理
如果我们的对话框中没有客户端窗口,我们可以简单地使用 OnMouseMove
函数,该函数将接收来自系统的 WM_MOUSEMOVE
。 但是,在本文中,我假设对话框中填充了许多控件,因此无法使用 OnMouseMove
函数。
那么,解决方案是什么? 由于通常光标位于对话框内部才能移动它,我选择在消息到达子窗口之前拦截该消息。 然后,如果消息满足条件(即:鼠标按下,然后鼠标移动),则应更改窗口位置。 因此,我们可以使用 PreTranslateMessage(..)
来实现这一点。 只需要过滤必要的消息,对其进行处理,就完成了。
注意:对于某些控件,我使用的方法不太友好。 因此,请根据需要进行修改。 可以通过检索控件的矩形,然后通过检查当前光标位置(是否在矩形内?或者不在?)来进行必要的过滤,从而使其不会到达主代码(这将移动窗口)。
一个非常简单的代码
这是我用来使对话框可拖动的代码。
BOOL CYourClassDlg::PreTranslateMessage(MSG* pMsg) { //The code starts here static bool mouse_down = false; static CRect MainRect; static HCURSOR cursor; // use this if you want the // “dragging” cursor different from the normal one static CPoint point; switch(pMsg->message) { case WM_LBUTTONDOWN: //save current dialog’s rectangle GetWindowRect(&MainRect); //save current cursor coordinate point = pMsg->pt; ScreenToClient(&point); //change the sign mouse_down = true; cursor = ::AfxGetApp()->LoadCursor(IDC_CURSOR1); break; case WM_LBUTTONUP: //stop the sign mouse_down = false; //gimme a standard cursor now!! cursor = ::AfxGetApp()->LoadStandardCursor(IDC_ARROW); break; case WM_MOUSEMOVE : cursor = ::AfxGetApp()->LoadStandardCursor(IDC_ARROW); if(mouse_down) { //if here, then the mouse is dragging cursor = ::AfxGetApp()->LoadCursor(IDC_CURSOR1); //finally, move the window MoveWindow( pMsg->pt.x - point.x, //count the relative position pMsg->pt.y - point.y, MainRect.Width(), //if the width doesn’t change MainRect.Height(), //if the height doesn’t change TRUE); } } SetCursor(cursor); //The code ends here return CDialog::PreTranslateMessage(pMsg); }
就这样了。 这是您需要添加到项目中的唯一代码。 希望这有帮助。