【问题标题】:wxWidgets - Creating a borderless frame movablewxWidgets - 创建一个可移动的无边框框架
【发布时间】:2011-07-02 05:39:54
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c++ wxwidgets panel movable


    【解决方案1】:

    “如何触发鼠标按下事件?”。您无需担心“触发”事件 - 操作系统会这样做。您需要处理 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 事件的细节有更具体的问题,请发布您的代码,描述您希望它做什么以及它做什么。

    【讨论】:

      【解决方案2】:

      一种方法是让窗口为其每个子窗口的鼠标按下事件注册一个事件处理程序。这样,如果满足特定条件(例如单击时按住 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()

      【讨论】:

        猜你喜欢
        • 2018-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多