在mfc c++中移动窗口而不使用标题栏?

问题描述 投票:0回答:2

我正在使用此代码来移动窗口。但这段代码不能很好地工作。当我单击窗口上的任意位置时,它会移动,但我只想移动窗口窗体。当我点击具体思考时。例如图片。我正在使用 MFC C++ HtmlDialog。有人知道该怎么做吗?

DHTML_EVENT_ONCLICK(_T("图像"), PreTranslateMessage)

BOOL CHtmlDlgTestDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_MOUSEMOVE && (pMsg->wParam & MK_LBUTTON))
{
    CPoint p;
    GetCursorPos(&p);
    CRect r;
    GetWindowRect(&r);
    if (r.PtInRect(p))
    {
        ReleaseCapture();
        SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
        SendMessage(WM_NCLBUTTONUP, HTCAPTION, 0);
        return 1;
    }
}

return CDialog::PreTranslateMessage(pMsg);    
}
html c++ visual-studio-2013 mfc
2个回答
2
投票

WM_NCLBUTTONDOWN
是一条通知消息,Windows发送此消息并且程序对其做出响应。该程序不应将此消息发送到 Windows。在这种情况下它可以工作,但不推荐。

我不知道这段代码是如何工作的:

DHTML_EVENT_ONCLICK(_T("image"), PreTranslateMessage)
它可能会被忽略,你可以删除它。
PreTranslateMessage
仍然被调用。您可以将其限制为窗口内的任何矩形,例如
CRect(50,50,200,200)
:

BOOL CHtmlDlgTestDlg::PreTranslateMessage(MSG* pMsg)
{
   if (pMsg->message == WM_MOUSEMOVE && (pMsg->wParam & MK_LBUTTON))
   {
       CPoint p = pMsg->pt;
       ScreenToClient(&p);
       CRect r(50,50,200,200);
       if (r.PtInRect(p))
       {
           ReleaseCapture();
           SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
           SendMessage(WM_NCLBUTTONUP, HTCAPTION, 0);
           return 1;
       }
   }
   return CDialog::PreTranslateMessage(pMsg);
}

如果你想在窗口内移动元素,你可以使用 javascript:

可移动/可拖动

Ps,通常您应该使用 WM_NCHITTEST,如前所述。这种情况很不寻常,因为它是 HTML 对话框。您应该重新考虑放置一个用户理解的普通标题栏,或者您可以将 html 控件放在对话框中,然后您可以使用标准 WinApi 控制对话框的其余部分。

此示例基于一个简单的 Visual Studio 2022 C++/MFC CDialogEx 向导生成的程序,演示如何制作没有标题栏的可移动对话框。

将以下内容添加到 CDialogEx 派生类头文件中:

// Use for moving w/o title bar
CPoint m_dragPoint;// when started moving
CRect m_rDrag;// when started moving
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

然后这是实现文件:

ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()

...

// Handlers needed to support moveable dialog box w/o a header / title bar
void CNoTitleBarDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// Capture the mouse and store the starting drag point
SetCapture();
m_dragPoint = point;
GetWindowRect(&m_rDrag);

CDialogEx::OnLButtonDown(nFlags, point);
}

void CNoTitleBarDlg::OnMouseMove(UINT nFlags, CPoint point)
{
TRACE(_T("CNoTitleBarDlg::OnMouseMove(%d, point)\n"), nFlags);
// If the left mouse button is pressed and the dialog is captured, move the dialog
if ((nFlags & MK_LBUTTON) && GetCapture() == this)
{
// Calculate the delta between the current mouse position and the starting drag point
CPoint delta = point - m_dragPoint;

// Move the dialog by the calculated delta
OffsetRect(&m_rDrag, delta.x, delta.y);
SetWindowPos(NULL, m_rDrag.left, m_rDrag.top, m_rDrag.Width(), m_rDrag.Height(),
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);// | SWP_MOVE);
}
CDialogEx::OnMouseMove(nFlags, point);
}

void CNoTitleBarDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// Release the mouse capture
auto bWasResizing = (GetCapture() == this);
if (bWasResizing)
{
ReleaseCapture();
}
CDialogEx::OnLButtonUp(nFlags, point);
}

在对话框的资源定义中,您需要将标题留空,并取消选中标题栏。

现在您有一个具有干净简约外观的对话框,没有复古的 Windows 3.1 标题栏,也可以通过简单地抓取和拖动它来在整个屏幕上移动。


0
投票

此示例基于一个简单的 Visual Studio 2022 C++/MFC CDialogEx 向导生成的程序,演示如何制作没有标题栏的可移动对话框。

将以下内容添加到 CDialogEx 派生类头文件中:

// Use for moving w/o title bar
CPoint m_dragPoint;// when started moving
CRect m_rDrag;// when started moving
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

然后这是实现文件:

ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()

...

// Handlers needed to support moveable dialog box w/o a header / title bar
void CNoTitleBarDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// Capture the mouse and store the starting drag point
SetCapture();
m_dragPoint = point;
GetWindowRect(&m_rDrag);

CDialogEx::OnLButtonDown(nFlags, point);
}

void CNoTitleBarDlg::OnMouseMove(UINT nFlags, CPoint point)
{
TRACE(_T("CNoTitleBarDlg::OnMouseMove(%d, point)\n"), nFlags);
// If the left mouse button is pressed and the dialog is captured, move the dialog
if ((nFlags & MK_LBUTTON) && GetCapture() == this)
{
// Calculate the delta between the current mouse position and the starting drag point
CPoint delta = point - m_dragPoint;

// Move the dialog by the calculated delta
OffsetRect(&m_rDrag, delta.x, delta.y);
SetWindowPos(NULL, m_rDrag.left, m_rDrag.top, m_rDrag.Width(), m_rDrag.Height(),
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);// | SWP_MOVE);
}
CDialogEx::OnMouseMove(nFlags, point);
}

void CNoTitleBarDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// Release the mouse capture
auto bWasResizing = (GetCapture() == this);
if (bWasResizing)
{
ReleaseCapture();
}
CDialogEx::OnLButtonUp(nFlags, point);
}

在对话框的资源定义中,您需要将标题留空,并取消选中标题栏。

现在您有一个具有干净简约外观的对话框,没有复古的 Windows 3.1 标题栏,也可以通过简单地抓取和拖动它来在整个屏幕上移动。

© www.soinside.com 2019 - 2024. All rights reserved.