我想创建一个在关闭时不会被销毁的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);
}
答案 0 :(得分: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的构造函数设为private,并添加一个静态函数来代替连接:
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更复杂的方面之一,如果不花费更多的时间而且我没有真正拥有它,更难以确定。
你可以通过一些模板等使这更通用。我已经这样做了但是使用了一个略有不同的模式,单一事件处理程序不作为用户数据传递,而是有一个处理事件的单独对象。