c++ - 将 MFC 应用程序从 VC6 迁移到 VS2010,现在不会为 CPropertyPage 子类调用 OnInitDialog()

标签 c++ visual-studio-2010 visual-c++ mfc visual-c++-6

我的任务是将我们产品的 UI 迁移到 VS2010。它是一个 MFC 应用程序,最初是用 VC6 编写的。我执行了以下步骤:

  • 使用VS2010转换VC6.dsp
  • 修复了由于更严格的 VS2010 编译器导致的编译错误
  • 删除了对 VC6 mfc 库和目录的所有项目引用

我的问题是,对于一个对话框对象(实际上它是一个 CPropertyPage 对象),OnInitDialog() 没有在其他方法之前被调用。这会导致异常,因为 OnInitDialog() 需要设置成员变量。

对话框类 (CPAGEViewDefRecordFields) 是我们自己的 CValidatedPropertyPage 的子类,而 CValidatedPropertyPage 又是从 MFC CPropertyPage 类派生的。虚方法 OnInitDialog() 存在于所有子类中。

在 VS2010 版本中,当在包含属性表上调用 DoModal() 时,不会调用 CPAGEViewDefRecordFields 类的 OnInitDialog() 方法。在VC6版本中,正在调用,一切正常。

在 VC6 中,我可以看到消息 WM_INITDIALOG 已发送,并在 AfxDlgProc() 中处理,然后调用对话框对象的 OnInitDialog()。

在VS2010版本中,处理的第一条消息是WM_NOTIFY,不是WM_INITDIALOG。

很遗憾,我以前没有使用 MFC 的经验。我假设 VC6 版本和 VS2010 版本之间 MFC 的行为发生了一些变化。但是,我无法在网上找到与此类似的任何内容。

我是否错过了另一个迁移步骤?在进行迁移时,我是否必须对项目中的资源做些什么?

我已检查该资源是否绑定(bind)到正确的 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 程序员!)

谢谢!

stack trace showing WM messages

最佳答案

OnInitDialog 在创建所有对话框控件之后和显示对话框之前调用。

关于c++ - 将 MFC 应用程序从 VC6 迁移到 VS2010,现在不会为 CPropertyPage 子类调用 OnInitDialog(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7239198/

相关文章:

c++ - 当 p 是函数指针时,我们应该使用 p(..) 还是 (*p)(..)?

java - 将 nonfree 包含到 opencv4android

visual-studio-2010 - VS2010 CTRL+M 键盘快捷键已停止工作

c++ - 在 Visual Studio 中启用 DEP

c++ - 如何在 Visual Studio 2010 中为代码创建 "Application file"

c++ - MsiEnumProductsEx 不工作

c++ - 为什么分配器需要构造和销毁接口(interface)?

c++ - 具有混合依赖性的 Makefile 模式规则

c++ - 如果编译器是 MSVC,是否定义了预处理器定义?

c++ - 在 MFC 中使用 DrawTextEx 自动换行