Multiple inheritance is strongly discouraged with MFC - especially when deriving from two classes which are both derived from CWnd as in your case - this won't work anyway.
You should probably implement the functionality you need in a class derived from CPropertyPage. If you absolutely need to share some part of the implementation for both CDialog- and CPropertyPage-derived classes, you could still consider creating a mix-in class with that behaviour (however, that class must nor be derived from CWnd or any other MFC class like CObject). You could then use multiple inheritance, deriving CYourDialog from CDialog and the mix-in class, and CYourPropertyPage from CPropertyPage and the mix-in class.
I am very curious to find out what's a mixin. Would you roughly explain what is it and what problem it solve. I couldn't find anything good from google search, probably I am not using the correct keyword.
What GStercken calls a mix-in class might also be called a helper class. Try to put whatever functionality you have in SDialog that would also be helpful in your CPropertyPage derived class.
Even if some of that functionality is dependent on the HWND that SDialog wraps, you can still have a helper class that is NOT derived from CWnd, the base wrapper class for HWND.
Split out the needed functionality in SDialog like so...
BOOL CHelper:oSomethingTrick(HWND hwnd)
{
//Do all this neat stuff
return TRUE;
}
When SDialog needs this functionality, it can call the CHelper object (which could be a member of SDialog) and passes in its HWND.
ASSERT(m_Helper.DoSomethingTrick(m_hWnd));
Or you could use multiple inheritance so that SDialog is derived from CHelper.
As gstercken said, just so long as both classes are not derived from CWnd.
Originally posted by gstercken
Multiple inheritance is strongly discouraged with MFC - especially when deriving from two classes which are both derived from CWnd as in your case - this won't work anyway.
Just out of curiosity...do you happen to know whether this includes virtual derivation as well?
Ciao, Andreas
"Software is like sex, it's better when it's free." - Linus Torvalds
Originally posted by Andreas Masur
Just out of curiosity...do you happen to know whether this includes virtual derivation as well?
Yes, even virtual derivation will not solve all the problems which arise when multiply deriving from certain MFC classes. From MSDN, TN016:
You may ask, "If you inherit CObject virtually, won't all of the ambiguity problems go away?".
[...]
The real answer is no, virtual inheritance will not solve the ambiguity problems illustrated above. For example: the Dump virtual member function is still ambiguous (since CFrameWnd and CObList implement it differently).
All my application dialogs/property pages now derive from SDialog.
The drawback is that the dialogs that do not require the property page functionality will inherit it -- this was something I can give up.
I need this approach as at the application frame level, I have to invoke functions within the child dialogs, and at run time its sufficient enough to know that I have an SDialog pointer and
call appropriate function using a typecast.
Something like this:
CWnd *pChild = GetChildWindow();
if (pChild)
{
((SDialog *)pChild)->SetActiveDate();
}
Because all my dialogs inherit from SDialog....I can easily do this, SetActiveDate() is declared virtual in SDialog.
The one thing I was not sure about was:
The CDialog constructor required a pointer to the parent:
CDialog( UINT nIDTemplate, CWnd* pParentWnd = NULL );
If I had to pass the value of pParentWnd up the hierarchy, how would I do it as the CPropertyPage/SPropertyPage constructor did not require it. So far I have not come across a reason to do this.
Originally posted by gstercken
Yes, even virtual derivation will not solve all the problems which arise when multiply deriving from certain MFC classes.
Sorry for the late reply...but thank you very much for the information...
Ciao, Andreas
"Software is like sex, it's better when it's free." - Linus Torvalds
CDialog stores the parent wnd pointer in m_pParentWnd. If it is NULL, the default argument, then CDialog simply calls AfxGetMainWnd() to get a pointer, so you could do the same.
Also, unless the derived classes implement their own version of SetActiveDate(), you don't need to make it virtual in the SDialog class.
Bookmarks