From: Joseph M. Newcomer on
I consider the code below very bad. First, you should never use commas in a declaration
list. If you want two CStrings, you would write
CString rString;
CString rString2;

then NEVER use GetDlgItemText in MFC; create a control variable and use GetWindowText.

The SetWindowText sets the text of the CURRENT window, because you did not tell it what
window to set, so you are changing the caption of the window. Since a CFormView does not
actually have a caption, the text is never displayed.

The correct code would be

CString rString;
CString rString2;

c_EditBox.GetWindowText(rString);
c_EditBox.SetWindowText(_T("555"));
c_EditBox.GetWindowText(rString2);
c_EditBox.GetWindowText(rString);

Note that since you have done nothing to change the contents of rString2, it should not
surprise you that it is still 555.

Remember, SetWindowText(_T("555")) translates as
this->SetWindowText(_T("555"))
and GetWindowText(rString2). translates as
this->GetWindowText(rString2);

but you do not want to change the caption of the dialog, so you have to specify explicitly
what window you want to work on!
joe

On Sat, 8 May 2010 22:14:30 -0400, "RB" <NoMail(a)NoSpam> wrote:

>Actually I added a couple of lines and seemingly solved this myself
>but would also like comments on another question at bottom.
>
>CString rString, rString2;
>GetDlgItemText( IDC_EditBox, rString);
>//rString now equals {"444"}
>SetWindowText(_T("555"));
>GetWindowText(rString2);
>GetDlgItemText( IDC_EditBox, rString);
>//rString still equals {"444"}
>//rString2 still equals {"555"}
>SetDlgItemText(IDC_EditBox, _T("555"));
>GetDlgItemText( IDC_EditBox, rString);
>//rString now equals {"555"}
>//rString2 still equals {"555"}
>
>It appears that Get(or Set)DlgItem does reference the EditBox control
>but GetWindowText does not.
>Additionally I find that accessing the IDC_EditBox in this method ties the
>value to a string, which could be converted of course, but to actually get
>the value to be a double to start with you have to declare IDC_EditBox
>variable of double type in the class wizard. And then it would appear you
>would have to use DDX (?? ) to access this variable or am I missing
>something ?
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: RB on
Hey Joe, thanks for replying:
In reference to my original post main request
"What is the best way to get and set the contents of an EditControl
(in a FormView) , other than using DDX."

> then NEVER use GetDlgItemText in MFC; create a control variable
>and use GetWindowText.

Ok, good so far, you tell me the best way is GetWindowText. But
I am still confused, when you create a control variable don't you have
to use DDX to access it ? In other words doesn't GetWindowText
only access the text in the window and not a control variable of say
type double ? And further did I understand you to previously say in
another thread not to use DDX ? (I sense I am not correct here but
still confused )
Or are you saying to create a control variable of type control (not value)
and use that instance to access the control variable of type double ?
If so, then I surmise this method is not tied into the DDX routines ?

> The SetWindowText sets the text of the CURRENT window, because
> you did not tell it what window to set, so you are changing the caption
> of the window. Since a CFormView does not actually have a caption,
> the text is never displayed.

> The correct code would be
> c_EditBox.GetWindowText(rString);
> c_EditBox.SetWindowText(_T("555"));
> c_EditBox.GetWindowText(rString2);
> c_EditBox.GetWindowText(rString);

Oh ok I can see now how I can isolate which window receives the
Get/SetWindowText call. I was wondering how this would take place

I will play around with this tonight when I get in, right now I am due at
my wife's mother's day dinner. Thanks again for all your help (and patience).
RB


From: Joseph M. Newcomer on
See below...
On Sun, 9 May 2010 09:13:43 -0400, "RB" <NoMail(a)NoSpam> wrote:

>Hey Joe, thanks for replying:
>In reference to my original post main request
>"What is the best way to get and set the contents of an EditControl
> (in a FormView) , other than using DDX."
>
>> then NEVER use GetDlgItemText in MFC; create a control variable
>>and use GetWindowText.
>
>Ok, good so far, you tell me the best way is GetWindowText. But
>I am still confused, when you create a control variable don't you have
>to use DDX to access it ?
****
No. It is a variable, and it has a type, and that type is a class, and that class has
methods. At no point do you need to use DDX to get the contents of the control.
****
>In other words doesn't GetWindowText
>only access the text in the window and not a control variable of say
>type double ?
****
GetWIndowText will send a WM_GETTEXT message to the control. Period. It only uses the
control variable to get the HWND so it can do a SendMessage(m_hWnd, WM_GETTEXT, ...) to
get the text. No string variables are used other than the ones you suppy. It gives you a
string, and if you want a double you should use _atof (prior to VS.NET) or _ttof (VS.NET
2002 and later). If you use the DDX method, and the target is a double, you get an
implicit _atof/_ttof conversion, both of which are naive and assume that if any non-digit
appears, the number is done. So it will accept 12ABC and call it "12" or "1.Z" and call
it "1". This is why I created my Validating Edit Control, so it will only accept valid
floating point numbers, and it you GetWindowText you will KNOW that it is a valid floating
point number (there is a function call IsValid that returns a BOOL that says if the
contents of the control are valid; this is because I want to KNOW if I have a valid number
there, not rely on some internal conversion to ignore syntax errors in the contents).

Another reason I don't use DDX to get values is that the DDX conversions are so mindlessly
simple that they won't report errors if the value is an ill-formed integer or floating
point number. This is unacceptable behavior. In addition, I would NEVER want an annoying
dialog box to pop up and say a number was invalid. This is poor GUI design. I do not do
poor GUI design. So as created, the design is horrible, and possible "fixes" would result
in an even more horrible design. So I choose to avoid it by not using these klunky
techniques. I created controls that validate their own input and I use those.
****
>And further did I understand you to previously say in
>another thread not to use DDX ? (I sense I am not correct here but
>still confused )
****
A control is bound to a Control variable using the DDX_Control call; note that I said I
avoid DDX *except* for the DDX_Control calls. I never, ever use any DDX control that
returns a value!
****
>Or are you saying to create a control variable of type control (not value)
>and use that instance to access the control variable of type double ?
>If so, then I surmise this method is not tied into the DDX routines ?
****
For example, if I put a double in a variable of type double, what kind of conversion am I
going to get when it is converted to a string? Is it going to say "1" "1.", "1.0", or
"1.000". Suppose I want it to *always* use *exactly* three digits in the conversion? I
don't see how I can get that (I can write

c_Distance.SetWindowText(ToString(_T("%6.3f"), value)));

which uses my "ToString" function which works like CString::Format but returns the string
value; you can find it on my MVP Tips site)

Overall, I consider the whole DDX-value and DDV mechanisms to be kludges that do not
adequately address the real problems of building robust, smooth, usable interfaces.
****
>
>> The SetWindowText sets the text of the CURRENT window, because
>> you did not tell it what window to set, so you are changing the caption
>> of the window. Since a CFormView does not actually have a caption,
>> the text is never displayed.
>
>> The correct code would be
>> c_EditBox.GetWindowText(rString);
>> c_EditBox.SetWindowText(_T("555"));
>> c_EditBox.GetWindowText(rString2);
>> c_EditBox.GetWindowText(rString);
>
>Oh ok I can see now how I can isolate which window receives the
>Get/SetWindowText call. I was wondering how this would take place
****
SetWindowText and GetWindowText are methods of CWnd, so they apply to a CWnd. You have to
tell it *which* CWnd! By default, it is this-> because that's how C++ scope resolution
rules work! This has nothing to do with MFC, or controls, but is fundamentally how C++
works.
joe

****
>
>I will play around with this tonight when I get in, right now I am due at
>my wife's mother's day dinner. Thanks again for all your help (and patience).
>RB
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: RB on
> Joseph M. Newcomer wrote:
> A control is bound to a Control variable using the DDX_Control call; note that
> I said I avoid DDX *except* for the DDX_Control calls. I never, ever use any
> DDX control that returns a value!
> ****
> Overall, I consider the whole DDX-value and DDV mechanisms to be kludges
> that do not adequately address the real problems of building robust, smooth,
> usable interfaces.
> ****
---------
Hey Joe thanks for replying again. I think I have gotten much of what you
have given me. Basically don't use DDX variables for direct assignment
but it is ok for DDX_Control calls. In other words if I
// From my View header file
//{{AFX_DATA(CMyAppView)
enum { IDD = IDD_MyApp_FORM };
CEdit m_EditBox;
//}}AFX_DATA

//From my View cpp file
void CMyAppView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyAppView)
DDX_Control(pDX, IDC_EditBox, m_EditBox);
//}}AFX_DATA_MAP
}

//Then inside the pertinant handler
CString rString;
m_EditBox.GetWindowText(rString);
m_EditBox.SetWindowText(_T("555"));
// This is the best way to Set and Get the EditBox's contents, Correct?



From: Goran on
On May 9, 3:42 am, "RB" <NoMail(a)NoSpam> wrote:
> Thanks David, I did check this out and experimented with it
> along with CWnd::GetWindowText.  I have the debugger
> results behind comments below.  All of this code is in my ViewClass
> and occurs incremetally with nothing in between that is not shown.
> Execution comes to here from an Button Ctrl handler.
> The intial 444 was entered into the IDC_Editbox prior to clicking
> the Button.
> I welcome comments from everyone on these:
>
> CString rString, rString2; // the two receiving items
>
> GetDlgItemText( IDC_EditBox, rString);
> //rString now equals {"444"} from initial user input to editbox
>
> SetWindowText(_T("555"));
> GetWindowText(rString2);
> //rString2 now equals {"555"} from the SetWindowText
>
> GetDlgItemText( IDC_EditBox, rString);
> //rString  still equals {"444"} however rString remains unchanged?
> //rString2 still equals {"555"}
> // Shouldn't rString have changed to 555 ?

Why should it? rString was given it's value in your first
GetDlgItemText, and was not touched since. You must clear in your head
how variables behave. You seem to think that, because you called
GetDlgItemText once using rString, rString should change every time
you call SetWindowText (or something along these lines). That is
seriously delusional.

You need to understand much, much more about programming in general.
Please do that first, before asking e.g. MFC-specific questions.

Goran.