wxWidgets - 创建一个无边框的可移动窗口

3
我正试图将我写的一个 C# - Windows Forms 应用程序转换成 C++ - wxWidgets。
我的应用程序没有边框,并在表单上方有一个薄透明的面板,可用于移动表单。(我使用了这个问题的技术: 使无边框窗体可移动?)
现在,基本上我想在 wxWidgets 中做同样的事情,我在互联网上搜索如何处理 wxPanel 上的鼠标按下事件,并找到了一些例子,但所有例子都在他们的文章/问题中使用了 wxPython,而我对 Python 一无所知。
那么,在C++ - wxWidgets中如何做到相同的事情呢?
2个回答

1
一种方法是为窗口的每个子窗口的鼠标按下事件注册一个事件处理程序。这样,如果满足某些条件(例如按住Alt键并单击),窗口就可以控制鼠标。
其中一些内容在wxWidgets\samples\shaped\shaped.cpp示例中有所说明,但基本上您需要执行以下操作:
在窗口中添加一个方法,在所有子窗口都已添加后调用该方法。
void MyFrame::BindChildEvents()
{
    visit_recursively(this,
        [] (wxWindow *window, MyFrame *thiz) {
            // Bind all but the main window's event
            if(window != thiz)
            {
                window->Bind(wxEVT_LEFT_DOWN, &MyFrame::OnChildLeftDown, thiz);
            }
        },
        this
    );
}

你可以自己编写窗口树遍历的代码,但我在这里使用了这个小辅助函数:
template<typename F, typename... Args>
void
visit_recursively(wxWindow *window, F func, Args&&... args)
{
    for(auto&& child : window->GetChildren())
    {
        visit_recursively(child, func, std::forward<Args>(args)...);
    }
    func(window, std::forward<Args>(args)...);
}

然后您设置鼠标按下事件拦截处理程序:
void MyFrame::OnChildLeftDown(wxMouseEvent& event)
{
    // If Alt is pressed while clicking the child window start dragging the window
    if(event.GetModifiers() == wxMOD_ALT)
    {
        // Capture the mouse, i.e. redirect mouse events to the MyFrame instead of the
        // child that was clicked.
        CaptureMouse();

        const auto eventSource = static_cast<wxWindow *>(event.GetEventObject());
        const auto screenPosClicked = eventSource->ClientToScreen(event.GetPosition());
        const auto origin = GetPosition();

        mouseDownPos_ = screenPosClicked - origin;
    }
    else
    {
        // Do nothing, i.e. pass the event on to the child window
        event.Skip();
    }
}

您可以通过随着鼠标移动窗口来处理鼠标移动:

void MyFrame::OnMouseMove(wxMouseEvent& event)
{
    if(event.Dragging() && event.LeftIsDown())
    {
        const auto screenPosCurrent = ClientToScreen(event.GetPosition());
        Move(screenPosCurrent - mouseDownPos_);
    }
}

wxEVT_LEFT_UPwxEVT_MOUSE_CAPTURE_LOST 事件中一定要调用 ReleaseMouse()


0
“如何触发鼠标按下的事件?”您不需要担心调用事件-操作系统会处理。您需要处理 EVT_LEFT_DOWN 事件,您的问题是否与处理 wxWidgets 事件有关?是否查看了示例程序?http://docs.wxwidgets.org/2.6/wx_samples.html 它们都是以 C++ 编写的。
这里有一份关于如何处理事件的描述:http://docs.wxwidgets.org/2.6/wx_eventhandlingoverview.html#eventhandlingoverview 如果您的问题涉及 EVT_LEFT_DOWN 事件处理的详细信息,请发布您的代码,并描述您想要它执行的操作以及实际执行的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接