Question

I have been tasked with migrating our product's UI to VS2010. It is an MFC app, originally written in VC6. I have performed the following steps:

  • Converted the VC6 .dsp using VS2010
  • fixed up compile errors due to stricter VS2010 compiler
  • Removed all project references to VC6 mfc libs and directories

My problem is that for a dialog object (actually it's a CPropertyPage object), OnInitDialog() is not being called before other methods are. This causes an exception as OnInitDialog() needs to setup member variables.

The dialog class (CPAGEViewDefRecordFields) is subclassed from our own CValidatedPropertyPage, which in turn is derived from the MFC CPropertyPage class. The virtual method OnInitDialog() is present in all subclasses.

In the VS2010 version, when DoModal() is called on the containing property sheet, the OnInitDialog() method of the CPAGEViewDefRecordFields class is not being called. In the VC6 version, it is being called and all works ok.

In VC6, I can see that the message WM_INITDIALOG is sent, and handled in AfxDlgProc(), which in turn then calls OnInitDialog() of the dialog object.

In the VS2010 version, the first message that is processed is WM_NOTIFY, not WM_INITDIALOG.

Unfortunately I have no prior experience in MFC. What I am assuming that something has changed in the behaviour of MFC between the VC6 version and the VS2010 version. However I've not been able to find anything on the net which is similar to this.

Is there another migration step I have missed? Should I have to do something to the resources in the project when doing the migration?

I have checked that the resource is tied to the correct cpp file, as I can double click on the property page, and the IDE takes me to the correct file for the CPAGEViewDefRecordFields class.

If any of you have any ideas, I'd be very grateful.

Thanks! Chris.

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:
  ...

UPDATE:

After some debugging, I can see what I think is the problem. However, not being an MFC programmer, I don't understand it.

I can see that OnInitDialog() is being called for the property sheet, and that a WM_INITDIALOG is then sent from the property sheet to the property pages. however, at some point in the windows internals, a WM_NOTIFY message is being sent, so this is the first message that is received, not the expected WM_INITDIALOG

I've highlighted the points on the stack trace, attached - can anyone explain why this is occuring? Is this normal behaviour - should I be catering for this in the future?

I've actually found a workaround, and that's to have an initialised flag, so that no code is executed until OnInitDialog() has been called. This is not the best solution, and I fear is more of a hack, so i would still appreciated any understanding of these messages. (I'm not an MFC programmer by trade you see!)

thanks!

stack trace showing WM messages

Was it helpful?

Solution 2

Thought I'd better answer this.

The answer came from a SO user's comment:

Your workaround with an initialized flag is the same as I would do. It looks like a tree view sends a notification when the tree view is created but your dialog isn't ready yet. You might not know when other controls do the same thing, so you need an initialized flag

The "workaround" is the only way to guarantee that the dialog is ready.

OTHER TIPS

OnInitDialog is called after all the dialog controls are created and just before the dialog box is displayed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top