Reputation: 6676
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_)
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
Upvotes: 1
Views: 8376
Reputation: 4640
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.
Upvotes: 0
Reputation: 1596
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.
Upvotes: 4
Reputation: 308530
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.
Upvotes: 0
Reputation: 43585
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.
Upvotes: 0