MFC MDI tab activation
-
Friday, August 17, 2012 5:22 PM
Hi,
I have an MDI application. In case , there are several documents open and I close one, the newly activated document is the last one in the frame , not the last one I visited. How do I force the application to activate a document my choice after a random one was closed.
All Replies
-
Saturday, August 18, 2012 12:58 AM
You could reinvent the wheel and add a resizable, docking tab control to your application. You would have complete programmatical control over your tabs. It requires some understanding of dockable panes and you may have to renovate your app so it's a design issue.
Here are the links: note the remarks and examples.
http://msdn.microsoft.com/en-us/library/bb982549(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/bb984302.aspx
Here's how I did it:
// CreateTabControl - Creates the tab control. BOOL CTheApp::CreateTabControl(int nID) { CRect rectDummy; bp_dock->GetWindowRect(&rectDummy); bp_dock->ScreenToClient(&rectDummy); if (!m_wndTabs.Create(CMFCTabCtrl::STYLE_3D_ROUNDED_SCROLL, rectDummy, bp_dock, nID, CMFCTabCtrl::LOCATION_TOP, false)) { AfxMessageBox("Failed to create the tab control."); return false; } m_wndTabs.EnableAutoColor(); m_wndTabs.EnableActiveTabCloseButton(); m_wndTabs.EnableTabDocumentsMenu(); m_wndTabs.SetActiveTabBoldFont(); m_wndTabs.SetFlatFrame(false, true); m_wndTabs.SetDrawFrame(); m_wndTabs.EnableTabSwap(true); created_tab_control = true; return true; } // CreateTabControl(...)bp_dock is the basepane/mdiclient.
For reasons similar to yours I decided to make the conversion, but it has added a lot of time to my project.
PAC
- Proposed As Answer by Elegentin XieMicrosoft Contingent Staff, Moderator Tuesday, August 21, 2012 6:37 AM
- Marked As Answer by AlexanderZel Tuesday, August 21, 2012 1:59 PM
-
Tuesday, August 21, 2012 1:59 PMThanks PAC!
-
Wednesday, August 22, 2012 3:40 AM
I think there is much simpler solution, in agreement with my MEMC approach.
Any time active tab changes, CMFCBaseTabCtrl object send a message to the MDI client area window. Since default implementation of CMDIClientAreaWnd does not handle this message, tab object attempts to notify main window by sending the same message from FireChangingActiveTab.
Handling this message allows controlling what tab is activated. The message is AFX_WM_CHANGING_ACTIVE_TAB.
To insert the handler in VS 2010 or 2012 you can use Class Wizar. Since this is registered message, choose Messages tab and click on Add Custom Message. . .button at the bottom of the wizard dialog and enter AFX_WM_CHANGING_ACTIVE_TAB message.
In VS 2008 and earlier do this in the CMainFrame header file (as protected):
afx_msg LRESULT OnAfxWmChangingActiveTab(WPARAM wParam, LPARAM lParam);
In the implementation file, insert macro:
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) . . . ON_REGISTERED_MESSAGE(AFX_WM_CHANGING_ACTIVE_TAB, &CMainFrame::OnAfxWmChangingActiveTab) . . . END_MESSAGE_MAP()
Insert following implementation:
LRESULT CMainFrame::OnAfxWmChangingActiveTab(WPARAM wParam, LPARAM lParam) { CMFCTabCtrl* pTab = (CMFCTabCtrl*)lParam; int iTabsCount = pTab->GetTabsNum(); // removed? if(m_iCurrentTabCount <= iTabsCount) { m_iCurrentTabCount = iTabsCount; return 0; } m_iCurrentTabCount = iTabsCount; CWnd *pWnd = pTab->GetActiveWnd(); if(NULL == pWnd) { // determine what tab you want to activate // I used tab #1 just for demonstration purpose pTab->SetActiveTab(1); // do not allow any further tab activation return 1; } return 0; }I did not code any error checking or checking if tab you want to activate is within tab count. It is up to you to come up with the logic of determining next active tab. Instead I used arbitrary number 1 for the demo and testing purpose.
By the way: MEMC means Minimum Coding Maximum Effect.
JohnCz
- Edited by JohnCz Wednesday, August 22, 2012 3:41 AM
- Marked As Answer by AlexanderZel Thursday, August 23, 2012 1:53 PM
-
Thursday, August 23, 2012 1:53 PM
Thanks John! Long live the MEMC!!
-
Thursday, August 23, 2012 4:58 PMYou are very welcome, glad to be of help. Good luck.
JohnCz Please consider voting if you find this post helpful.

