1

簡単なMFCappwizardダイアログプロジェクトを作成しました。クラスウィザードを使用して、CDialogに基づいてCMyDlgという新しいクラスを作成しました。次に、メッセージマップ画面に移動し、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列挙型とコンストラクターを削除しましたが、まったく違いはありませんでした。CMyDlgdlgはありません。dlg.DoModal()は、通常のCDialogクラスではなく、CMyDlgから派生したメインダイアログ自体として呼び出します。

私はまだこの問題を解決していないので、助けていただければ幸いです。

乾杯

リンクテキスト

4

4 に答える 4

4

あなたは派生 CDeriveDlgTestDlgしますCMyDlgが、あなたの内部では、CDeriveDlgTestDlg::OnInitDialog()コンパイラに基本クラスを飛び越えて実行するように明示的に指示してCDialog::OnInitDialog()いるので、CMyDlg::OnInitDialog()呼び出されることはありません。

于 2009-11-13T15:23:57.860 に答える
0

CMyDlgを他のダイアログクラスのベースとして使用する場合は、CMyDlgクラスにIDDを設定することはできません。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。これを行うと、あなたは行ってもいいです。

于 2009-11-11T11:19:02.780 に答える
0

MFCダイアログを使用している場合は、WM_INITDIALOGメッセージを処理しないでください。MFC CDialogクラスには、OnInitDialog()という名前の仮想メソッドがあり、これをオーバーライドするだけで、そのメソッドが呼び出されます。このメソッドは、VSの[ウィンドウメッセージ]タブではなく、[オーバーライド]タブから自動的に作成できます。

于 2009-11-11T21:15:16.120 に答える
0

デバッグではなくリリースビルドを使用している場合、ブレークポイントの設定に問題が発生する可能性があります。ブレークポイントが間違った行に設定されたり、完全に無視されたりする可能性があります。デバッグビルドを使用していることを再確認するか、コードに到達しているか到達していないかを判断する別の方法を見つけてください。私はあなたのコードに明らかに悪いことは何も見ていません。

于 2009-11-11T22:04:16.993 に答える