Environment: ****** –>
Default system menu for standard MFC toolbar has maximize/minimize/restore ability. I didn’t like the
way the Maximized toolbar looked. Ben Summers and
Sushil Saxena already submited some ways to fix
MFC bars, however, I found another one:
MFC removes SC_SIZE from toolbar frame each time when it appears.
BOOL CMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
…
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
…
}
The solution is a class derived from CMiniDockFrame with his own Create(…)
BOOL CFixedMiniFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
// set m_bInRecalcLayout to avoid flashing during creation
// RecalcLayout will be called once something is docked
m_bInRecalcLayout = TRUE;DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
FWS_SNAPTOBARS;if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwStyle &= ~MFS_MOVEFRAME;DWORD dwExStyle = 0;
#ifdef _MAC
if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwExStyle |= WS_EX_FORCESIZEBOX;
else
dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
#endifif (!CMiniFrameWnd::CreateEx(dwExStyle,
NULL, &afxChNil, dwStyle, rectDefault, pParent))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}
dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
CString str;
if (str.LoadString(AFX_IDS_HIDE))
pSysMenu->ModifyMenu(SC_CLOSE,
MF_BYCOMMAND|MF_STRING|MF_ENABLED, SC_CLOSE, str);
// convert SC_RESTORE to ToggleDocking();
if (str.LoadString(AFX_IDS_DOCK))
pSysMenu->ModifyMenu(SC_RESTORE,
MF_BYCOMMAND|MF_STRING|MF_ENABLED, SC_RESTORE, str);
// must initially create with parent frame as parent
if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
AFX_IDW_DOCKBAR_FLOAT))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}// set parent to CMiniDockFrameWnd
m_wndDockBar.SetParent(this);
m_bInRecalcLayout = FALSE;return TRUE;
}
Then I add code to handle SC_RESTORE. This is not
necessary, but why not?
BEGIN_MESSAGE_MAP(CFixedMiniFrameWnd, CMiniDockFrameWnd)
//{{AFX_MSG_MAP(CFixedMiniFrameWnd)
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CFixedMiniFrameWnd message handlersvoid CFixedMiniFrameWnd::OnSysCommand(UINT nID, LPARAM)
{
switch (nID & 0xFFF0)
{
case SC_RESTORE:
OnNcLButtonDblClk( HTCAPTION, CPoint(0,0));
return;
}
Default();
}
Of course, MainFrame must know our new class
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
…
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);// Use our own class for miniframes
m_pFloatingFrameClass = RUNTIME_CLASS(CFixedMiniFrameWnd);
…
}