关闭时避免wxFrame破坏

Avoid wxFrame destroy when closing

本文关键字:wxFrame 破坏      更新时间:2023-10-16

我想创建wxFrame,它在关闭时不会被销毁,这样我以后可以显示它们,即使它们被隐藏,也可以不断更新。

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

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

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

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);
}

如果您查看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的一个更复杂的方面,如果不花更多的时间,就很难确定。

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