C++ TabControl multi tab issue
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-05
03:51 PM
- last edited on
2023-07-13
03:43 PM
by
Doreena Deng
I have five classes to implement my TabControl
There is one main dialog class and two class for each tab.
My dialog opens without any problem. First tab events fires without any problem. The only problem is that second tab events (ButtonClicked) do not fire and I can not change any control text in second tab.
Here is my whole code.
resource file
'GDLG' 32511 Modal 0 0 444 174 "Upload IFC" { /* [ 1] */ NormalTab 0 0 428 148 32512 NoIcon "New" 32513 NoIcon "Existing" } 'DLGH' 32511 DLG_32511_Upload_IFC { 1 "" uploadTabControl } 'GDLG' 32512 TabPage 0 0 428 134 "" { /* [ 1] */ LeftText 13 23 84 13 LargePlain "Model file name:" /* [ 2] */ TextEdit 104 18 293 20 LargePlain 256 /* [ 3] */ Separator 13 53 385 1 /* [ 4] */ Button 241 68 75 23 LargePlain "Cancel" /* [ 5] */ Button 322 68 75 23 LargePlain "Upload" } 'DLGH' 32512 TabPage_32512 { 1 "" lblModelName_New 2 "" txtModelName 3 "" seperator_0 4 "" btnCancel 5 "" btnUpload } 'GDLG' 32513 TabPage 0 0 428 134 "" { /* [ 1] */ LeftText 13 23 84 13 LargePlain "Model file name:" /* [ 2] */ PopupControl 104 18 293 20 144 0 /* [ 3] */ Separator 13 53 385 1 /* [ 4] */ Button 241 68 75 23 LargePlain "Cancel" /* [ 5] */ Button 322 68 75 23 LargePlain "Upload" } 'DLGH' 32513 TabPage_32513 { 1 "" lblModelName_Existing 2 "" comboModelName 3 "" seperator_2 4 "" btnCancel 5 "" btnUpload }.h file
class ExportDialog : public DG::ModalDialog { friend class NewTabControl; friend class NewTabControlObserver; friend class EditTabControl; friend class EditTabControlObserver; private: enum ui { id = 32511, normalTabID = 1 }; DG::NormalTab m_normalTab; NewTabControl *m_newTabControl; NewTabControlObserver *m_newTabObserver; EditTabControl *m_editTabControl; EditTabControlObserver *m_editTabObserver; public: ExportDialog(); ~ExportDialog(); private: ExportDialog(const ExportDialog&); const ExportDialog& operator=(const ExportDialog&); //Disabled }; // ----------------------------------------------- New tabe class---------------------------------------------------- class NewTabControl : public DG::TabPage { friend class NewTabControlObserver; private: enum ui { TabID = 32512, lblModelNameID = 1, txtModelNameID = 2, seperator0ID = 3, btnCancelID = 4, btnUploadID = 5 }; DG::TextEdit m_txtModelName; DG::Button m_btnCancel; DG::Button m_btnSave; public: NewTabControl( const DG::TabControl& tabControl, short tabItem ); ~NewTabControl( void ); }; class EditTabControl : public DG::TabPage { friend class EditTabControlObserver; private: enum ui { TabID = 32513, comboModel = 2, btnCancelID = 4, btnUploadID = 5 }; DG::PopUp m_comboModel; DG::Button m_btnCancel; DG::Button m_btnSave; public: EditTabControl( const DG::TabControl& tabControl, short tabItem ); ~EditTabControl( void ); }; // ----------------------------------------------- TabControlObserver ----------------------------------------------- class NewTabControlObserver : public DG::PanelObserver, public DG::NormalTabObserver, public DG::ButtonItemObserver, public DG::CompoundItemObserver { private: NewTabControl *m_newTabControl; ExportDialog &mainDialog; protected: // DG::PanelObserver virtual void PanelOpened (const DG::PanelOpenEvent& ev) override; // DG::ButtonItemObserver virtual void ButtonClicked (const DG::ButtonClickEvent& ev) override; public: explicit NewTabControlObserver (NewTabControl* newTabControl, ExportDialog &exportDialog); ~NewTabControlObserver (); }; // ----------------------------------------------- EditControlObserver ----------------------------------------------- class EditTabControlObserver : public DG::PanelObserver, public DG::NormalTabObserver, public DG::ButtonItemObserver, public DG::CompoundItemObserver { private: EditTabControl *m_EditTabControl; ExportDialog &mainDialog; protected: // DG::PanelObserver virtual void PanelOpened (const DG::PanelOpenEvent& ev) override; // DG::ButtonItemObserver virtual void ButtonClicked (const DG::ButtonClickEvent& ev) override; public: explicit EditTabControlObserver (EditTabControl* editTabControl, ExportDialog &exportDialog); ~EditTabControlObserver (); };.cpp
ExportDialog::ExportDialog() : ModalDialog (ACAPI_GetOwnResModule (), ui::id, InvalidResModule), m_normalTab(GetReference (), ui::normalTabID), m_newTabControl(new NewTabControl(m_normalTab, ui::normalTabID)), m_newTabObserver(new NewTabControlObserver(m_newTabControl, *this)), m_editTabControl(new EditTabControl(m_normalTab, ui::normalTabID)), m_editTabObserver(new EditTabControlObserver(m_editTabControl, *this)) { } ExportDialog::~ExportDialog() { delete m_newTabObserver; delete m_newTabControl; } //------------------------------ NewTabClass -------------------------------- NewTabControl::NewTabControl (const DG::TabControl& tabControl, short tabItem): DG::TabPage (tabControl, tabItem, ACAPI_GetOwnResModule(), ui::TabID, ACAPI_GetOwnResModule ()), m_txtModelName (GetReference (), ui::txtModelNameID), m_btnCancel(GetReference (), ui::btnCancelID), m_btnSave(GetReference (), ui::btnUploadID) { } NewTabControl::~NewTabControl () { } //-----------------------------------------------------------------EditTabClass---------------------------------------------------------- EditTabControl::EditTabControl (const DG::TabControl& tabControl, short tabItem): DG::TabPage (tabControl, tabItem, ACAPI_GetOwnResModule(), ui::TabID, ACAPI_GetOwnResModule ()), m_comboModel (GetReference (), ui::comboModel), m_btnCancel(GetReference (), ui::btnCancelID), m_btnSave(GetReference (), ui::btnUploadID) { this->m_btnCancel.SetText("ascaca"); } EditTabControl::~EditTabControl () { } //-------------------------- Class TabControlObserver ----------------------- NewTabControlObserver::NewTabControlObserver (NewTabControl* newTabControl, ExportDialog &exportDialog): m_newTabControl (newTabControl), mainDialog(exportDialog) { m_newTabControl->Attach (*this); AttachToAllItems (*m_newTabControl); } NewTabControlObserver::~NewTabControlObserver () { m_newTabControl->Detach (*this); DetachFromAllItems (*m_newTabControl); } void NewTabControlObserver::PanelOpened (const DG::PanelOpenEvent& ev) { } void NewTabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) { // Close dialog with acceptance if (ev.GetSource () == &m_newTabControl->m_btnCancel) { mainDialog.PostCloseRequest(DG::ModalDialog::Accept); } else if ( ev.GetSource() == &m_newTabControl->m_btnSave ) { } } //--------------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------- Class TabControlObserver ----------------------- EditTabControlObserver::EditTabControlObserver (EditTabControl* editTabControl, ExportDialog &exportDialog): m_EditTabControl (editTabControl), mainDialog(exportDialog) { m_EditTabControl->Attach (*this); AttachToAllItems (*m_EditTabControl); } EditTabControlObserver::~EditTabControlObserver () { m_EditTabControl->Detach (*this); DetachFromAllItems (*m_EditTabControl); } void EditTabControlObserver::PanelOpened (const DG::PanelOpenEvent& ev) { } void EditTabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) { // Close dialog with acceptance if (ev.GetSource () == &m_EditTabControl->m_btnCancel) { mainDialog.PostCloseRequest(DG::ModalDialog::Accept); } else if ( ev.GetSource() == &m_EditTabControl->m_btnSave ) { } }
- Labels:
-
Add-On (C++)

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 09:15 AM
There could be more bugs in your code, but the first I noticed is the following:
You should have an observer class for your modaldialog also (ExportDialogObserver), so 2 class for each.
And the modaldialog's observer should be inherited from DG::PanelObserver, DG::NormalTabObserver and DG::CompoundItemObserver.
It's a mistake in your code that your tabpages' observers inherited from DG::NormalTabObserver, however they don't have any NormalTab, so please delete that inheritance.
Regards,
Tibor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 01:06 PM
Tibor wrote:
Hi,
There could be more bugs in your code, but the first I noticed is the following:
You should have an observer class for your modaldialog also (ExportDialogObserver), so 2 class for each.
And the modaldialog's observer should be inherited from DG::PanelObserver, DG::NormalTabObserver and DG::CompoundItemObserver.
It's a mistake in your code that your tabpages' observers inherited from DG::NormalTabObserver, however they don't have any NormalTab, so please delete that inheritance.
Regards,
Tibor
Than you for the response.
What concern to tabpage's observers I removed the DG::NormalTabObserver.
The strange thing is that first tab functionality working fine. The only problem is second tab.
What concern ModelDialog why I should have an observer class ?
Some times age you gave me this example where the main dialog has no observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 01:14 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 02:48 PM
So please explain me why my code works only for first tab ?
And why I need Observer also for Dialog ?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 03:50 PM
ggiloyan wrote:Observers handle the user interface changes. So if the user selects an another tab, then the observer must handle it and run the required updates.
So please explain me why my code works only for first tab ?
And why I need Observer also for Dialog ?
In your case I think one of the required updated didn't run and that's why you should implement an observer for your dialog class, and attach the observer to the dialog.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-08-06 04:53 PM
The strange thing is that my second tab constructor working and in constructor I wrote this this->m_btnCancel.SetText("ascaca"); which does not change the button name.
Here is the new dialog's observer class
class TabControlObserver: public DG::PanelObserver, public DG::NormalTabObserver, public DG::ButtonItemObserver, public DG::CompoundItemObserver { private: ExportDialog* mDialog; protected: // DG::PanelObserver virtual void PanelOpened (const DG::PanelOpenEvent& ev) override; // DG::ButtonItemObserver virtual void ButtonClicked (const DG::ButtonClickEvent& ev) override; public: explicit TabControlObserver (ExportDialog* testDialog); ~TabControlObserver (); };.cpp
TabControlObserver::TabControlObserver (ExportDialog* testDialog): mDialog (testDialog) { mDialog->Attach (*this); AttachToAllItems (*mDialog); } TabControlObserver::~TabControlObserver () { mDialog->Detach (*this); DetachFromAllItems (*mDialog); } void TabControlObserver::PanelOpened (const DG::PanelOpenEvent& /*ev*/) { mDialog->SetClientSize (mDialog->GetOriginalClientWidth (), mDialog->GetOriginalClientHeight ()); } void TabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) { }
And I'm calling the dialog by this way
ExportDialog dialog (ACAPI_GetOwnResModule (), 32511); if (DBERROR (dialog.GetId () == 0)) { return; } TabControlObserver observer (&dialog); dialog.Invoke (); return;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2019-11-07 12:40 PM
I have the same problem.
What is the solution to this problem?
Thanks.