-
[MFC MDI] How to activate a view programmatically and safely ?
I've developing MFC-MDI applications and this application has tabbed document style.
I want to activate each view programmatically and using CMainFrame::SetActiveView method like below.
void CMyView::OnShowWindow( BOOL bShow ... )
{
CView::OnShowWindow( bShow, ... );
CMainFrame *mf = (CMainFrame*)AfxGetMainWnd();
mf->SetActiveView(this);
}
This code makes a view active programatically but has a critical problem that the application pops up the error about the activation of the context when I close a document.
How can I solve this problem?
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Maybe you need to do this only when bShow=TRUE.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Sorry I did it, but I'd forgot to write in the avobe code.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
lightshield
I've developing MFC-MDI applications and this application has tabbed document style.
I want to activate each view programmatically and using CMainFrame::SetActiveView method like below.
I don't understand. When do you want to activate a view?
What kind of behavior are you trying to implement?
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
lightshield
This code makes a view active programatically but has a critical problem that the application pops up the error about the activation of the context when I close a document.
How can I solve this problem?
Have you tried stepping into the mfc source code and finding out where the error has occurred? Often times, the MFC source code will have comments where the assertion occurs that helps you track down the problem.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
You didn't tell us the error and you didn't show all your code. Not much we can do at this point. I'm not really sure why you're doing it from OnShowWindow either.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
This tab's problem can be discussed abstractly.
MDI style application has the tabbed document style.
If one tab clicked then associated view will be activated and other views will be deactivated.
I want to implement this behavior programmatically but I've not found solutions yet.
Please give me gurus power.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
I think that the MFC has not had obvious method to implement this behavior programmatically because of nothing of requirements for this purpose.
I'd implemented desired behavior by an other agenda. But if programmatic methods for this purpose exists, I want to know these.
So please try to answer this problem. Thanks all.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Did you even look at MSDN? If you had, you probably would have found
CMDIFrameWnd::MDIActivate
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Yes, I had
But MDIActivate didn't work with tabbed document style. I had used CMDIFrameWnd::SetActiveView alternatively and this makes the objective view active but an exception occurs when I close arbitrary documents.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
I say this situation other words, MDIActivate and SetActiveView functions didn't emulate 'click on a tab' behavior.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
lightshield
I say this situation other words, MDIActivate and SetActiveView functions didn't emulate 'click on a tab' behavior.
Did you pass a view pointer or a MDI child pointer. I believe it wants a CChildFrame pointer rather than a view.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Yes, I did.
I'd tried some way using CView* or CChildFrame* with CMDIFrameWnd::SetActiveView, but I can't solve an exception. But, therefor, this method can activate the desired view.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
lightshield
Yes, I did.
I'd tried some way using CView* or CChildFrame* with CMDIFrameWnd::SetActiveView, but I can't solve an exception. But, therefor, this method can activate the desired view.
I'm having trouble following what you're saying here. What exception?
Can you show the code you tried.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Sorry, now I can't show you the entire of my code.
But I'll prepare test code as possible.
An exception that occurs when I close documents arbitrary after activate one view. Exception messages are like below
'A deactivating object is not a recently activated object'
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
lightshield
Sorry, now I can't show you the entire of my code.
But I'll prepare test code as possible.
An exception that occurs when I close documents arbitrary after activate one view. Exception messages are like below
'A deactivating object is not a recently activated object'
Did the call work otherwise?
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
An exception message is like below
'A deactivating object is not a recently activated object.'
GCDEF, please show the tail of my first post. thanks
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Sorry for my duplicated post.
What about 'the call' and what means 'work' ?
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
I've made the VC solution to repro this problem.
I'll upload files to some server soon.
And I fix my words that the exception occurs when I close 'the application', not a document.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
https://skydrive.live.com/?cid=578e0...8337%21103
An above link is for the repro program and download 'mditest.zip'.
1. build the solution
2. run the mditest.exe and create at least 2 documents.
3. close the application from 'X' button -> exception will be invoked.
Please try it.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
At a quick glance you're switching the view in the child frame instead of activating the correct frame. I'm not sure why you're even doing that. If you comment out the call to ForceActivate the program behaves the same way. Use the MDIActivate function and pass in a pointer to a child frame as I said instead of switching the view in the active frame.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
I'd already tried ways that you said but I couldn't emulate 'click on a tab' behavior.
I've known that above code is incorrect. I just want to know ways for 'click on a tab' behavior.
MDIActivate method does not work this purpose by calling this method simply.
In other words, make the procedure of OnActivateView same as tab-click.
But I found a strange thing that existing documents will be deactivated when the new document created. This may be same behavior as tab-click.
Therefor, I couldn't get same result. fmmm
I got the another way to avoid this problem now. But It's difficult problem to emulate the tab-click behavior.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
I've solved this problem by enumerating documents from document templates and proceed desired behavior.
It's a safe way to synchronize between each view.
GCDEF, thank you for this log conversation.
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
try this code:
POSITION pos = GetMDITabGroups().GetHeadPosition();
while(pos){
const CObject* obj = GetMDITabGroups().GetNext(pos);
CMFCTabCtrl* tab = (CMFCTabCtrl*)obj;
int count = tab->GetWindowedChildCount();
for(int i=0; i<count; i++){
tab->ActivateMDITab(i);
if(openedScenario==GetActiveView()){
break;
}
}
}
-
Re: [MFC MDI] How to activate a view programmatically and safely ?
Quote:
Originally Posted by
wootra
try this code:
POSITION pos = GetMDITabGroups().GetHeadPosition();
while(pos){
const CObject* obj = GetMDITabGroups().GetNext(pos);
CMFCTabCtrl* tab = (CMFCTabCtrl*)obj;
int count = tab->GetWindowedChildCount();
for(int i=0; i<count; i++){
tab->ActivateMDITab(i);
if(openedScenario==GetActiveView()){
break;
}
}
}
the openedScenario is the View you wanted to activate.
you can know what view you want to active in the other way.
I had same problem, but I couldn't find the way to solve this problem. So I leave my solution here.
-
1 Attachment(s)
Re: [MFC MDI] How to activate a view programmatically and safely ?
An MDI application with "tabbed views" can have zero, one or more tab groups.
Here is an example of one having two tab groups.
Attachment 33245
If you want to programmatically activate a tab item (and its associated view) from a given tab group you have to do the following:
- call CMDIFrameWndEx::GetMDITabGroups to get a list of tab groups (this is a list of CMFCTabCtrl pointers, one for each tab group);
- get the desired tab group from the list;
- call CMFCTabCtrl::ActivateMDITab to activate the desired tab item (and the associated view).
And here is a sample code:
Code:
BOOL CMainFrame::_ActivateTab(INT_PTR nTabGroupIndex, int nTabItemIndex /*= -1*/)
{
BOOL bRet = FALSE;
const CObList& list = GetMDITabGroups();
POSITION pos = list.FindIndex(nTabGroupIndex);
if(NULL != pos)
{
const CObject* pTabGroup = list.GetAt(pos);
VERIFY(pTabGroup->IsKindOf(RUNTIME_CLASS(CMFCTabCtrl)));
if(NULL != pTabGroup)
{
CMFCTabCtrl* pTabCtrl = (CMFCTabCtrl*)pTabGroup;
if(pTabCtrl->GetTabsNum() > nTabItemIndex)
{
pTabCtrl->ActivateMDITab(nTabItemIndex);
bRet = TRUE;
}
}
}
return bRet;
}
Code:
void CMainFrame::OnSomeCommand()
{
// just for demo purpose
// activate the third tabbed view from the first tab group
VERIFY(_ActivateTab(0, 2));
}