WTLVisual C++ 8.0Windows VistaWindows 2003Visual Studio 2005Windows 2000Windows XP中级开发Visual StudioWindowsC++
如何移动没有标题栏的对话框






3.41/5 (10投票s)
两种通过拖动客户端区域移动对话框的方法。
引言
本文面向初学者,介绍了两种通过拖动客户端区域移动没有标题栏的对话框的方法。
1. WM_SYSCOMMAND 消息
发送 WM_SYSCOMMAND 消息会启动移动操作。将以下代码添加到鼠标按下事件的处理程序中
BEGIN_MSG_MAP(CMainDlg)
    ...
    MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
END_MSG_MAP()
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    SendMessage(WM_SYSCOMMAND, SC_MOVE|0x0002);
    return 0;
}
需要注意的是:仅在 WM_SYSCOMMAND 消息中指定 SC_MOVE 会告诉 Windows 您正在使用键盘移动对话框。要指示您希望使用鼠标移动对话框,必须指定 SC_MOVE|0x0002。
2. WM_NCHITTEST 消息
思路是处理 WM_NCHITTEST 消息,当鼠标在客户端区域内时返回 HTCAPTION 而不是 HTCLIENT,从而欺骗 Windows 开始移动对话框。
BEGIN_MSG_MAP(CMainDlg)
    ...
    MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
END_MSG_MAP()
LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    if (::DefWindowProc(m_hWnd, uMsg, wParam, lParam) == 
        HTCLIENT && ::GetAsyncKeyState(MK_LBUTTON) < 0)
      return HTCAPTION;
    return 0;
}
Devil for ever 提供了下面的 MFC 解决方案(感谢!)。思路相同 - 处理 WM_NCHITTEST 消息。
UINT OnNcHitTest(CPoint point)
{
    UINT nHit = CDialog::OnNcHitTest(point);
    return (nHit == HTCLIENT ? HTCAPTION : nHit);
}


