http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_MFCNOTES_TN026.asp
you could call it any time you want.
You're right. Many people forget you can add you're own data validations in
this routine. I find that adding tooltips for controls helps as well.
I'd write IsValidData to take a CDataExchange* argument. I'd add the call
to IsValidData at the end of the dialog's DoDataExchange function (after
the wizard-generated code) and pass it the pDX that the framework passed
to
DoDataExchange. If the data weren't valid I'd set the focus to the control
I wanted the user to re-enter first, and call pDX->Fail exactly as I would
in a custom DDV function.
The default OnOK can then be used without change, and all the validation
is
being done in one place in the code (which makes maintenance easier).
... for me to do it in OnOK() is more natural.
Each to his own, but that doesn't strike me as natural at all.
There is also some use for UpdataData() in OnInitDialog().
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
PrepareInputs();
UpdateData(FALSE);
return TRUE;
}
I've never felt the need to do that. It's inelegant and inefficient (as
you
say) and there seem to me to be better ways to achieve it.
When there's processing that needs to be done to set up the data for the
initial state of the dialog -- such a initializing a listbox from a
CStringArray (or a std::vector<std::string>) what I usually do is to bind
a
control object (CListBox) to the control and explicitly call
box->AddString
in OnInitDialog.
That's what I usually do, bit it's not very elegant, I should really write
a custom DDX function that initializes a listbox from an array. In fact:
*ALL* initialization of this type could be done in DoDataExchange, and
that's probably the best place for it.
In fact it is often possible to
NOT call the base class OnInitDialog first (as instructed by the Wizard):
BOOL CMyDialog::OnInitDialog()
{
PrepareInputs();
CDialog::OnInitDialog();
// perhaps other initialization here
return TRUE;
}
Sure. I often insert processing that needs to happen before the DDX calls
at the top of OnInitDialog. The wizard docs are right in general --
because
what you usually want to do in OnInitDialog will be to call methods of the
dialog's control members, and the MFC control objects aren't bound to the
actual dialogs's controls until DDX time -- but not in all cases.
Personally, I quite like UpdateData(), and I think I know enough about
how it works to use it correctly. But to each his own.
Don't get me wrong: I like UpdateData a lot. What I like most about it is
that it does a ton of work for me and I never (well, hardly ever) even
have
to call it.
I'm not in the (as Tom Serface puts it) "avoid it all costs" camp; I've
just found very few reasons to call it that I didn't think could be coded
better in a different way.
Cheers,
Daniel.