1

I have a class Derived from CDialog (CNotificationDialog) which is auto-generated by Visual Studio when selecting the Add Class option.

I also have another class that's derived from CNotificationDialog (CWebNotificationDialog).

My code is something like:

CNotificationDialog* dlg = new CWebNotificationDialog();
dlg->Display();

The dialog is displayed but the CWebNotificationDialog::OnInitDialog method is not called. Only the CNotificationDialog::OnInitDialog method is called.

And before you ask, YES it is declared virtual. I've alos tried adding DECLARE_DYNAMIC, BEGIN_MESSAGE_MAP and all the other macros that are auto-generated, but no luck.

What am I doing wrong?

This is what CNotificationDialog::OnInitDialog looks like.

BOOL C1NotificationDialog::OnInitDialog()
{
   CDialog::OnInitDialog();

   HICON hIconBig = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 32, 32, LR_SHARED); 
   CStatic *pPictureCtrl = (CStatic*)GetDlgItem(IDS_NOTIFICATION_DLG_LOGO);
   pPictureCtrl->SetIcon(hIconBig);

   return TRUE;
}

It's declared like this:

protected:
virtual BOOL OnInitDialog();
conectionist
  • 2,694
  • 6
  • 28
  • 50

2 Answers2

2

I just had this very same problem, was very perplexed, and found that in my case, the problem was this:

If you are calling the member function Create() function inside the class constructor, as recommended in MSDN, it must go in the derived class constructor. Calling a virtual function from within a base-class constructor is to be avoided, per this question:

Calling virtual functions inside constructors

I found that in the following code, the derived class OnInitDialog() was not called when an object of the derived class was instantiated:

class BaseDialog : public CDialog{
public:
    BaseDialog(UINT resourceID, CWnd *pParent) : CDialog(resourceID, pParent){
        Create(resourceID, pParent);
    };
};

class DerivedDialog : public BaseDialog{
public:
   DerivedDialog(UINT resourceID, CWnd *pParent) : BaseDialog(resourceID, pParent){};

    BOOL OnInitDialog(){ /* NOT CALLED */};
};

With Create() being called from the derived class constructor, the derived class OnInitDialog() was called as intended:

class BaseDialog : public CDialog{
public:
    BaseDialog(UINT resourceID, CWnd *pParent) : CDialog(resourceID, pParent){
      //  Create(resourceID, pParent);
    };
};

class DerivedDialog : public BaseDialog{
public:
   DerivedDialog(UINT resourceID, CWnd *pParent) : BaseDialog(resourceID, pParent){
        Create(resourceID, pParent);
    };

    BOOL OnInitDialog(){ /* This was called */ };
};
Community
  • 1
  • 1
lequinne
  • 118
  • 8
0

You're calling the base class of CDialog and not the derived OnInitDialog from CWebNotificationDialog. Try...

BOOL C1NotificationDialog::OnInitDialog()
{
   CWebNotificationDialog::OnInitDialog();
rrirower
  • 4,338
  • 4
  • 27
  • 45
  • I don't understand. How am I supposed to do it? – conectionist Sep 23 '15 at 17:32
  • That's not how it works. CWebNotificationDialog is derived from CNotificationDialog. CNotificationDialog does not know anything about its descendants. What if I derive another class from C1NotificationDialog? How will the code for C1NotificationDialog::OnInitDialog() look then? The idea is for the proper OnInitDialog to be called based on what dlg is pointing to. That's polymorphism. – conectionist Sep 23 '15 at 17:44
  • @conectionist The code sample you posted does not seem to correlate with _"This is what **CNotificationDialog**::OnInitDialog looks like"_. Hence, the confusion on my part. Is that code correct? – rrirower Sep 23 '15 at 17:54
  • @conectionist Can you post the class definitions (from the header files), so that an accurate picture of the class derivation can be made? You say..."_I also have another class that's derived from CNotificationDialog (CWebNotificationDialog)._" But, the code sample shows CNotificationDialog being used as a pointer. – rrirower Sep 23 '15 at 18:19