wxWidgets - Создание подвижного кадра без полей - PullRequest
3 голосов
/ 22 февраля 2011

Я пытаюсь преобразовать одно из моих приложений, написанных на C # - Windows Forms, в C ++ - wxWidgets.

Мое приложение не имеет границ и имеет тонкую прозрачную панель поверх формы, которую можно использовать для перемещения формы. (Я использовал технику из этого вопроса: Сделать форму без полей подвижной? )

Теперь, я в основном хочу сделать то же самое в wxWidgets, я искал в интернете, как обрабатывать событие нажатия мыши над wxPanel, и нашел пару примеров, но оба использовали wxPython в своей статье / вопросе, и я совсем не знаю о Python.

Итак, как сделать то же самое в C ++ - wxWidgets?

Ответы [ 2 ]

1 голос
/ 06 августа 2018

Один из способов заключается в том, чтобы окно регистрировало обработчик событий для каждого из событий мыши, связанных с дочерними окнами.Таким образом, окно может управлять мышью, если выполняется определенное условие (например, удерживается нажатой клавиша Alt при нажатии).

Некоторые из этих вещей показаны в примере wxwidgets\samples\shaped\shaped.cpp, но в основном вы делаетеthis:

Добавьте метод к вашему окну, который вы вызываете после того, как были добавлены все дочерние окна:

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_UP и wxEVT_MOUSE_CAPTURE_LOST.

0 голосов
/ 23 февраля 2011

«как запустить событие мыши?». Вам не нужно беспокоиться о «срабатывании» события - это делает ОС. Вам нужно обработать событие 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, то, пожалуйста, опубликуйте свой код, опишите, что вы хотите, чтобы он делал и что вместо этого.

...