views:

918

answers:

5

Hi, I have create a simple MFC appwizard dialog project. I used the Class Wizard to create a new class called CMyDlg based on CDialog. Then I went to the Message Map screen and doubleclicked on the WM_INITDIALOG entry to automatically create a CMyDlg::OnInitDialog() handler.

The problem I have is that CMyDlg::OnInitDialog() will not call. I have put a breakpoint in there and it simply will not call. The parent dialog's OnInitDialog() method gets called, but it will not call the CMyDlg::OnInitDialog() method.

Is there something special than needs to be done?

I have managed to implement a workaround which is to send a message of my own from the parent dialog's OnInitDialog() method and have it handled in CMyDlg but.. I'm sure this is not the way to do it..

// MyDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DeriveDlgTest.h"
#include "MyDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

CMyDlg::CMyDlg( UINT nIDTemplate, CWnd* pParent /*=NULL*/)
    : CDialog(nIDTemplate, pParent)
{
  // PDS: THIS GETS CALLED
}

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMyDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CMyDlg)
     // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
}


void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CMyDlg)
     // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    //{{AFX_MSG_MAP(CMyDlg)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog() 
{
  // PDS: THIS DOES NOT GET CALLED
    CDialog::OnInitDialog();


    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}


#if !defined(AFX_MYDLG_H__ECC7F6AC_FEB3_419D_AFE2_6B6DE8196D74__INCLUDED_)
#define AFX_MYDLG_H__ECC7F6AC_FEB3_419D_AFE2_6B6DE8196D74__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyDlg.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

class CMyDlg : public CDialog
{
// Construction
public:
    CMyDlg(CWnd* pParent = NULL);   // standard constructor
  CMyDlg( UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
// Dialog Data
    //{{AFX_DATA(CMyDlg)
    enum { IDD = IDD_DERIVEDLGTEST_DIALOG };
     // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA


// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:

    // Generated message map functions
    //{{AFX_MSG(CMyDlg)
    virtual BOOL OnInitDialog();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYDLG_H__ECC7F6AC_FEB3_419D_AFE2_6B6DE8196D74__INCLUDED_)
A: 

If you want to use CMyDlg as a base for other dialog classes, you cannot have the IDD set in your CMyDlg class. The IDD should be set on the class derived from CMyDlg.

So you should delete this:

enum { IDD = IDD_DERIVEDLGTEST_DIALOG };

and replace the standard constructor:

// in the .h file:
//CMyDlg(CWnd* pParent = NULL);
CMyDlg(LPCSTR szIDTemplate, CWnd* pParent = NULL );


// in the .cpp file:
CMyDlg::CMyDlg(LPCSTR szIDTemplate,CWnd* pParent /*=NULL*/)
    : CDialog(szIDTemplate, pParent)
{
}

Edit: I just saw your link code. Have you noticed this in your derived class?

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

You are calling CDialog::OnInitDialog(), not CMyDlg::OnInitDialog()!

In fact, you should replace all mentions of CDialog thar appear in CDeriveDlgTestDlg with CMyDlg. Do this and you're good to go.

djeidot
A: 

You must not handle the WM_INITDIALOG message if you're using an MFC dialog. The MFC CDialog class has a virtual method named OnInitDialog() which you must simply override and that one will get called. You can create that method automatically from the "overrides" tab instead of the "window messages" tab in VS.

Stefan
The message map is empty, so that doesn't appear to be the problem. I'm not sure it would hurt anything even if it was there.
Mark Ransom
A: 

If you're using a Release build rather than Debug, you might have trouble setting breakpoints - they might get set on the wrong line, or ignored entirely. Either double check to see that you're using a Debug build, or find another way to determine that the code is or isn't being reached. I don't see anything obviously wrong with your code.

Mark Ransom
A: 

Thanks Guys. I've uploaded the dummy project to the link below. Try building the project and you will find that CMyDlg::OnInitDialog() is never called.

I removed the IDD enum and constructor as advised above but it didn't make any difference at all. There is not CMyDlg dlg; dlg.DoModal() call as the main dialog itself it derived from CMyDlg as opposed to the usual CDialog class.

I still haven't solved this issue so any help would be appreciated.

Cheers

link text

SparkyNZ
+1  A: 

You derive CDeriveDlgTestDlg from CMyDlg but inside CDeriveDlgTestDlg::OnInitDialog() you explicitly direct compiler to jump over base class and execute CDialog::OnInitDialog(), so CMyDlg::OnInitDialog() is never called.

BostonLogan
Perfect! You found the problem. Thanks for that.. and how silly of me. :-) I'll have to keep an eye on that one in the future. Thanks heaps!
SparkyNZ