finding the last active view from a modeless dlg
Lawrence_Chan_at_HONGKONG@pcmailgw.ml.com
Thursday, May 30, 1996
VC4.0 NT3.51
I am creating a modeless dialog that interacts with views in a MDI
application. The dialog contains 3 slide controls which the user can
slide up and down. When the left button is up, a user-defined message
is sent to the active view to tell the view to reflect the changes.
That's pretty straight forward in a SDI. But in a MDI how do you know
which view is active? (the current active window is the dialog
itself). I know you can iterate thru a bunch of
GetFirstDocTemplatePosition() or pDoc->GetFirstViewPostion() to get
all the views. A solution that I can think of is to have the modeless
dialog keeping a list of views currently in the application. Each time
a view is activated, the view tells the dialog to remember it is the
current active view.
An example of such a dialog is the Find dialog in Winword 6.0. When
the find button is pressed, it always goes and finds the string in the
document that was last active. When there are no active documents in
the window, the Find dialog disables the find button itself.
Is there a more elegant way to solve this problem?
Frederic Steppe -- FredericS@msn.com
Sunday, June 02, 1996
[Mini-digest: 8 responses]
> VC4.0 NT3.51
>
> I am creating a modeless dialog that interacts with views in a MDI
> application. The dialog contains 3 slide controls which the user can
> slide up and down. When the left button is up, a user-defined message
> is sent to the active view to tell the view to reflect the changes.
>
> That's pretty straight forward in a SDI. But in a MDI how do you know
> which view is active? (the current active window is the dialog
> itself). I know you can iterate thru a bunch of
> GetFirstDocTemplatePosition() or pDoc->GetFirstViewPostion() to get
> all the views. A solution that I can think of is to have the modeless
> dialog keeping a list of views currently in the application. Each time
> a view is activated, the view tells the dialog to remember it is the
> current active view.
You may try something like this :
CMDIChildWnd * pActiveChild;
CView * pActiveView;
pActiveChild = AfxGetMainWnd()->MDIGetActive();
if(pActiveChild != NULL) pActiveView = pActiveChild->GetActiveView();
Frederic Steppe (frederics@msn.com)
-----From: chucks@skypoint.com (Erik Funkenbusch)
Umm.. UpdateAllViews?
The approach I usually take is call UpdateAllViews, then in the OnUpdate
code of your child windows you have them detect if they are currently the
active MDI window via GetActiveView()
-----From: Mario Contestabile
If the CMDIChildWnd is the parent of the dialog, perhaps something like
CView* m_currentview = GetParent()->GetActiveDocument()->GetActiveView();
might work.
mcontest@universal.com
-----From: "Greg Tighe"
AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
This will return a pointer to the currently active view (the one on
top.) I believe it will return NULL if no documents (views) are
currently open.
-Greg Tighe
Applied Intelligent Systems, Inc.
Ann Arbor, MI
gdt@aisinc.com
-----From: Lawrence_Chan@pcmailgw.ml.com
Greg,
Thanks for your suggestion.
I tried your code and it works all right except that if I close all
the views, GetDescendantWindow will still return a pointer to the main
frame. But the problem is easily solved by doing:
CView * CFloatdlg::GetLastActivateView()
{
CWnd *pWnd= AfxGetMainWnd()->
GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))
return (CView *)pWnd;
return NULL;
}
-----From: Lawrence_Chan@pcmailgw.ml.com
You solved my first problems. Thanks very much.
The second problem has not been solved, at least for now. The CFloatDlg is
created by calling CFloatDlg::Create(). Memory is deallocated at
CFloatDlg::PostNcDestroy().
My design goal is that I don't want the application to know who created
CFloatDlg. As long as it is created, the FloatDlg does whatever interactions it
wants to the views(if it found one. <- solved...with your help). In my view I
have something like this:
void CMyView::OnViewFloatdlg()
{
CFloatdlg *pDlg= (CFloatdlg *)IsDlgFloating(); <<== need help on this
if (!pDlg)
{
pDlg= new CFloatdlg;
pDlg->Create(IDD_DIALOG1, this);
pDlg->CenterWindow();
pDlg->ShowWindow(SW_SHOWNORMAL);
}
else
pDlg->SetActiveWindow();
}
This way I don't need a member pointer to store the dialog. The question should
therefore be: How do I code the IsDlgFloating()?
In my opinion, the best way is to make use of the unique dialog identifier. By
passing the nID to IsDlgFloating(), the function returns a pointer to the dialog
or null if it couldn't find one floating. Could that be done?
----------------------------------------------------------------------------
First of all, did my suggestion (above) solve your (first) problem?
Secondly, how are you creating you modeless dialog? Are you calling
CDialog::Create()? In that case you must have allocated the CDialog
first, either dynamically or on the stack. So you should have either
a pointer to your CDialog or a CDialog member variable hanging around
somewhere. In this case just do something like the following:
if (NULL != m_pMyModelessDlg) // Only necessary if dialog is dynamically
allocated.
{
if (::IsWindow (m_pMyModelessDlg->GetSafeHwnd ()))
{
return m_pMyModelessDlg;
}
}
return NULL;
Hope this helps.
-Greg Tighe
Applied Intelligent Systems, Inc.
Ann Arbor, MI
gdt@aisinc.com
-----From: Lawrence_Chan_at_HONGKONG@pcmailgw.ml.com
Greg,
I tried it but it wouldn't work. Even if I force CFloatDlg to set its
parent to AfxGetMainWnd(), I still get NULL from
GetDescendantWindow(). I looked into WINCORE.CPP and found that
GetDescendantWindow() is basically a recursive function that iterates
through the child windows list and tries its luck on GetDlgItem.
So your suggestion should work!!! Truth is it did not. Do we have any other
alternatives in solving this?
_
Try removing the second parameter from your call to Create(). The
second parameter will then default to NULL which means the main
application window will be the parent of your floating dialog. As
you have it above means that one of the view windows will be the
parent of your floating dialog which is perhaps why you cannot find
it.
After you have done this try the following for IsDlgFloating():
AfxGetMainWnd()->GetDescendantWindow(IDD_DIALOG1, TRUE);
// I think you tried this before, but it always returned NULL,
// perhaps because the floating dialog was not a child of the main
// application window.
Let me know how this works.
-Greg Tighe
Applied Intelligent Systems, Inc.
Ann Arbor, MI
gdt@aisinc.com
| Вернуться в корень Архива
|