我的任务是将我们产品的 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 程序员!)
谢谢!
最佳答案
OnInitDialog 在创建所有对话框控件之后和显示对话框之前调用。
关于c++ - 将 MFC 应用程序从 VC6 迁移到 VS2010,现在不会为 CPropertyPage 子类调用 OnInitDialog(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7239198/