簡體   English   中英

從VC6遷移到VS2010的MFC應用程序,現在OnInitDialog()沒有調用CPropertyPage子類

[英]Migrated MFC app from VC6 to VS2010, now OnInitDialog() not called for CPropertyPage subclass

我的任務是將產品的UI遷移到VS2010。 它是一個MFC應用程序,最初用VC6編寫。 我執行了以下步驟:

  • 使用VS2010轉換VC6 .dsp
  • 由於更嚴格的VS2010編譯器,修復了編譯錯誤
  • 刪除了對VC6 mfc庫和目錄的所有項目引用

我的問題是,對於一個對話框對象(實際上它是一個CPropertyPage對象),OnInitDialog()在其他方法之前沒有被調用。 這會導致異常,因為OnInitDialog()需要設置成員變量。

對話框類(CPAGEViewDefRecordFields)是我們自己的CValidatedPropertyPage的子類,后者又是從MFC CPropertyPage類派生的。 虛方法OnInitDialog()存在於所有子類中。

在VS2010版本中,當在包含屬性表上調用DoModal()時,不會調用CPAGEViewDefRecordFields類的OnInitDialog()方法。 在VC6版本中,它被調用,一切正常。

在VC6中,我可以看到消息WM_INITDIALOG被發送,並在AfxDlgProc()中處理,然后反過來調用對話框對象的OnInitDialog()。

在VS2010版本中,處理的第一條消息是WM_NOTIFY,而不是WM_INITDIALOG。

不幸的是,我沒有MFC的經驗。 我假設VC6版本和VS2010版本之間的MFC行為發生了變化。 但是,我無法在網上找到與此類似的任何內容。

我錯過了另一個遷移步驟嗎? 在進行遷移時,我是否應該對項目中的資源執行某些操作?

我已檢查資源是否綁定到正確的cpp文件,因為我可以雙擊屬性頁面,IDE將我帶到CPAGEViewDefRecordFields類的正確文件。

如果你們有任何想法,我將非常感激。

謝謝! 克里斯。

class CPAGEViewDefRecordFields : public CValidatedPropertyPage
{
public:

   // Construction

   CPAGEViewDefRecordFields(CWnd*         pParent,
                           CXpViewProp*  pViewProp,
                           CFont*        pFont      = NULL,
                           UINT          nIDCaption = 0,
                           BOOL          bSumOpRequired = TRUE,
                           BOOL          bMinMaxRequired = TRUE,
                           BOOL          bAllRecords = TRUE,
                           BOOL          bShowInitSel = TRUE,
                           XLong         lLimits = 0,
                           BOOL          bSortSelTree = TRUE,
                           CXpThreshBaseLogProp* pThreshLogProp = NULL);

  ~CPAGEViewDefRecordFields();

  // Dialog Data
  //{{AFX_DATA(CPAGEViewDefRecordFields)
  enum { IDD = IDD_VIEW_DEF_RECORD_FIELDS };
  //}}AFX_DATA

  // Overrides
  // ClassWizard generate virtual function overrides
  //{{AFX_VIRTUAL(CPAGEViewDefRecordFields)
  virtual BOOL OnInitDialog();
  //}}AFX_VIRTUAL

 virtual BOOL OnSetActive();
 virtual BOOL OnKillActive();
 virtual void OnOK();

protected:

  ... 

  // Generated message map functions
  //{{AFX_MSG(CPAGEViewDefRecordFields)
  afx_msg void OnPbRemove();
  afx_msg void OnPbAdd();
  afx_msg void OnDblclkAvailableFields(NMHDR* pNMHDR, LRESULT* pResult);
  afx_msg void OnDblclkSelectedFields(NMHDR* pNMHDR, LRESULT* pResult);
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()

private:
  ...

更新:

經過一些調試后,我可以看到我認為的問題。 但是,我不是MFC程序員,我不明白。

我可以看到正在為屬性表調用OnInitDialog(),然后WM_INITDIALOG從屬性表發送到屬性頁。 但是,在Windows內部的某個時刻,正在發送WM_NOTIFY消息,因此這是收到的第一條消息,而不是預期的WM_INITDIALOG

我已經突出顯示堆棧跟蹤上的點,附加 - 任何人都可以解釋為什么會發生這種情況? 這是正常的行為 - 我將來應該為此做好准備嗎?

我實際上找到了一個解決方法,那就是有一個初始化標志,這樣在調用OnInitDialog()之前不會執行任何代碼。 這不是最好的解決方案,我擔心更多的是黑客攻擊,所以我仍然會理解對這些消息的理解。 (我不是你看到的MFC程序員!)

謝謝!

堆棧跟蹤顯示WM消息

以為我最好回答這個問題。

答案來自SO用戶的評論:

使用初始化標志的解決方法與我的做法相同。 看起來樹視圖在創建樹視圖時發送通知但您的對話框尚未就緒。 您可能不知道其他控件何時執行相同的操作,因此您需要初始化標志

“解決方法”是保證對話框准備就緒的唯一方法。

在創建所有對話框控件之后並且在顯示對話框之前調用OnInitDialog。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM