Prev: How to let a CFrameWnd based SDI application start in full screen?
Next: update CDialog region in a user defined message handler
From: Giovanni Dicanio on 14 Jun 2010 06:03 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 14 Jun 2010 09:38 > 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 14 Jun 2010 09:59 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 14 Jun 2010 10:35 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 14 Jun 2010 11:43
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 |