From: Giovanni Dicanio on
On 13/06/2010 21:34, RB wrote:

> Thanks Giovanni, worked like a charm, though I changed the
> SetVersionString function to no args. I have a couple of
> questions if you would be so kind. See code and comments
> below. Questions are at very bottom in the OnInitDialog.

> class CAboutDlg : public CDialog
> {
> private:
> CString m_strVersion;
> public:
> void SetVersionString( );

If the SetVersionString method is not designed to be called from the
outside of the class, you could make it 'private' (so it can be
accessible only inside CAboutDlg class), or 'protected' (so it can be
accessible inside CAboutDlg class and classes derived from it).


> BOOL CAboutDlg::OnInitDialog( )
> { //** Class Wizard added base call ** //
> CDialog::OnInitDialog( );
>
> //** being added code //
> SetVersionString( ); // format the CString
> HWND hDlg = m_CtrlStaticVer.GetSafeHwnd( );
>
> //** Question 1.
> //** here I used the API SetWindowText to get a return, the
> // MFC SetWindowText was a void return, Is this a big deal ?
>
> BOOL bResult = ::SetWindowText(hDlg, m_strVersion);

Frankly speaking, in MFC code I've always used CWnd::SetWindowText
method (not the global raw Win32 API ::SetWindowText).

e.g. considering the m_CtrlStaticVer control class, I would just write:

m_CtrlStaticVer.SetWindowText( someString );

However, you are right that the return value of ::SetWindowText is lost
in this case.

In VC10 (VS2010), the implementation of CWnd::SetWindowText is like this:

<code>

void CWnd::SetWindowText(LPCTSTR lpszString)
{
ENSURE(this);
ENSURE(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

if (m_pCtrlSite == NULL)
::SetWindowText(m_hWnd, lpszString);
else
m_pCtrlSite->SetWindowText(lpszString);
}

</code>

So, the return value of ::SetWindowText is just discarded.
I would have preferred a method returning BOOL, to better wrap the raw
Win32 ::SetWindowText.

Note that ATL's CWindow::SetWindowText() correctly returns a BOOL, so it
is a better wrapper to ::SetWindowText:

http://msdn.microsoft.com/en-us/library/wfaxc8w5(VS.80).aspx

>
> //**Question 2
> //** Class Wizard put below return in ? when I had planned to return the
> //** the result of the SetWindow, Can you explain what this is all about ?
>
> return TRUE; // return TRUE unless you set the focus to a control
> // EXCEPTION: OCX Property Pages should return FALSE
> }

When you use a framework like MFC, it is better to follow the rules of
this framework, as indicated by the comments introduced by the MFC Wizard.

Note also that OnInitDialog method wraps the WM_INITDIALOG Win32
message, and in the "Return Value" paragraph you can read:

http://msdn.microsoft.com/en-us/library/ms645428(VS.85).aspx

<quote>

The dialog box procedure should return TRUE to direct the system to set
the keyboard focus to the control specified by wParam. Otherwise, it
should return FALSE to prevent the system from setting the default
keyboard focus.

</quote>


Giovanni
From: RB on
> void CWnd::SetWindowText(LPCTSTR lpszString)
> {
> ENSURE(this);
>............

Oh I see, I was also later stepping thru it and began to have
a hunch this was the case. So the importance of the return
is dimished quite a bit being that a failure is handled within.

> Note that ATL's CWindow::SetWindowText() correctly returns a BOOL, so it is a better wrapper to ::SetWindowText:

I will check out the link, I had wondered about CWindow class,
was curious why MFC would seemingly have two classes to do
much of the same stuff, but never really investigated it enough to
even know what was the story. Thanks for the info.

> When you use a framework like MFC, it is better to follow the rules of this framework, as indicated by the comments introduced by
> the MFC Wizard.
> Note also that OnInitDialog method wraps the WM_INITDIALOG Win32 message, and in the "Return Value" paragraph you can read:
> The dialog box procedure should return TRUE to direct the system to set the keyboard focus to the control specified by wParam.
> Otherwise, it should return FALSE to prevent the system from setting the default keyboard focus.

Well yes I should have thought of that being that it is a class handler it
has it's own adjenda rather than me implementing mine on it's return.
I should have thought to wrap the call to SetWindowText and then
deal with my return accordingly before letting OnInitDialog deal with
it's own adjenda. That was stupid on my part but none the less always
glad to hear words of wisdom from experience.
This could be the last correspondence I will experience on this group
(only time will tell ) but I appreciate all you guys have helped me on,
and hopefully I can get my NNTP set up so the forums won't be so
cryptic. RB


From: RB on
Thanks Joe, another novice stupid move on my part. One
thing about me, I am not afraid to screw up in order to move
forward.
But in reference to the dangerous code that you so informatively
detailed, I have rectified it (with the help of Giovanni ) and it is
now working great and I have learned another facet of programming
that hopefully will stick with me enough not to do it again. In
retrospect I had a hunch previously that much of what you said was
the case from remembering long ago when I tried writing small simple
API apps that had child windows.
This has taught me that I am leaning too much on what is visually
available in the Class Wizard rather than having the foresight to
have looked in the docs for CDialog class I would have found
in the OnInitDialog class member text, clearly showing that it
was the function I was needing. Even though I have my VS2005
now, I still do my experimentations in VC6 since I am so used to
it. But this is yet another reason to move on even in that facet.
If I don't see you on this group again, thanks ever so much for all
your help. RB


From: Giovanni Dicanio on
On 14/06/2010 15:38, RB wrote:

>> Note that ATL's CWindow::SetWindowText() correctly returns a BOOL, so it is a better wrapper to ::SetWindowText:
>
> I will check out the link, I had wondered about CWindow class,
> was curious why MFC would seemingly have two classes to do
> much of the same stuff, but never really investigated it enough to
> even know what was the story. Thanks for the info.

Actually, CWindow is an ATL class, completely different from CWnd.
CWindow is an inexpensive class to create: it's just a wrapper around an
HWND data member (instead, MFC maintains maps between HWND's and CWnd's...).
Moreover, when an instance of CWindow goes out of scope, the associated
window is *not* destroyed.

The spirit of ATL is different from the spirit of MFC: ATL is a more
thin wrapper around Win32 APIs, heavily uses templates, is leaner than
MFC, supports COM programming very well, etc.

There is a project called WTL which started internally in Microsoft and
then went open-source, that is built upon ATL, and offers several C++
wrapper classes to several Windows controls.


> That was stupid on my part

When you try to learn something there is nothing stupid about it :)


> This could be the last correspondence I will experience on this group
> (only time will tell ) but I appreciate all you guys have helped me on,
> and hopefully I can get my NNTP set up so the forums won't be so
> cryptic. RB

This newsgroup seems still active :)


Giovanni

From: Joseph M. Newcomer on
See below...
On Mon, 14 Jun 2010 09:38:50 -0400, "RB" <NoMail(a)NoSpam> wrote:

>> void CWnd::SetWindowText(LPCTSTR lpszString)
>> {
>> ENSURE(this);
>>............
>
>Oh I see, I was also later stepping thru it and began to have
>a hunch this was the case. So the importance of the return
>is dimished quite a bit being that a failure is handled within.
>
>> Note that ATL's CWindow::SetWindowText() correctly returns a BOOL, so it is a better wrapper to ::SetWindowText:
>
>I will check out the link, I had wondered about CWindow class,
>was curious why MFC would seemingly have two classes to do
>much of the same stuff, but never really investigated it enough to
>even know what was the story. Thanks for the info.
****
CWnd is the MFC class

CWindow is the ATL class

CWindow is a stripped-down lightweight class for use in ActiveX controls (primarily in
ActiveVIrus controls, those controls whose purpose in life is to be blocked by
intelligently-configured browsers)

You would not use CWindow in an MFC app.
****
>
>> When you use a framework like MFC, it is better to follow the rules of this framework, as indicated by the comments introduced by
>> the MFC Wizard.
>> Note also that OnInitDialog method wraps the WM_INITDIALOG Win32 message, and in the "Return Value" paragraph you can read:
>> The dialog box procedure should return TRUE to direct the system to set the keyboard focus to the control specified by wParam.
>> Otherwise, it should return FALSE to prevent the system from setting the default keyboard focus.
>
>Well yes I should have thought of that being that it is a class handler it
>has it's own adjenda rather than me implementing mine on it's return.
****
All methods designed by the framework are designed with the frameworks's "agenda" in mind.
Note that this also means that in a raw Win32 app (using windows but no MFC), that the
return value from the WM_INITDIALOG message is what the Windows framework defines it to
be, and has nothing to do with your wishes. In fact, the resturn value (or lack thereof)
for EVERY WM_, EM_, CB_, etc. message is predefined by the Windows framework!

The CDialog::OnInitDialog virtual method you override is just a reflection of the deep
functionality of the WM_INITDIALOG message, and corresponds to its requirements. It
doesn't care at all about yours, since you will never see the return value from
OnInitDialog (only the dialog box framework, an integral part of Windows, sees it)
****
>I should have thought to wrap the call to SetWindowText and then
>deal with my return accordingly before letting OnInitDialog deal with
>it's own adjenda.
****
You are clearly confused about "agendas" here. The "agenda" on WM_INITDIALOG is to allow
YOU to do what YOU want with the controls in the dialog. As such, it is not issued until
all the controls are created. The CDialog::OnInitDialog virtual method reflects this
functionality. Note that the root CDiallog::OnInitDialog calls the virtual method
DoDataExchange, and your virtual DoDataExchange method calls the parent class's
DoDataExchange, and so on up the line (this allows one dialog to derive from another!).
DoDataExchange, knowing that the controls now exist (a guarantee), will bind the controls
to the variables.

So I'm not sure what "agenda" is going on here. It *specifically* exists to allow you to
implment "your agenda".
joe
****
> That was stupid on my part but none the less always
>glad to hear words of wisdom from experience.
>This could be the last correspondence I will experience on this group
>(only time will tell ) but I appreciate all you guys have helped me on,
>and hopefully I can get my NNTP set up so the forums won't be so
>cryptic. RB
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm