Re: Benefits of Protected Construtors in MFC
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Thu, 22 May 2008 09:34:19 -0400
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;
****
Joseph M. Newcomer [MVP]
If you help me to understand this concept i will be very glad
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Benefits of Protected Construtors in MFC
- From: Ian Semmel
- Re: Benefits of Protected Construtors in MFC
- References:
- Benefits of Protected Construtors in MFC
- From: sawer
- Benefits of Protected Construtors in MFC
- Prev by Date: Re: Displaying 120 Mega Pixels in 256 MB Video RAM
- Next by Date: Do indexed colors of a color palette save any conventional RAM?
- Previous by thread: Re: Benefits of Protected Construtors in MFC
- Next by thread: Re: Benefits of Protected Construtors in MFC
- Index(es):
Relevant Pages
|