CMFCPropertyGridCtrl class's constructor and method are called two times at expanded UI

Hi guys.

I make customized user interface in rhinoceros with C++.
In the project, I make new class which inherited from CRhinoTabbedDockBarDialog , and the class have some controls of MFC.

original DockBarDialog class is (some codes which are no related are deleted.)

CUtDockDialog.h

class CUtDockDialog : public CRhinoTabbedDockBarDialog
{
	DECLARE_DYNCREATE(CUtDockDialog)

	public:
        CUtDockDialog();
		virtual ~CUtDockDialog();
		 
		enum { IDD = IDD_UTDOCK_DOCKBAR_DIALOG };

		CUtPgCtrl   UtPg;

		static ON_UUID ID();
		const wchar_t* Caption()  const override;
		ON_UUID        TabId()    const override;
		ON_UUID        PlugInId() const override;

		void OnShowTab(const class CRhinoUiPanel& db, bool bShowTab, const ON_UUID& dockBarId) override;

	protected:
		virtual void DoDataExchange(CDataExchange* pDX) override;
		virtual BOOL OnInitDialog()                     override;

	private:
		DECLARE_MESSAGE_MAP()

		void InitUiSetting();
};

CUtDockDialog.cpp

IMPLEMENT_DYNCREATE(CUtDockDialog, CRhinoTabbedDockBarDialog)

////////////////////// PUBLIC //////////
///////////
/////////// CONSTRUCTOR & DESTRUCTOR 

CUtDockDialog::CUtDockDialog()
	: CRhinoTabbedDockBarDialog()
{
}

CUtDockDialog::~CUtDockDialog()
{
}

/////////// STATIC METHOD 

ON_UUID CUtDockDialog::ID()
{
	char *uuid = "????????????????????????????";

	return ON_UuidFromString(uuid);
}

/////////// OVERRIDE METHOD 

const wchar_t* CUtDockDialog::Caption() const
{
	return L"UtDock";
}

ON_UUID CUtDockDialog::TabId() const
{
	return ID();
}

ON_UUID CUtDockDialog::PlugInId() const
{
	return UtDockPlugIn().PlugInID();
}

void CUtDockDialog::OnShowTab(const class CRhinoUiPanel& db, bool bShowTab, const ON_UUID& dockBarId)
{
	UNREFERENCED_PARAMETER(db);
	UNREFERENCED_PARAMETER(bShowTab);
	UNREFERENCED_PARAMETER(dockBarId);
}

////////////////////// PROTECTED //////////
///////////
/////////// OVERRIDE METHOD

void CUtDockDialog::DoDataExchange(CDataExchange* pDX)
{
	CRhinoTabbedDockBarDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_UTDOCK_PG, this->UtPg);
}

BOOL CUtDockDialog::OnInitDialog()
{
     /* some operation of initialization */
	return TRUE;
}


////////////////////// PRIVATE //////////
///////////
/////////// METHOD 

BEGIN_MESSAGE_MAP(CUtDockDialog, CRhinoTabbedDockBarDialog)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_CBN_SELCHANGE(IDC_COMBO1, &CUtDockDialog::OnPsCbnSelchange)
END_MESSAGE_MAP()

int CUtDockDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	return CRhinoTabbedDockBarDialog::OnCreate(lpCreateStruct);
}

void CUtDockDialog::OnDestroy()
{
	CRhinoTabbedDockBarDialog::OnDestroy();
}

And, the class have original control class which inherited from CMFCPropertyGridCtrl

CUtPgCtrl.h

class CUtPgCtrl : public CMFCPropertyGridCtrl
{
	public:
		CUtPgCtrl();
		void UpdateCUtPgProperties(UINT index);

	protected:
		BOOL ValidateItemData(CMFCPropertyGridProperty* pProp) override;

};

CUtPgCtrl.cpp

CUtPgCtrl::CUtPgCtrl():CMFCPropertyGridCtrl()
{
}

/////////// METHOD 
void CUtPgCtrl::UpdateCUtPgProperties(UINT index)
{
}

At the program, CUtPgCtrl class constructor and methods are called two times.
I thought the problems depend on the DoDataExchange method, and I made similar application without Rhino enviroment. At the Application, I cannot get same behavior, so I thought the problems is depend on Rhinoceros API.

By the problem, I couldn’t control rhinoceros application state well.
If you know the solution of the problem or know MFC application , please contact me.
Thank you.

Hi @oktkhr0916

as far as i understand this is working as designed. The CRhinoTabbedDockBarDialog class is instantiated during the call of CRhinoTabbedDockBarDialog::Register. But i will de delete immediately.
The second and final instantiation will be done after CRhinoTabbedDockBarDialog::ShowDockbarTab.

But in the end it’s not a problem at all, isn’t it? :man_shrugging:

@dsw

Thank you for replying.

In my application, I want to change User Attribute Text from subclass of CMFCPropertyGridCtrl.
Then I get the changing of the class’s value like:

BOOL UtPgCtrl::ValidateItemData(CMFCPropertyGridProperty* pProp)
{
	if (pProp)
	{
        CString prop_name;
		CString val_name;

		prop_name = pProp->GetName();
		pProp->OnUpdateValue();
		val_name = pProp->GetValue();


		/*  update RObjects's  User Attribute Text  here  */	

	}
	return TRUE;
}

In this code, I got error after the method called secondly.
so I think the error is depend on the API.

This is image of UI.

Sorry, i can’t tell anything from the code you posted. And as far as i understood you have a problem with the CMFCPropertyGridCtrl class. Maybe you search for the error message e.g. at stackoverflow?

1 Like

Thank you for replying, @dsw

I can solve this problem by using CMFCPropertyGridCtrl::OnPropertyChanged method instead of ValidateItemData.

However I have not understood why ValidateItemData is called two times at Rhino environment yet.