From: Joseph M. Newcomer on 6 May 2010 17:24 See below... On Wed, 5 May 2010 18:25:03 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >news:1i44u59hf7o13rrovvkbd5lfgd8fo0q0ke(a)4ax.com... >>>Code: >>>UpdateData(true); >> **** >> You can tell this was designed by an amateur because UpdateData takes an >> argument, true or >> false, to indicate the direction of flow. If anything resembling >> intelligent design was >> used, there would have been methods called ControlsToVariables and >> VariablesToControls, >> instead of the non-mnemonic 'true' and 'false' options of UpdateData. You >> can always tell >> bad design because it exhibits pathologies like this. I never liked it >> when I first >> encountered it, because I had already spent over two decades arguing >> against this kind of >> design (it is hard to use, highly error-prone, and basically sucks) > >I'm usually among the most dense people in terms of analyzing the name of >something and figuring out what it does, but in this case, I think >UpdateData(BOOL) makes intuitive sense! Think of it as Update(Member)Data. >If it is TRUE, it is as the name means -- the member data is updated. If it >is FALSE, it is the opposite of the name -- the HWND gets the member data. > > >> None of my dialogs have ever been so trivial as to be able to use >> UpdateData. For >> example, I want to enable the Dothis button when the edit control is >> non-empty. UpdateData >> doesn't have any provision for this. >> > >It works for me. Handle EN_CHANGE: > > UpdateData(); // (with no parameter, TRUE is assumed > m_buttonDoThis.EnableWindow( m_strClientName.GetLength() > 0 ); **** The problem is that in sophisticated tests, you want to enable the button if the text is nonempty and the whatever checkbox is checked, so it becomes m_ButtonDoThis.EnableWIndow(m_strCleintName.GetLength() > 0 && m_chkWhatever.GetCheck() == BST_CHECKED); and then you have to replicate this in the OnBnClicked handler, and then...anyway, in one of the classics, I found something like 23 different locations where code like this appeared, using six different algorithms, only two of which were correct. So the complaint was "the controls enable and disable incorrectly, and it depends on what order you click or type things so we have to tell the customers the correct order to use, and this is incorrect". While any one instance in a contrived example might look simple, in real dialogs it often becomes much more confusing to manage this. **** > >I like DDX because it lets you write 2 line handlers like the above that >make it really easy to even leave out the comment **** If you replace the UpdateData() with CString s; m_ctlClientName.GetWindowText(s); you have added only one line, a declaration of a variable, and not required accessing any value OTHER than the one actually required. **** > > // Enable Do This button if something is typed into the edit box > >I mean it reads like that already. Convolute the code with all manner of >temporary CString, GetWindowText, DDX control variable access etc. and you >will find yourself adding the comment. **** I have found that it is easier to manage the controls if all the management is in one place, particularly when more than one condition is involved in the enable/visible state. joe **** > >-- David Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 6 May 2010 17:30 The problem is that it is seductive. It gives the illusion of working correctly, until you get into one of the obscure cases in which it fails completely, then the poor programmer has no idea what went wrong. Inevitably, this happens. So I just say "don't start doing things in a way that appears simple, when in fact it is not; develop good programming habits early". joe On Thu, 6 May 2010 07:27:37 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"Goran" <goran.pusic(a)gmail.com> wrote in message >news:66615a25-f9df-42a8-86ed-274ad556302d(a)k29g2000yqh.googlegroups.com... >> While I also disagree with Joe on general usefulness of DDX, >> systematically calling UpdateData is sometimes way too coarse-grained. >> It transfers ALL dialog control state to ALL dialog members, and that >> might, or might not, be desirable. I am convinced that many-a-MFC-er >> encountered situations where calling UpdateData was causing problems. >> > >It's true, eventually you will discover UpdateData() problems with >coarseness, as you try to do more and more sophisticated things. But this >does not negate that it is a useful technique for more situations than not, >like a lot of things in C++ like casting, multiple inheritance, and other >controversial things. > >-- David Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Ching on 6 May 2010 17:52 "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:bic6u5dsrf3lkvet7graoap8c5v4gm5ucj(a)4ax.com... > The problem is that in sophisticated tests, you want to enable the button > if the text is > nonempty and the whatever checkbox is checked, so it becomes > > m_ButtonDoThis.EnableWIndow(m_strCleintName.GetLength() > 0 && > m_chkWhatever.GetCheck() == BST_CHECKED); > > and then you have to replicate this in the OnBnClicked handler, and > then...anyway, in one > of the classics, I found something like 23 different locations where code > like this > appeared, using six different algorithms, only two of which were correct. > So the > complaint was "the controls enable and disable incorrectly, and it depends > on what order > you click or type things so we have to tell the customers the correct > order to use, and > this is incorrect". > > While any one instance in a contrived example might look simple, in real > dialogs it often > becomes much more confusing to manage this. In real dialogs of that complexity, both the EN_CHANGE and BN_CHECKED handlers would call the same function which would be the same lines. Nothing you have said here invalidates using UpdateData. In fact, using control variables does not simplify the problem in any way. > If you replace the UpdateData() with > CString s; > m_ctlClientName.GetWindowText(s); > you have added only one line, a declaration of a variable, and not > required accessing any > value OTHER than the one actually required. After getting used to WinForms which allows: m_ButtonDoThis.Enabled = (m_strCleintName.Length > 0) && m_chkWhatever.Checked; I tend to write my MFC code to emulate it as closely as possible. You lose your tolerance of superfluous temporary variables and other nonsense. > I have found that it is easier to manage the controls if all the > management is in one > place, particularly when more than one condition is involved in the > enable/visible state. I agree, but that has nothing to do with using UpdateData() or not. -- David
From: David Ching on 6 May 2010 17:55 "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:14d6u5dg1upf6pc3eslbggqfia00m70oep(a)4ax.com... > The problem is that it is seductive. It gives the illusion of working > correctly, until > you get into one of the obscure cases in which it fails completely, then > the poor > programmer has no idea what went wrong. Inevitably, this happens. So I > just say "don't > start doing things in a way that appears simple, when in fact it is not; > develop good > programming habits early". Well, that has a lot to do with the quality of your programmer. It's hard for me to see how a clear, reproducible case where all the symptoms of incorrectly disabling controls are in front of your face and you have a great debugger like Visual Studio that it could be considered "obscure and the poor programmer has no idea of what went wrong." If it goes wrong, just fix it. Granted there are a lot of MFC programmers where this is too much to ask, but since when in any C++ do we cater to those? The solution is to let them write Excel macros instead of MFC programs. -- David
From: Joseph M. Newcomer on 6 May 2010 22:18
See below... On Thu, 6 May 2010 14:55:57 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >news:14d6u5dg1upf6pc3eslbggqfia00m70oep(a)4ax.com... >> The problem is that it is seductive. It gives the illusion of working >> correctly, until >> you get into one of the obscure cases in which it fails completely, then >> the poor >> programmer has no idea what went wrong. Inevitably, this happens. So I >> just say "don't >> start doing things in a way that appears simple, when in fact it is not; >> develop good >> programming habits early". > >Well, that has a lot to do with the quality of your programmer. It's hard >for me to see how a clear, reproducible case where all the symptoms of >incorrectly disabling controls are in front of your face and you have a >great debugger like Visual Studio that it could be considered "obscure and >the poor programmer has no idea of what went wrong." If it goes wrong, just >fix it. **** And how many times do we ask people "have you entered the debugger and single-stepped?" only to be responded to by the NG equivalent of a blank look? What you and I can do easily doesn't count. And ultimately, I get to try to fix the mess they create. I know this, because I have not once received a piece of code that did not have masses of "code clumps" that were created by copy-and-paste (which is the editor solution to a subroutine call!). And which were ultimately wrong, and unmaintainable. joe **** > >Granted there are a lot of MFC programmers where this is too much to ask, >but since when in any C++ do we cater to those? The solution is to let them >write Excel macros instead of MFC programs. > >-- David Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm |