2012-11-29 68 views
0

我想創建一個在關閉時不會被銷燬的wxFrame,所以我可以稍後再顯示它們,並且即使它們被隱藏也會繼續更新它們。關閉時避免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); 
     } 
+1

你確定你真的想保持窗口周圍,而不是分離出你想要更新到另一個類的具體數據嗎? *(像文檔/視圖分離...)*保持操作系統窗口周圍 - 但不可見是一種奇怪的優化,在程序中做的事情越多,它越容易混淆。 – HostileFork

+0

爲什麼不能從wxFrame派生並將事件處理程序放在派生類中? – Pete

+0

@Pete:我認爲繼承添加一個像這樣的功能是沒有意義的,因爲我可能想要擁有許多不同的功能併爲它們中的每一個繼承......根本不可能。 – Arthur

回答

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更復雜的一個方面,並且更難以確切地說明,而不會花費更多我沒有的時間。

你可以使這個更通用的一些模板等。我已經做到了這一點,但使用一個單一的事件處理程序不會作爲用戶數據傳遞,但有一個單獨的對象來處理事件的一個稍微不同的模式。

+0

我沒有看看源代碼,但從文檔中不清楚誰擁有用戶數據。我也嘗試了你的想法,並且'〜FrameCloseHider'永遠不會被調用... – Arthur

+0

它應該是如果框架被刪除。嘗試進入你的wxFrame析構函數,看看在通過它的基類wxEvtHandler dtor時會發生什麼。 – Pete