Pregunta

Tengo crear un sencillo proyecto de diálogo MFC AppWizard. He utilizado el Asistente para clases para crear una nueva clase llamada CMyDlg basado en CDialog. Luego fui a la pantalla de mapa de mensajes y doubleclicked en la entrada WM_INITDIALOG para crear automáticamente un controlador CMyDlg :: OnInitDialog ().

El problema que tengo es que CMyDlg :: OnInitDialog () no llamará. He puesto un punto de interrupción en allí y simplemente no llamaré. El método del diálogo padres OnInitDialog () es llamado, pero no va a llamar al método CMyDlg :: OnInitDialog ().

¿Hay algo especial que hay que hacer?

He logrado implementar una solución que es para enviar un mensaje de mi propia desde el método del diálogo padres OnInitDialog () y que sea manejado en CMyDlg pero .. estoy seguro de que esta no es la manera de hacerlo ..

// 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_)

Gracias chicos. He subido el proyecto ficticio al enlace de abajo. Intenta construir el proyecto y se encuentra que CMyDlg :: OnInitDialog () no se llama.

He quitado la enumeración IDD y constructor como estaba previsto anteriormente, pero no hace ninguna diferencia en absoluto. No hay CMyDlg DLG; dlg.DoModal () llama como el propio diálogo principal se deriva de CMyDlg en oposición a la clase CDialog usual.

Todavía no he resuelto este problema por lo que se agradece cualquier ayuda.

Saludos

texto del enlace

¿Fue útil?

Solución

Se deriva CDeriveDlgTestDlg de CMyDlg pero dentro CDeriveDlgTestDlg::OnInitDialog() que el compilador de forma explícita directa a saltar por encima de la clase base y ejecutar CDialog::OnInitDialog(), por lo CMyDlg::OnInitDialog() nunca es llamado.

Otros consejos

No debe manejar el mensaje WM_INITDIALOG si estás usando un diálogo de MFC. La clase MFC CDialog tiene un método virtual denominado OnInitDialog () que simplemente hay que anular y que uno será llamado. Puede crear este método de forma automática desde la pestaña "anulaciones" en lugar de la pestaña "ventana de mensajes" en VS.

Si está utilizando una versión de lanzamiento en lugar de depuración, es posible que tenga problemas para establecer puntos de interrupción - que alguien los pudiera establecer en la línea equivocada, o se ignora por completo. O bien vuelva a comprobar para ver que está utilizando una versión de depuración, o encontrar otra manera de determinar que el código está o no se está alcanzando. No veo nada malo, obviamente, con su código.

Si desea utilizar CMyDlg como base para otras clases de diálogo, puede no tener el conjunto IDD en su clase CMyDlg. La IDD se debe establecer en la clase derivada de CMyDlg.

Por lo que debe eliminar este:

enum { IDD = IDD_DERIVEDLGTEST_DIALOG };

y reemplace el constructor estándar:

// 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)
{
}

Editar acabo de ver su código de enlace. ¿Ha notado esto en su clase derivada?

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

Está llamando CDialog::OnInitDialog(), no CMyDlg::OnInitDialog()!

De hecho, se debe reemplazar todas las menciones de Thar CDialog aparecen en CDeriveDlgTestDlg con CMyDlg. Hacer esto y ya está bueno para ir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top