0

我想创建在关闭时不会被销毁的 wxFrame,所以我可以稍后将它们显示回来,并且即使它们被隐藏也可以继续更新它们。

我尝试使用SetExtraStyle(wxWS_EX_BLOCK_EVENTS)跳跃,它不会将 wxCloseEvent 传播给曾经破坏它的人,但它没有帮助。

我找到了以下解决方案。我必须创建一个处理程序来处理关闭事件并隐藏框架。在这种情况下,事件不会被进一步传播。但这有点重,因为我需要跟踪处理程序并自己删除它。

有人有更聪明的解决方案吗?

    class FrameCloseHider
        : public wxEvtHandler
      {
      public:
        explicit FrameCloseHider(wxTopLevelWindow*);
        void internalOnQuit(wxCloseEvent&);
        wxTopLevelWindow* getFrame();
      private:
        wxTopLevelWindow*   frame_;
      };

     wxTopLevelWindow* FrameCloseHider::getFrame()
      {
        return this->frame_;
      }

      void FrameCloseHider::internalOnQuit(wxCloseEvent& obj)
      {
         this->frame_->Hide();
       }  

      FrameCloseHider::FrameCloseHider(wxTopLevelWindow* frame)
        :frame_(frame)
      {
        this->frame_->Connect(
          frame_->GetId(),
          wxEVT_CLOSE_WINDOW,
          wxCloseEventHandler(FrameCloseHider::internalOnQuit),
          NULL,
          this);
      }
4

1 回答 1

1

如果你看一下 wxEvtHandler 源代码,你会看到如果你提供用户数据来连接,那么它会在连接被破坏时被删除。

因此,在您的示例中,由于 wxEvtHandler 继承自 wxObject,您应该可以这样做:

this->frame_->Connect(
  frame_->GetId(),
  wxEVT_CLOSE_WINDOW,
  wxCloseEventHandler(FrameCloseHider::internalOnQuit),
  this, // ** Use the event handler as the user data.
  this);

现在,由于您要确保仅在堆上创建它,请将 FrameCloseHider 的构造函数设为私有并添加一个静态函数来建立连接:

public:
    static void ConnectTo(wxTopLevelWindow* frame) {
        FrameCloseHider* obj = new FrameCloseHider(frame);
        frame->Connect(
          frame->GetId(),
          wxEVT_CLOSE_WINDOW,
          wxCloseEventHandler(FrameCloseHider::internalOnQuit),
          obj,
          obj);
    }
private:
      FrameCloseHider::FrameCloseHider(wxTopLevelWindow* frame)
        :frame_(frame)
      {
      }

[注意:您可能应该通过使用 auto_ptr 并在连接调用后释放它来确保此异常安全] 您需要进行测试以确保对连接中的用户数据使用事件处理程序不会使其崩溃。从 wx 代码看起来应该没问题,但它是 wx 更复杂的方面之一,如果不花更多时间,我更难确定,而我并没有。

您可以使用一些模板等使其更通用。我已经做到了这一点,但使用了一个稍微不同的模式和一个不作为用户数据传递但有一个单独的对象来处理事件的单例事件处理程序。

于 2012-11-30T09:31:46.793 回答