我的任务是将产品的UI迁移到VS2010。它是一个MFC应用程序,最初用VC6编写。我执行了以下步骤:
我的问题是,对于一个对话框对象(实际上它是一个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程序员!)
谢谢!
答案 0 :(得分:0)
在创建所有对话框控件之后且在显示对话框之前调用OnInitDialog。
答案 1 :(得分:0)
以为我最好回答这个问题。
答案来自SO用户的评论:
使用初始化标志的解决方法与我的做法相同。看起来树视图在创建树视图时发送通知但您的对话框尚未就绪。您可能不知道其他控件何时执行相同的操作,因此您需要初始化标志
“解决方法”是保证对话框准备就绪的唯一方法。