2009-11-10 120 views
1

我創建了一個簡單的MFC appwizard對話框項目。我使用類嚮導基於CDialog創建一個名爲CMyDlg的新類。然後我進入消息映射屏幕,雙擊WM_INITDIALOG條目以自動創建CMyDlg :: OnInitDialog()處理程序。Visual C++ 6.0 - 派生CDialog類中的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類。

我還沒有解決這個問題,所以任何幫助將不勝感激。

乾杯

link text

+0

你如何顯示你的CMyDlg實例? – 2009-11-10 22:38:24

+0

Hi Miles。我從一個簡單的對話框應用程序開始(嚮導爲您做的一個對話框應用程序,並顯示一個靜態標籤,一個確定和取消按鈕)。 然後我修改它,以代替如果繼承CDialog類,而不是子類CMyDlg。 乾杯 – SparkyNZ 2009-11-11 02:41:38

+0

大概你有一些看起來像CMyDlg myDlg的代碼; myDlg.DoModal();?我們可以看到這些代碼嗎? – Goz 2009-11-11 09:26:05

回答

4

您從CMyDlg派生 CDeriveDlgTestDlg但裏面CDeriveDlgTestDlg::OnInitDialog()您明確直接編譯跳過了基類和執行CDialog::OnInitDialog(),所以CMyDlg::OnInitDialog()不會被調用。

+0

完美!你發現了這個問題。謝謝你,以及我多麼愚蠢。 :-)我將不得不在未來保持關注。感謝堆! – SparkyNZ 2009-11-16 21:18:00

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()

實際上,您應該將出現在CDeriveDlgTestDlgCDialog的所有提及替換爲CMyDlg。做到這一點,你很好去。

0

如果您使用MFC對話框,則不得處理WM_INITDIALOG消息。 MFC CDialog類有一個名爲OnInitDialog()的虛擬方法,您必須重寫該方法,並調用該方法。 您可以從「覆蓋」選項卡中自動創建該方法,而不是VS中的「窗口消息」選項卡。

+0

消息映射是空的,所以看起來不是問題。即使它在那裏,我也不確定它會傷到什麼。 – 2009-11-11 22:05:29

+0

'Windows通過所有Microsoft基礎類庫對話框通用的標準全局對話框過程調用OnInitDialog函數,而不是通過消息映射,因此您不需要此成員函數的消息映射條目。因此,沒有消息地圖是需要的。 – Edeph 2013-05-27 06:37:22

0

如果您使用Release版本而不是Debug,那麼您可能在設置斷點時遇到問題 - 它們可能會設置在錯誤的行上,或者完全忽略。請仔細檢查以確定您正在使用Debug版本,或者查找另一種方法來確定代碼是否已到達。我沒有看到任何明顯的代碼錯誤。