The problem
Paul DiLascia has published a technique in his C++ Q&A column that suggests
a technique for causing ON_UPDATE_COMMAND_UI messages to be handled in
a dialog. Unfortunately, I've tried this a couple times and could not get it
to work. It appears on the MSDN CD-ROM; find it by searching for WM_KICKIDLE
and looking at the C++ Q&A columns that come up. However, the only difference
between the technique I'm about to describe and the technique he describes is
how the code is partitioned. In his solution, each control has an ON_UPDATE_COMMAND_UI
handler, and the code to enable the control goes in that handler. In my solution,
all the code is in one function. But the important feature of both these techniques
is that the control manipulation code exists in precisely one place in the
program.
The usual examples given in introductory textbooks (with one exception I am
certain of: see Win32 Programming, by Brent
Rector and Joseph M. Newcomer) show dialogs as enabling controls in response
to button presses, listbox selections, and the like, in the code that responds
to the event. This is the wrong place to do it.
Why is this the wrong place? Well, a good example is a piece of code I inherited
(I'm a freelance consultant). It had twenty-three separate places where it enabled
one control. As usual, this led to the case where each change (such as adding
a new control) created a new condition for enabling the control in question,
and not every site got updated consistently. In fact, I found five separate algorithms
for determining enabling. And the order in which they were executed produced
very odd results. In addition, at least two other places where the state changed
so the enabling condition changed did not bother to do the computations at all.
Maintaining code like this is a nightmare. Getting it right is impossible.
Of course, you might think "The obviously correct thing to do would have
been to make a subroutine that did the enabling and call it from the right places".
This assumes that you know the right places. While my solution is not
perfect in this regard, it is a whole lot better than the normal distributed
update mechanism.