MDI list in the status bar ( and a custom Window List dialog )
Download demo 141K

1. What is this ?
Some time ago, Carlos Alberto Silva asked me for a way to display in the Window dialog
list different names from the ones in title bar. We end up with this thing: it's basically
a replacement for the standard Window List Dialog (the one from the Window menu, I mean)
and a tab control inserted in the status bar acting like the start menu bar.
The title of the MDI windows can be different from the one displayed in the title bar.
2. How to implement this thing
You'll need to add to your project those classes:
- CViewManager
- CWindowListDlg
- CWindowTabCtrl
The CWindowListDlg is a dialog resource, so add it using the standard add components
way or manually copy its dialog template resource.
Now inlude in the view cpp file and in the mainframe cpp this header:
#include "ViewManager.h"
In the mainframe, get an handler for the wm_close message and write this:
void CMainFrame::OnClose()
{
theViewManager.RemoveAll();
theViewManager.bClosing = true;
CMDIFrameWnd::OnClose();
}
In the view contructor, add this line:
CMDIWindListView::CMDIWindListView()
{
theViewManager.AddView("", this);
}
and it the view destructor, this one:
CMDIWindListView::~CMDIWindListView()
{
theViewManager.RemoveView(this);
}
Last, in the view OnInitialUpdate we can define the view name:
void CMDIWindListView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CMDIWindListDoc * pDoc = GetDocument();
CString cs = pDoc->GetTitle();
cs += " -with custom text for window list";
theViewManager.SetViewName(cs, this);
}
With the SetViewName function we give the name we want to be displayed in the status
bar and in the window dialog list. If the standard name is good, simply pass the
document.GetTitle() text. You'll need to call this function every time the title of your
view changes (usually after a save).
3. Adding the status bar
If we want the status bar like the desktop bar, we'll need to do this modify to the
mainframe.
First add in the CMainFrame::OnCreate this line:
theWindowTab.Create(WS_CHILD|WS_VISIBLE|TCS_BUTTONS|TCS_FIXEDWIDTH|TCS_SINGLELINE|TCS_FORCELABELLEFT,
CRect(0,0,0,0), &m_wndStatusBar, 1000); Change the 1000 used as hardcode value
for the tab control as you like; it's not good practice to hard code the controls value.
Then, get an handler for the wm_size message and write this:
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIFrameWnd::OnSize(nType, cx, cy);
if (m_wndStatusBar.GetSafeHwnd() && theWindowTab.GetSafeHwnd())
{
CRect rc;
m_wndStatusBar.GetItemRect(0, rc);
theWindowTab.SetWindowPos(0,rc.left,rc.top,rc.Width(), rc.Height(), SWP_NOZORDER);
}
}
In this sample, I putted the tab control containing the windows in the status bar first
pane; if you want it to be as large as the status bar, try this:
if (m_wndStatusBar.GetSafeHwnd() && theWindowTab.GetSafeHwnd())
{
CRect rc;
m_wndStatusBar.GetWindowRect(rc);
m_wndStatusBar.ScreenToClient(rc);
theWindowTab.SetWindowPos(0,0,0,rc.Width(), rc.Height(), SWP_NOZORDER);
}
Or, if you want to put the tab in another pane, simply change the index of the
statusbar.GetItemRect.
4. The custom Window List Dialog
The custom window list dialog is invoked with the function:
theViewManager.DoWindowList();
Simply make a menu item named "my window list", handle it in mainframe and
call the function above.
That's all. The code is mine, the concept is of Carlos.
Enjoy!
Last updated: 2 July 1998

Comments
Some comments about the record of Tabs.
Posted by Legacy on 08/09/2001 12:00amOriginally posted by: Hanbo Sun
Instead of using CView poitners as key for search, delete, whatever. should use CWnd pointers to store the ChildFrm object as search keys. The reason for that is sometimes developper uses more than 2 views on a child frame. and view used as search key can be on top of another frame, so GetParent() function would not work out that covenient. Use CWnd * to store the ChildFrame can eliminate this problem.
ReplyExcellent!
Posted by Legacy on 05/10/2001 12:00amOriginally posted by: Kyle
It is excellent and fits my project quite well.
ReplyBut I have met some problems.
In my project I fixed the size of each item, so I
hope there will be a scrollbar in the tabctrl
after I have added enough items.
But the scrollbar only apeared after I have deleted one
item though there already were many items.
Why?
And another problem is when I click the right scrollbar,
it doesn't work properly sometimes.
Why?
Who can help me?
Cool, but small bug.
Posted by Legacy on 08/16/2000 12:00amOriginally posted by: Jamie Nordmeyer
First, let me say that this is a very cool piece of work. It's exacltly what I needed in my app. One extremely small bug, though. If you have enough documents open that the tabs are forced to resize, when you begin closing those windows one by one, the tabs say the same size. In other words, if you open 20 documents, the tabs are fairly small (you can't read all the lettering on the tab). When you start closing windows, their size doesn't adjust. To fix this, add
#include "ViewManager.h"
to the .cpp file of your Child Frame class. Add a handler for PostNcDestory to the Child Frame, and modify the code as such:
void CChildFrame::PostNcDestroy()
{
theWindowTab.ResizeTabs();
CMDIChildWnd::PostNcDestroy();
}
Now, as you close windows, the tabs will resize them selves properly.
Reply