From: David Ching on
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:04i7u5tr3ec3uuflbloflgchke2ija97ib(a)4ax.com...
> Actually, I don't see the "relief" at all. I have to maintain a set of
> duplicate
> variables, that may or may not reflect the instantaneous contents of the
> controls, and I
> have to use a non-intuitive mechanism to grab them (does "true" transfer
> TO or FROM the
> controls?). It is easier just to ask the control I need what its value
> is.

Why duplicate? In your example 3 HWND child controls were involved. You
need a DDX control to disable the Do It button, one DDX member for the
string being empty, and one DDX member for the checkbox value. No HWND has
any duplicate DDX.

As for non-intuitive, I told you how it is perfectly intuitive for me.

Well, reasonable people can disagree. I dare say if I got your source code,
I would spend a fair amount of time overhauling it and you would do the same
for mine. (In fact I did do that with your excellent serial port example
code, which btw, I have a note that I should send you the changes I made.)
Such is life. But that doesn't mean either of us are wrong.

-- David



From: Joseph M. Newcomer on
See below.,
On Fri, 7 May 2010 07:13:00 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote:

>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:04i7u5tr3ec3uuflbloflgchke2ija97ib(a)4ax.com...
>> Actually, I don't see the "relief" at all. I have to maintain a set of
>> duplicate
>> variables, that may or may not reflect the instantaneous contents of the
>> controls, and I
>> have to use a non-intuitive mechanism to grab them (does "true" transfer
>> TO or FROM the
>> controls?). It is easier just to ask the control I need what its value
>> is.
>
>Why duplicate? In your example 3 HWND child controls were involved. You
>need a DDX control to disable the Do It button, one DDX member for the
>string being empty, and one DDX member for the checkbox value. No HWND has
>any duplicate DDX.
****
But I don't need value variables, because any control whose value I want I can query
directly.
****
>
>As for non-intuitive, I told you how it is perfectly intuitive for me.
****
I always have to look it up whenever I find it, because I never remember which way is
which. This is what I call "C overloading" and it is inappropriate in C and more so in
C++. There is no reason to ever have a single function with a boolean argument telling it
what to do, when two functions would do the job. When creating functionality, split,
don't lump.
****
>
>Well, reasonable people can disagree. I dare say if I got your source code,
>I would spend a fair amount of time overhauling it and you would do the same
>for mine. (In fact I did do that with your excellent serial port example
>code, which btw, I have a note that I should send you the changes I made.)
>Such is life. But that doesn't mean either of us are wrong.
****
But what works for us doesn't work for beginners. I try to make working for beginners as
painless as possible. I teach courses in MFC. UpdateData is actually hard to explain.
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: JCO on
Joseph,
I've read every ones comments and I understand that the UpdateData() can
cause issues. If done your way, does this mean you create a control (ctl)
variable for every control on your Dialog? This brings me to my next issue:

Which method do you recommend to use?
One: //no control variable used
CString strName;
CEdit *pName = (CEdit*) GetDlgItem(IDC_CUSTOMER_NAME);

pName->GetWindowTextw(strName);
SetCustomerName(strName);


Two: //uses control variable
CString strName;
ctlEditCutomerName.GetWindowTextW(strName);
SetCustomerName(strName);

Method two seems easier, however, you must declare the control variable (not
shown) which makes your code larger in size (I realize not much). My issue
.... the Dialog I'm working on has 30 CEditBox. Do I really need to create
30 Control Variables (ex ctlCustomerName) plus 30 member variables (ex
m_strCutomerName)? If I use the GetDlgItem(), I avoid the 30 Control
Variables.

Thanks for your in-depth response to my original question.


"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:1i44u59hf7o13rrovvkbd5lfgd8fo0q0ke(a)4ax.com...
> I am always offering a contrarian opinion on this: I would NEVER, EVER use
> a variable to
> hold a value except in some extremely rare and estoteric situations which
> I hardly ever
> encounter, so NEVER, EVER is a pretty good characterization of what I do.
>
> I make all the variables "control" variables which are just ways to name
> the control, and
> use methods of those variables to extract the data from the control, such
> as
> GetWindowText, GetCheck, GetCurSel, etc.
>
> I never, ever call UpdateData in a dialog or formview; I think the ONLY
> valid times this
> is called is when the framework calls them before OnInitDialog or after
> OnOK is called,
> and 99% of the time, I never use this capability either. I seriously
> preach that the
> whole DDX mechanism should not be used, EXCEPT for DDX_Control that binds
> controls to
> variables, and the entire DDV mechanism should be ignored completely, in
> favor of
> intelligent real-time input validation.
>
> I generally react to code that arrives on my desk by removing all these
> variables and
> removing all UpdateData calls, and replacing them with what I consider
> sane and robust
> code. I allow ONLY control variables to exist.
> On Wed, 5 May 2010 14:23:35 -0500, "JCO" <someone(a)somewhere.com> wrote:
>
>>I have a general question concerning members of class and assigning the
>>content. Particularly if I have a class that, for instance has an
>>EditBox.
>>If I use the Wizard, I can create a member data of type "Control" or
>>"Variable". If I choose variable, the wizard does it's thing. Is this
>>variable simply used as a conduit? Should it be used simply to set my
>>actual data member that I created manually in my Class? Example.
>>m_editClientName was created from the Wizard as type variable CString.
>>m_strClientName was created by me as part of my private class member.
>>
>>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)
> *****
>>m_strClientName = m_editClientName; //editbox variable is simply a
>>conduit to set my my actual member
> ****
> I would use
> m_EditClient.GetWIndowText(m_strClientName);
>
> which makes it obvious what is going on; there is never a chance that the
> variables and
> the controls are out-of-sync. There is only one truth, the truth in the
> control. Note
> that because I rely on the truth of the control, there is never a need to
> have the string
> value kept in a member variable at all! In fact, it is not at all clear
> why you wrote the
> equivalent of
> B = A:
> above, because A already has the value and there is no reason to make a
> copy of it in B!
> *****
>>
>>I'm asking the question because sometimes I fill like I'm creating more
>>data
>>variables than really needs to be. So, is it good practice to do it the
>>way
>>shown above? In reality (I just didn't show it), my data is private and
>>I
>>use Public "Get" & "Set" statements to get & set the variables. So below
>>is
>>the way I've been doing it.
> ****
> My opinion: if you have n data variables, you have n-too-many variables.
> ****
>>
>>Code:
>>UpdateData(true);
>>SetClientsName( m_editClientName );
> ****
> It is not clear why you need to do this inside the implementation. Not
> that it is bad,
> but if the whole point is to copy a private value to a public value, there
> are serious
> questions that should be asked, such as why there is even a private copy
> at all.
>>
>>Continued Code:
>>MyClass::SetClientsName ( CString strName )
>>{
>> m_strClentName = strName;
>>}
> ****
> What good does it do to set this name in a variable if the variable is not
> transferred to
> the control? The whole point of using a setter is that it should actually
> do something to
> make this internal copy be the control contents, or the control and the
> copy are
> out-of-sync and if the user types something we are going to have problems.
>
> Note that doing this right is not always easy or straightforward, but
> doing it wrong
> (UpdateData) is really easy and supported by the framework; so it is easy
> to get wrong.
>
> 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.
>
> We really need to have dialogs support the OnUpdateCommandUI mechanism;
> but I essentially
> do that explicitly with my constraint-based model (see my essay on dialog
> control
> management on my MVP Tips site)
> joe
> ****
>>
>>Thanks for your response.
>>
>>
>>
>>
> 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
"JCO" <someone(a)somewhere.com> wrote in message
news:uJXGecs7KHA.5820(a)TK2MSFTNGP04.phx.gbl...
> Joseph,
> I've read every ones comments and I understand that the UpdateData() can
> cause issues. If done your way, does this mean you create a control (ctl)
> variable for every control on your Dialog? This brings me to my next
> issue:
>
> Which method do you recommend to use?
> One: //no control variable used
> CString strName;
> CEdit *pName = (CEdit*) GetDlgItem(IDC_CUSTOMER_NAME);
>
> pName->GetWindowTextw(strName);
> SetCustomerName(strName);
>
>
> Two: //uses control variable
> CString strName;
> ctlEditCutomerName.GetWindowTextW(strName);
> SetCustomerName(strName);
>

Use Method 1. However, since GetWindowText is a method of CWnd, you don't
nee to cast to CEdit *:

CWnd *pName = GetDlgItem(IDC_CUSTOMER_NAME);
pName->GetWindowText(strName); // <-- note: no need to call
GetWindowTextW
SetCustomerName(strName);


This is important, it is technically illegal to cast the return of
GetDlgItem() to a CWnd derived class like CEdit. This is because the class
returned by GetDlgItem() is *not* a CEdit *, it is a CWnd * because that's
what was constructed when your dialog was initialized. It usually works out
that if the dialog control really is an edit control, that casting to CEdit
* will work but it is not a good idea.

If you find yourself having to cast in order to call methods declared only
in CEdit (and not in CWnd), use method 2, which constructs a real CEdit
instance to handle the dialog item.

-- David

From: Joseph M. Newcomer on
See below...
On Sat, 8 May 2010 10:57:11 -0500, "JCO" <someone(a)somewhere.com> wrote:

>Joseph,
>I've read every ones comments and I understand that the UpdateData() can
>cause issues. If done your way, does this mean you create a control (ctl)
>variable for every control on your Dialog? This brings me to my next issue:
****
It means I create a control variable for every control I care about. That's a different
statement. For example, for static labels (control ID IDC_STATIC) I don't bother to
create controls.
****
>
>Which method do you recommend to use?
>One: //no control variable used
>CString strName;
>CEdit *pName = (CEdit*) GetDlgItem(IDC_CUSTOMER_NAME);
****
This sucks. It is inappropriate.
****
>
>pName->GetWindowTextw(strName);
>SetCustomerName(strName);
>
>
>Two: //uses control variable
>CString strName;
>ctlEditCutomerName.GetWindowTextW(strName);
****
This is the only way I work. Except I would not use GetWindowTextW; that is the kind of
programming error Intellinonsense tends to introduce. I would have called GetWindowText.
****
>SetCustomerName(strName);
****
You have not specified what SetCustomerName does, or where it is declared. So I can't
comment on the behavior of this call.
****
>
>Method two seems easier, however, you must declare the control variable (not
>shown) which makes your code larger in size (I realize not much).
****
Frankly, if you are worried about this kind of issue, you need to get a grip on life. It
is a completely foolish concern. It means you think code size matters, and essentially,
code size never matters, not when you have a 2GB virtual address space. We are no longer
programming PDP-11 minicomputers with 64K of memory, and such concerns are misplaced.

Program like it is 2010, not 1975.
****
>My issue
>... the Dialog I'm working on has 30 CEditBox. Do I really need to create
>30 Control Variables (ex ctlCustomerName) plus 30 member variables (ex
>m_strCutomerName)? If I use the GetDlgItem(), I avoid the 30 Control
>Variables.
***
Sure. Why not? What possible problem could this cause? The GetDlgItem requires a cast,
which I consider disastrous. Look at any of the dialogs in any of the source code I
have. If I have 60 controls I have 60 control variables, so what? I cannot imagine doing
it any other way. I have one massive dialog that has a couple hundred control variables.
The GetDlgItem method is antiquated, a throwback to Petzold-style C programming, and
error-prone.
joe
****
>
>Thanks for your in-depth response to my original question.
>
>
>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:1i44u59hf7o13rrovvkbd5lfgd8fo0q0ke(a)4ax.com...
>> I am always offering a contrarian opinion on this: I would NEVER, EVER use
>> a variable to
>> hold a value except in some extremely rare and estoteric situations which
>> I hardly ever
>> encounter, so NEVER, EVER is a pretty good characterization of what I do.
>>
>> I make all the variables "control" variables which are just ways to name
>> the control, and
>> use methods of those variables to extract the data from the control, such
>> as
>> GetWindowText, GetCheck, GetCurSel, etc.
>>
>> I never, ever call UpdateData in a dialog or formview; I think the ONLY
>> valid times this
>> is called is when the framework calls them before OnInitDialog or after
>> OnOK is called,
>> and 99% of the time, I never use this capability either. I seriously
>> preach that the
>> whole DDX mechanism should not be used, EXCEPT for DDX_Control that binds
>> controls to
>> variables, and the entire DDV mechanism should be ignored completely, in
>> favor of
>> intelligent real-time input validation.
>>
>> I generally react to code that arrives on my desk by removing all these
>> variables and
>> removing all UpdateData calls, and replacing them with what I consider
>> sane and robust
>> code. I allow ONLY control variables to exist.
>> On Wed, 5 May 2010 14:23:35 -0500, "JCO" <someone(a)somewhere.com> wrote:
>>
>>>I have a general question concerning members of class and assigning the
>>>content. Particularly if I have a class that, for instance has an
>>>EditBox.
>>>If I use the Wizard, I can create a member data of type "Control" or
>>>"Variable". If I choose variable, the wizard does it's thing. Is this
>>>variable simply used as a conduit? Should it be used simply to set my
>>>actual data member that I created manually in my Class? Example.
>>>m_editClientName was created from the Wizard as type variable CString.
>>>m_strClientName was created by me as part of my private class member.
>>>
>>>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)
>> *****
>>>m_strClientName = m_editClientName; //editbox variable is simply a
>>>conduit to set my my actual member
>> ****
>> I would use
>> m_EditClient.GetWIndowText(m_strClientName);
>>
>> which makes it obvious what is going on; there is never a chance that the
>> variables and
>> the controls are out-of-sync. There is only one truth, the truth in the
>> control. Note
>> that because I rely on the truth of the control, there is never a need to
>> have the string
>> value kept in a member variable at all! In fact, it is not at all clear
>> why you wrote the
>> equivalent of
>> B = A:
>> above, because A already has the value and there is no reason to make a
>> copy of it in B!
>> *****
>>>
>>>I'm asking the question because sometimes I fill like I'm creating more
>>>data
>>>variables than really needs to be. So, is it good practice to do it the
>>>way
>>>shown above? In reality (I just didn't show it), my data is private and
>>>I
>>>use Public "Get" & "Set" statements to get & set the variables. So below
>>>is
>>>the way I've been doing it.
>> ****
>> My opinion: if you have n data variables, you have n-too-many variables.
>> ****
>>>
>>>Code:
>>>UpdateData(true);
>>>SetClientsName( m_editClientName );
>> ****
>> It is not clear why you need to do this inside the implementation. Not
>> that it is bad,
>> but if the whole point is to copy a private value to a public value, there
>> are serious
>> questions that should be asked, such as why there is even a private copy
>> at all.
>>>
>>>Continued Code:
>>>MyClass::SetClientsName ( CString strName )
>>>{
>>> m_strClentName = strName;
>>>}
>> ****
>> What good does it do to set this name in a variable if the variable is not
>> transferred to
>> the control? The whole point of using a setter is that it should actually
>> do something to
>> make this internal copy be the control contents, or the control and the
>> copy are
>> out-of-sync and if the user types something we are going to have problems.
>>
>> Note that doing this right is not always easy or straightforward, but
>> doing it wrong
>> (UpdateData) is really easy and supported by the framework; so it is easy
>> to get wrong.
>>
>> 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.
>>
>> We really need to have dialogs support the OnUpdateCommandUI mechanism;
>> but I essentially
>> do that explicitly with my constraint-based model (see my essay on dialog
>> control
>> management on my MVP Tips site)
>> joe
>> ****
>>>
>>>Thanks for your response.
>>>
>>>
>>>
>>>
>> Joseph M. Newcomer [MVP]
>> email: newcomer(a)flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm