Re: Benefits of Protected Construtors in MFC

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



I use public constructors when I have embedded FormViews derived from a class which lives in a static library.

There is a bit of jiggery-pokey involved but it works.

"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message news:bvsa34trchvjbvjs64g13a19o0385ik2hf@xxxxxxx:

See below...
On Thu, 22 May 2008 03:16:01 -0700, sawer <sawer@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:


>Hi
>
>I want to ask you about logic behind the protected constructors in MFC.
>Firstly i want to give an example. This make easier to explain the problem.
>
>I added a class which is driven from CView class. And i want to show it when
>clicked "View->New Window" menu.
>***********************
>#pragma once
>
>
>// code view
>
>class code : public CView
>{
> DECLARE_DYNCREATE(code)
>
>protected:
> code(); // protected constructor used by dynamic creation
> virtual ~code();
>
>public:
> virtual void OnDraw(CDC* pDC); // overridden to draw this view
>#ifdef _DEBUG
> virtual void AssertValid() const;
>#ifndef _WIN32_WCE
> virtual void Dump(CDumpContext& dc) const;
>#endif
>#endif
>
>protected:
> DECLARE_MESSAGE_MAP()
>};
>*************************
>
>I can not call like this:
>CView* pView = (CView*) new code; // error C2248 cannot access protected
>member

****
That's correct. You cannot access the protected member. Why would you want to? Doing
'new code' makes no sense. If you want a new view, you would create the new view using
the supported interfaces, which not only create the view, but initialize it properly.
****

>
>1-) Why are the wizard declare classes constructors protected or private?
>What is the benefit/logic? For example If i add class which is derived from
>CEdit with wizard, its constructors is declared public but if it is derived
>from CEditView its constructor is declared protected. Why is that so?

****
Because view constructors are protected for a reason: you are not supposed to be calling
them. So, deliberately, they are made protected. The rationale is that you do not know
how to create a view; it is more than just allocating an object. So don't do it. Do it
the right way.
****

>
>2-)Is changing protected to public best way?

****
No, it will do the wrong thing, and you will not be happy with the result. Why are you
confusing the concept of "create a new view" with "use the new operator"?
****

>
>3-) Where must i handle the menu selection, i mean creating new form. In
>MainFrm.cpp or something else?

****
I usually do this in the CMainFrame class; here's the code

I did this from the mainfrm.cpp file. The code goes like this:

Add a protected variable to the mainframe class:

CMultiDocTemplate * GreenTemplate;

In the CMainFrame::CMainFrame constructor, clear it out
GreenTemplate = NULL;
Add a new protected class member function
CDocument * GetCurrentDocument();
For symmetry, I added an additional variable
CMultiDocTemplate * RedTemplate;
and set it to NULL as well.

Create a new CView-derived class, in my case CGreenView (the names have been sanitized to
protected certain secure information).

The default view is a Red view, as exemplified by the standard InitInstance code:

pDocTemplate = new CMultiDocTemplate(IDR_RedViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CRedView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);


I added the following:

a new menu

#define IDR_GreenViewTYPE (xxx)

where xxx is a resource number you have not already used. In my case it was 130. It has
to have an ICON of that ID, and a STRINGTABLE resource of that ID, so the ID numeric value
cannot be used already in either a string, icon, or menu context.

I added to the Window menu of the exisiting IDR_RedViewTYPE the item
&Green View = ID_WINDOW_GREENVIEW
and to the new menu for the IDR_GreenViewTYPE the item
&Red View = ID_WINDOW_REDVIEW


I Created an icon of the ID IDR_GreenTYPE.

In mainfrm.cpp, I added the handler to create a Green View:

CDocument * CMainFrame::GetCurrentDocument()
{
CMDIFrameWnd * frame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
if(frame == NULL)
return NULL;
CMDIChildWnd * child = (CMDIChildWnd *)frame->GetActiveFrame();
if(child == NULL)
return NULL;
CView * view = child->GetActiveView();
if(view == NULL)
return NULL;
CDocument * doc = view->GetDocument();
return doc;
} // CMainFrame::GetCurrentDocument

void CMainFrame::OnWindowGreenview()
{
if(GreenTemplate == NULL)
GreenTemplate = new CMultiDocTemplate(IDR_GreenViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CGreenView));

CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
CFrameWnd * frame = GreenTemplate->CreateNewFrame(doc, NULL);
if(frame != NULL)
{ /* frame created */
frame->InitialUpdateFrame(doc, TRUE);
} /* frame created */
}

void CMainFrame::OnUpdateWindowGreenview(CCmdUI *pCmdUI)
{
CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
pCmdUI->Enable(doc != NULL);
}

And one for a Red view:

void CMainFrame::OnWindowRedview()
{
if(RedTemplate == NULL)
RedTemplate = new CMultiDocTemplate(IDR_RedViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CRedView));

CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
CFrameWnd * frame = RedTemplate->CreateNewFrame(doc, NULL);
if(frame != NULL)
{ /* frame created */
frame->InitialUpdateFrame(doc, TRUE);
} /* frame created */
}

void CMainFrame::OnUpdateWindowRedview(CCmdUI *pCmdUI)
{
CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
pCmdUI->Enable(doc != NULL);
}

To the destructor CMainFrame::~CMainFrame add
delete RedTemplate;
delete GreenTemplate;


****

>
>
>
>If you help me to understand this concept i will be very glad

Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

.



Relevant Pages

  • Re: Benefits of Protected Construtors in MFC
    ... I want to ask you about logic behind the protected constructors in MFC. ... virtual void Dumpconst; ... CMultiDocTemplate * GreenTemplate; ... cannot be used already in either a string, icon, or menu context. ...
    (microsoft.public.vc.mfc)
  • Re: [PHP] How can I do this -- method chaining
    ... I believe constructors return void, ... the 'new' keyword returns a copy of the object. ... public static function getInstance() { ...
    (php.general)
  • Re: template copy constructor
    ... auto_ptr without template functions, and it works. ... That's because you don't have any constructors from "wrong" odd_ptr ... X& operator*const throw; ... void resetthrow; ...
    (microsoft.public.vc.language)
  • Re: Best way to develop in parallel
    ... Both have exactly the same method signatures, constructors, etc. ... How can I easily switch between the classes? ... Have the test code refer to the interface and construct one or the other based on some condition. ... void testB() ...
    (comp.lang.java.help)
  • Re: Multiple views Single Document MDI
    ... CMultiDocTemplate * GreenTemplate; ... cannot be used already in either a string, icon, or menu context. ... void CMainFrame::OnWindowGreenview ... I dont know whether creating multiple document templates is a good ...
    (microsoft.public.vc.mfc)