Introduction
This trick will illustrate a method to get rid of close menu from CDockablePane
. If if you have just one CDockablePane
in your application, it is just enough to override CanBeClosed()
method inside your pane, but if you have more panels, when you attach them one in another, then "close" menu button shows up again.
Background
Once, I had the same issue to solve, and guided by others, I had solved ... and because I spot several questions regarding this, I decided to write a little tip for those who have the same task.
Using the Code
You can use the CNonClosableDockablePane
class inside of your project, and derive your own CDockablePane
from this class ... this class will do everything it needs in order to hide the "close" menu.
Here, I list the source code of this CNonClosableDockablePane
class:
#define AFX_NON_CLOSE_DOCKING_PANE_STYLE AFX_CBRS_FLOAT | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE
class CNonClosableDockablePane : public CDockablePane
{
DECLARE_DYNAMIC(CNonClosableDockablePane)
public:
CNonClosableDockablePane();
virtual ~CNonClosableDockablePane();
virtual CTabbedPane* CreateTabbedPane();
protected:
virtual BOOL CanAdjustLayout() const {return ! m_bIsSliding || ! m_bIsHiding;}
virtual BOOL CanBeClosed() const {return FALSE;}
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
DECLARE_MESSAGE_MAP()
};
The implementation of this class can be found inside the sample project.
Then, all you need to do is to derive your CDockablePane
from this class.
#include "NonClosableDockablePane.h"
class CMyPanelWnd : public CNonClosableDockablePane
{
...
}
And when you create your panels, you setup AFX_NON_CLOSE_DOCKING_PANE_STYLE
style for CDockablePane
tabbed bar. Suppose you have 3 panels in your application ... then here is a little sample of how to handle them to get rid of "close" menu button:
AddPane(&m_wndPane1);
AddPane(&m_wndPane2);
AddPane(&m_wndPane3);
m_wndPane1.EnableDocking(CBRS_ALIGN_ANY);
m_wndPane2.EnableDocking(CBRS_ALIGN_ANY);
m_wndPane3.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndPane1);
CDockablePane* pTabbedBar = NULL;
m_wndPane2.AttachToTabWnd(&m_wndPane1, DM_SHOW, TRUE, &pTabbedBar);
m_wndPane3.AttachToTabWnd(&m_wndPane1, DM_SHOW, TRUE, &pTabbedBar);
EnableAutoHidePanes(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
pTabbedBar = (CDockablePane*)m_wndPane1.GetParentTabbedPane();
if(NULL != pTabbedBar->GetSafeHwnd())
pTabbedBar->SetControlBarStyle(AFX_NON_CLOSE_DOCKING_PANE_STYLE);
pTabbedBar = (CDockablePane*)m_wndPane2.GetParentTabbedPane();
if(NULL != pTabbedBar->GetSafeHwnd())
pTabbedBar->SetControlBarStyle(AFX_NON_CLOSE_DOCKING_PANE_STYLE);
pTabbedBar = (CDockablePane*)m_wndPane3.GetParentTabbedPane();
if(NULL != pTabbedBar->GetSafeHwnd())
pTabbedBar->SetControlBarStyle(AFX_NON_CLOSE_DOCKING_PANE_STYLE);
In order to give a real sample of this method, I have attached a little sample project. Enjoy it!
Points of Interest
This solution has been tested on VS2008 and VS2010, but I am pretty sure that will work on newer Visual Studio versions ... if not, just give me a sign.
Update: I have uploaded a solution that will solve this issue when CDockablePane
is part of CMainFrame
.