wxWidgets 和 WM_NCHITTEST

发布于 2024-10-25 05:54:36 字数 159 浏览 7 评论 0原文

我正在使用 wxWidgets 和 Visual C++ 2010。
我的目标之一是能够移动我使用窗口的任何部分(客户端或其他)创建的框架。为此,我过去曾使用 WM_NCHITTEST 来欺骗 Windows,使其认为窗口的每个部分都是标题栏。
在 wxWidgets 中应该如何完成呢?

I am using wxWidgets with Visual C++ 2010.
One of my goals is being able to move a frame I created with any part of the window (client or otherwise). For this purpose, I have used WM_NCHITTEST in the past to fool Windows into thinking every part of my window is the title bar.
How should that be done in wxWidgets?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

老子叫无熙 2024-11-01 05:54:36

经过广泛的研究,由于应答部门不活跃,我找到了一个有点可以接受(尽管不可移植)的解决方案:

WXLRESULT [your-wxWindow-inheriting-objectname-here]::MSWWindowProc(WXUINT message,WXWPARAM wParam,WXLPARAM
lParam)  
{  
    if(message==WM_NCHITTEST) { return HTCAPTION; }

    return wxFrame::MSWWindowProc(message,wParam,lParam);
}

这可以用于任何 WINAPI 消息。

After extensive research, due to inactivity on the answering department, I've found a somewhat acceptable (although not portable) solution:

WXLRESULT [your-wxWindow-inheriting-objectname-here]::MSWWindowProc(WXUINT message,WXWPARAM wParam,WXLPARAM
lParam)  
{  
    if(message==WM_NCHITTEST) { return HTCAPTION; }

    return wxFrame::MSWWindowProc(message,wParam,lParam);
}

This can be used for any WINAPI message.

温折酒 2024-11-01 05:54:36

另一种可移植的解决方案可能是这样的:

//assume your frame named wxUITestFrame
//headers
class wxUITestFrame : public wxFrame
{
    DECLARE_EVENT_TABLE()

protected:
    void OnMouseMove(wxMouseEvent& event);
    void OnLeftMouseDown(wxMouseEvent& event);
    void OnLeftMouseUp(wxMouseEvent& event);
    void OnMouseLeave(wxMouseEvent& event);

private:
    bool        m_isTitleClicked;
    wxPoint     m_mousePosition; //mouse position when title clicked
};


//cpp
BEGIN_EVENT_TABLE(wxUITestFrame, wxFrame)
    EVT_MOTION(wxUITestFrame::OnMouseMove)
    EVT_LEFT_DOWN(wxUITestFrame::OnLeftMouseDown)
    EVT_LEFT_UP(wxUITestFrame::OnLeftMouseUp)
    EVT_LEAVE_WINDOW(wxUITestFrame::OnMouseLeave)
END_EVENT_TABLE()


void wxUITestFrame::OnMouseMove( wxMouseEvent& event )
{
    if (event.Dragging())
    {
        if (m_isTitleClicked)
        {
            int x, y;
            GetPosition(&x, &y); //old window position

            int mx, my;
            event.GetPosition(&mx, &my); //new mouse position

            int dx, dy; //changed mouse position
            dx = mx - m_mousePosition.x;
            dy = my - m_mousePosition.y;

            x += dx;
            y += dy;

            Move(x, y); //move window to new position
        }
    }
}

void wxUITestFrame::OnLeftMouseDown( wxMouseEvent& event )
{
    if (event.GetY() <= 40) //40 is the height you want to set for title bar
    {
        m_isTitleClicked = true;
        m_mousePosition.x = event.GetX();
        m_mousePosition.y = event.GetY();
    }
}

void wxUITestFrame::OnLeftMouseUp( wxMouseEvent& event )
{
    if (m_isTitleClicked)
    {
        m_isTitleClicked = false; 
    }
}

void wxUITestFrame::OnMouseLeave( wxMouseEvent& event )
{
    //if mouse dragging too fase, we will not get mouse move event 
    //instead of mouse leave event here.
    if (m_isTitleClicked)
    {
        int x, y;
        GetPosition(&x, &y);

        int mx, my;
        event.GetPosition(&mx, &my);

        int dx, dy;
        dx = mx - m_mousePosition.x;
        dy = my - m_mousePosition.y;

        x += dx;
        y += dy;

        Move(x, y);
    }
}

实际上,John Locke 在 1 楼提到的解决方案是 wxMSW 中建议的 more,并且在类似 linux 的系统中我们可以模拟单击标题时的 ALT BUTTON DOWN 消息。

another portable solution maybe like this:

//assume your frame named wxUITestFrame
//headers
class wxUITestFrame : public wxFrame
{
    DECLARE_EVENT_TABLE()

protected:
    void OnMouseMove(wxMouseEvent& event);
    void OnLeftMouseDown(wxMouseEvent& event);
    void OnLeftMouseUp(wxMouseEvent& event);
    void OnMouseLeave(wxMouseEvent& event);

private:
    bool        m_isTitleClicked;
    wxPoint     m_mousePosition; //mouse position when title clicked
};


//cpp
BEGIN_EVENT_TABLE(wxUITestFrame, wxFrame)
    EVT_MOTION(wxUITestFrame::OnMouseMove)
    EVT_LEFT_DOWN(wxUITestFrame::OnLeftMouseDown)
    EVT_LEFT_UP(wxUITestFrame::OnLeftMouseUp)
    EVT_LEAVE_WINDOW(wxUITestFrame::OnMouseLeave)
END_EVENT_TABLE()


void wxUITestFrame::OnMouseMove( wxMouseEvent& event )
{
    if (event.Dragging())
    {
        if (m_isTitleClicked)
        {
            int x, y;
            GetPosition(&x, &y); //old window position

            int mx, my;
            event.GetPosition(&mx, &my); //new mouse position

            int dx, dy; //changed mouse position
            dx = mx - m_mousePosition.x;
            dy = my - m_mousePosition.y;

            x += dx;
            y += dy;

            Move(x, y); //move window to new position
        }
    }
}

void wxUITestFrame::OnLeftMouseDown( wxMouseEvent& event )
{
    if (event.GetY() <= 40) //40 is the height you want to set for title bar
    {
        m_isTitleClicked = true;
        m_mousePosition.x = event.GetX();
        m_mousePosition.y = event.GetY();
    }
}

void wxUITestFrame::OnLeftMouseUp( wxMouseEvent& event )
{
    if (m_isTitleClicked)
    {
        m_isTitleClicked = false; 
    }
}

void wxUITestFrame::OnMouseLeave( wxMouseEvent& event )
{
    //if mouse dragging too fase, we will not get mouse move event 
    //instead of mouse leave event here.
    if (m_isTitleClicked)
    {
        int x, y;
        GetPosition(&x, &y);

        int mx, my;
        event.GetPosition(&mx, &my);

        int dx, dy;
        dx = mx - m_mousePosition.x;
        dy = my - m_mousePosition.y;

        x += dx;
        y += dy;

        Move(x, y);
    }
}

Actually, the solution mentioned by John Locke at 1st Floor is more suggested in wxMSW, and in linux like system we can simulate ALT BUTTON DOWN message when title is clicked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文