Visual C ++ 6.0 - OnInitDialog в производном классе CDialog не работает

StackOverflow https://stackoverflow.com/questions/1711464

  •  19-09-2019
  •  | 
  •  

Вопрос

Я создал простой диалоговый проект MFC appwizard.Я использовал Мастер классов для создания нового класса под названием 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.

Я все еще не решил эту проблему, поэтому буду признателен за любую помощь.

Ваше здоровье

текст ссылки

Это было полезно?

Решение

Вы выводите CDeriveDlgTestDlg От CMyDlg но внутри CDeriveDlgTestDlg::OnInitDialog() вы явно указываете компилятору перепрыгнуть через базовый класс и выполнить CDialog::OnInitDialog(), так что CMyDlg::OnInitDialog() никогда не вызывается.

Другие советы

Вы не должны обрабатывать сообщение 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.Сделай это, и все будет в порядке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top