0

閉じたときに破棄されない wxFrame を作成したいので、後で表示したり、非表示の場合でも更新し続けることができます。

SetExtraStyle(wxWS_EX_BLOCK_EVENTS)wxCloseEvent を破棄しようとしている人に伝播しないようにホッピングを使用しようとしましたが、役に立ちませんでした。

次の解決策で見つけました。close イベントを処理してフレームを非表示にするハンドラーを作成する必要があります。この場合、イベントはそれ以上伝播されません。しかし、ハンドラーを追跡して自分で削除する必要があるため、少し重いです。

誰でもよりスマートなソリューションを持っていますか?

    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 のより複雑な側面の 1 つであり、私が実際に持っていないより多くの時間を費やさずに確実に伝えるのはより困難です。

いくつかのテンプレートなどでこれをより一般的にすることができます。私はこれを行いましたが、ユーザー データとして渡されず、イベントを処理する別のオブジェクトを持つシングルトン イベント ハンドラーで少し異なるパターンを使用します。

于 2012-11-30T09:31:46.793 に答える