Re: Single Document MDI-like interface questions
On 23 jul, 20:31, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Thu, 23 Jul 2009 14:10:43 +0200, "Mikel" <mikel.luri_NOSPAM@gmail_NOSP=
AM.com> wrote:
Hi all:
I'm creating a single-document MDI-like application. You know, several
different views on a single document, in an MDI framework.
I'd like it to have a CFormView as a main view, where the user can set s=
ome
"Project" settings and from which the user can open the other views.
So far, I've created the CFormView MDI app, and changed the "new documen=
t"
handling mechanism to close the current document and open a new one, so =
that
only one document (and one FormView) is open at any time. I've also adde=
d
two views, and by following Joe's example in
http://groups.google.es/group/microsoft.public.vc.mfc/browse_thread/t...=
, I
can open them via a menu handler:
void CMainFrame::OnOpenGreenView()
{
OpenGreenView();
}
void CMainFrame::OpenGreenView()
{
if (pGreenViewTemplate == NULL)
{
pGreenViewTemplate = new CMultiDocTemplate(IDR_GreeVie=
wTYPE,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CGreenChildFrm),
RUNTIME_CLASS(CGreeView));
CMyDoc* doc = (CMyDoc*)GetCurrentDocument();
CFrameWnd* frame = pGreenViewTemplate->CreateNewFrame(=
doc, NULL);
if (frame != NULL)
{
frame->InitialUpdateFrame(doc, TRUE);
}
}
}
I have the same for the other view, say RedView.
Now, how can I handle the situation where the user closes the view and l=
ater
tries to open it?
****
Closes which view?
****>Right now it doesn't open, because the MultiDocTemplate is not destr=
oyed.
****
The point of the code is that the MultiDocTemplate is not *supposed* to b=
e destroyed, at
least not until the CMainFrame::OnDestroy or CMainFrame::~CMainFrame hand=
ler. THe whole
point of the code is that it may or may not already exist, but if it does=
n't it is created
at the point where it is first needed, and retained until the program ter=
minates. So you
can't say "it doesn't open because the MultiDocTemplate is not destroyed"=
.. It may not
open for some OTHER reason (that's why single-stepping was invented in th=
e debugger) but
it is *not* because the template is not destroyed! The template should=
be created ONCE. I
just chose to not bother to create it until it was needed.
****>I've thought of posting a message to the MainFrame when the ChildFra=
me is
destroyed, so it can destroy the CMultidocTemplate and set it to NULL.
****
That would be a mistake. There is no REASON to destroy the template, a=
nd in any case, you
must not.destroy it because it must exist!
****>Other
idea I've come across is to hide or minimize the ChildFrame instead of
destroying it and when the user tries to open it again, restore it, but =
I'm
not really sure how to do this.
****
No, this would be wrong. When you destroy the view, you *want* the chi=
ld frame to be
destroyed!
****
Another problem is I don't know how to switch to an open view. For examp=
le,
the three views are open and maximized, the active one is the FormView, =
and
the user clicks on "open the GreenView". I'd like it to switch to the on=
e
that's already open.
****
That case is simple. You just get the current active document, and cal=
l its method
ActivateView(RUNTIME_CLASS(CGreenView)). Since you have made sure you =
have only one
instance of each view, you define this as
BOOL CMyDocument::ActivateView(CRuntimeClass * act)
{ /* scan views */
POSITION pos = GetFirstViewPosition();
while(pos != NULL)
{
CView * view = GetNextViewPosition(pos);
if(IsKindOf(view, act))
{ /* found it */
CMDIChildWnd * wnd = (CMDIChildWnd *)view->G=
etParentFrame();
wnd->MDIActivate();
return TRUE;
} /* found it */
} /* scan views */
return FALSE;
}
Now when you come in to the CreateGreenView handler in the main frame, yo=
u first call
GetActiveDocument(). If this returns NULL, you are in trouble, since t=
he menu item should
not have been activated and you shouldn't be here. If it is non-NULL, =
you would call the
ActivateView(RUNTIME_CLASS(GreenView)); if it returns TRUE, the view exis=
ts and has been
activated; if it returns FALSE, you create the view.
****
I guess I have to get the ChildFrame from the
CMultiDocTemplate and activate it, but I don't know how to do it, as thi=
s is
my first incursion in the MDI world.
****
I wouldn't deal with the template; I'd have the document worry about it.
****
And the last, for now: I'd like to open the "Green" and "Red" views in
response to button clicks in the form view, instead of (or in adition to=
)
menu commands. How should I do this? Send a message to the MainFrame in =
the
button handler, maybe?
****
In this case, I would have the CFormView do as you describe; send a user-=
defined message,
such as UWM_ACTIVATE_VIEW, which contains the RUNTIME_CLASS of the view i=
n its WPARAM or
LPARAM. Then some simple if-tests and call the appropriate OnXXXXView =
handler.
****
Thanks in advance for your patience. As I said, I'm new to MDI.
Mikel
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm- Ocultar texto de la cita -
- Mostrar texto de la cita -
Thanks, Joe. What you suggest is, more or less, what I ended up doing,
and it is working fine.
Now I have a solution, I see that what I was trying to do was quite
silly. Anyway, thanks
Mikel