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, Сделай это, и все готово.

Другие вопросы по тегам