3

我正在尝试将我的一个用 C# - Windows Forms 编写的应用程序转换为 C++ - wxWidgets。

我的应用程序是无边界的,并且在表单顶部有一个薄而透明的面板,可用于移动表单。(我使用了这个问题中的技术:Make a borderless formmovable?

现在,我基本上想在 wxWidgets 中做同样的事情,我在互联网上搜索了如何处理 wxPanel 上的鼠标按下事件并找到了几个示例,但都在他们的文章/问题中使用了 wxPython,我不知道关于 Python。

那么如何在 C++ - wxWidgets 中做同样的事情呢?

4

2 回答 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_);
    }
}

一定要调用和ReleaseMouse()事件。wxEVT_LEFT_UPwxEVT_MOUSE_CAPTURE_LOST

于 2018-08-06T14:40:58.573 回答
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 事件的详细信息的更具体的问题,请发布您的代码,描述您希望它做什么以及它做什么。

于 2011-02-23T12:58:33.950 回答