Ribbon动态事件绑定的userdata传入问题(wx3.1)

这是wxWidgets论坛的中文版本。在这里,您可以用您的母语汉语讨论上面任一子论坛所涉及的所有关于wxWidgets的话题。欢迎大家参与到对有价值的帖子的中英互译工作中来!
Post Reply
shawnee
Experienced Solver
Experienced Solver
Posts: 51
Joined: Tue Jan 16, 2018 1:05 am

Ribbon动态事件绑定的userdata传入问题(wx3.1)

Post by shawnee » Tue Jan 16, 2018 2:55 am

大家好,

我在做Ribbon控件动态绑定事件的时候,Debug模式下碰到一个crash问题。我用的是wx3.1。

示例代码如下(仅列出关键代码,其他代码已忽略):

#define wxID_App_TEST 100000
///////////////////////////////////
class myFrame : public wxFrame {
private:
int user_id;

private:
wxRibbonBar *create_ribbon();
wxRibbonBar * ribbbon;

private:
void OnClick(wxRibbonButtonBarEvent & event);

public:
myFrame():wxFrame(NULL, wxID_ANY, "test", wxDefaultPosition, wxSize(800, 450), wxDEFAULT_FRAME_STYLE | wxSUNKEN_BORDER) {
this->ribbon = NULL;
this->user_id= 0;

this->ribbbon = this->create_ribbon();
}
~myFrame();
};

wxRibbonBar *myFrame::create_ribbon()
{
wxRibbonBar * rbar = new wxRibbonBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxRIBBON_BAR_FLOW_HORIZONTAL | wxRIBBON_BAR_SHOW_PAGE_LABELS);
wxRibbonPage *pApplication = new wxRibbonPage(this->ribbbon, wxID_ANY, "Application", wxNullBitmap);
wxRibbonPanel *pApplicationPanel = new wxRibbonPanel(pApplication , wxID_ANY, "Test", wxNullBitmap,
wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE);
wxRibbonButtonBar *pAppTestBar = new wxRibbonButtonBar(pApplicationPanel);
pAppTestBar->AddButton(wxID_App_TEST, "Test", wxArtProvider::GetBitmap(wxART_QUESTION, wxART_TOOLBAR, wxSize(48,48)));

this->ribbbon->Realize();

Bind(wxEVT_RIBBONBUTTONBAR_CLICKED, &myFrame ::OnClick, this, wxID_App_TEST, wxID_ANY, this);

return rbar;
}

void myFrame::OnClick(wxRibbonButtonBarEvent& event)
{
//@@preconditions
//@@end preconditions

myFrame* userdata = static_cast<myFrame*>(event.GetEventUserData()); assert(userdata);
userdata->user_id = 1000;
}


意图是传一个user data给OnClick回调函数,这样可以做些别的处理。
但是正常退出程序时,遇到crash,并且在析构函数~myFrame()里!

如果不传user data,绑定代码如(Bind(wxEVT_RIBBONBUTTONBAR_CLICKED, &myFrame ::OnClick, this, wxID_App_TEST)),则没有Crash,程序可以正常退出。可是传user data对我来说是必须的。

请问这样的问题该如何解决?谢谢!

shawnee
Experienced Solver
Experienced Solver
Posts: 51
Joined: Tue Jan 16, 2018 1:05 am

Re: Ribbon动态事件绑定的userdata传入问题(wx3.1)

Post by shawnee » Tue Jan 16, 2018 8:32 am

我从别的帖子找到了解决方法,viewtopic.php?f=1&t=39934&p=161254&hili ... ta#p161249

定义一个通用类,专门存放宿主指针。
template<class T>
class wxExUserData : public wxObject {
public:
T * Class() { return cls; }

private:
T * cls;

public:
wxExUserData(T * cl) : cls(cl) {}
virtual ~wxExUserData() {};
};


Bind函数写成这样:
Bind(wxEVT_RIBBONBUTTONBAR_CLICKED, &myFrame ::OnClick, this, wxID_App_TEST, wxID_ANY, new wxUserData<myFrame>(this));

回调函数里改成这样:
void myFrame::OnClick(wxRibbonButtonBarEvent& event)
{
//@@preconditions
//@@end preconditions

wxUserData<myFrame> * userdata = static_cast<wxUserData<myFrame> *>(event.GetEventUserData()); assert(userdata);
myFrame* frm = userdata ->Class();
frm->user_id = 1000;
}


这样子后,程序正常退出就无事了!

Post Reply