Visual C++ 6.0 - OnInitDialog в классе производного CDialog не работает
Я создал простой диалоговый проект MFC appwizard. Я использовал Class Wizard для создания нового класса CMyDlg на основе CDialog. Затем я перешел на экран "Карта сообщений" и дважды щелкнул по записи WM_INITDIALOG, чтобы автоматически создать обработчик CMyDlg::OnInitDialog().
У меня проблема в том, что CMyDlg::OnInitDialog() не будет вызывать. Я поставил точку останова там, и она просто не будет вызывать. Метод OnInitDialog () родительского диалога вызывается, но он не будет вызывать метод CMyDlg::OnInitDialog().
Есть что-то особенное, что нужно сделать?
Мне удалось реализовать обходной путь, который состоит в том, чтобы отправить собственное сообщение из метода OnInitDialog () родительского диалога и обработать его в CMyDlg, но... Я уверен, что это не способ сделать это..
// 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_)
Спасибо, парни. Я загрузил фиктивный проект по ссылке ниже. Попробуйте построить проект, и вы обнаружите, что CMyDlg::OnInitDialog() никогда не вызывается.
Я удалил перечисление IDD и конструктор, как указано выше, но это не имело никакого значения. Там нет CMyDlg dlg; Вызов dlg.DoModal() в качестве основного диалога сам по себе выводится из CMyDlg, в отличие от обычного класса CDialog.
Я до сих пор не решил эту проблему, поэтому любая помощь будет оценена.
ура
4 ответа
Вы выводитеCDeriveDlgTestDlg
от CMyDlg
но внутри CDeriveDlgTestDlg::OnInitDialog()
вы явно указываете компилятору перепрыгнуть через базовый класс и выполнить CDialog::OnInitDialog()
, так CMyDlg::OnInitDialog()
никогда не называется.
Если вы используете сборку Release, а не Debug, у вас могут возникнуть проблемы с установкой точек останова - они могут быть установлены в неправильной строке или полностью игнорироваться. Либо дважды проверьте, что вы используете сборку Debug, либо найдите другой способ определить, достигнут ли код или нет. Я не вижу ничего явно плохого в вашем коде.
Вы не должны обрабатывать сообщение WM_INITDIALOG, если вы используете диалог MFC. Класс MFC CDialog имеет виртуальный метод с именем OnInitDialog(), который необходимо просто переопределить, и этот метод будет вызван. Вы можете создать этот метод автоматически на вкладке "переопределения" вместо вкладки "оконные сообщения" в VS.
Если вы хотите использовать CMyDlg в качестве основы для других диалоговых классов, вы не можете установить IDD в своем классе CMyDlg. IDD должен быть установлен в классе, производном от CMyDlg.
Поэтому вы должны удалить это:
enum { IDD = IDD_DERIVEDLGTEST_DIALOG };
и замените стандартный конструктор:
// 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)
{
}
Изменить: я только что видел ваш код ссылки. Вы заметили это в своем производном классе?
BOOL CDeriveDlgTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
Ты звонишь CDialog::OnInitDialog()
не CMyDlg::OnInitDialog()
!
На самом деле, вы должны заменить все упоминания CDialog
появляются в CDeriveDlgTestDlg
с CMyDlg
, Сделай это, и все готово.