System menu fix for floating toolbar
Posted
by Paul Bludov
on February 24th, 1999
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);
#endif
if (!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 handlers
void 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);
...
}

Comments
"afxChNil" undeclared identifier in vc++.net
Posted by Legacy on 09/17/2002 12:00amOriginally posted by: ghj1976
-
Replyeven i am having this problem
Posted by nidhinidhi on 06/24/2008 06:02ameven i am having this problem
ReplyVC6.0 made this article obsolete.
Posted by Legacy on 11/03/1999 12:00amOriginally posted by: Paul Bludov
CMiniDockFrameWnd::Create() from VC6 does it in a right way. It seems to there was a bug in VC5 and VC4.
ReplyBy the way, this bug appears only with WinNT4.
Multiple Frame Wnd Problems
Posted by Legacy on 11/03/1999 12:00amOriginally posted by: Robert Pearmain
I have read your article on Mini Frame Windows with great interest. I have used the bars on 2 different CFrameWnd's.
The problem is, if I set focus between the 2 frame windows via the main title captions, all is fine. However, if I try to set the focus of a window by clicking on the MiniFrameWnd title caption, I get a First Chance exception error:
CWnd::Default() line 250 + 29 bytes
CWnd::OnNcLButtonDown(unsigned int 2, unsigned int 2) line 414 + 15 bytes
CMiniFrameWnd::OnNcLButtonDown(unsigned int 2, CPoint {x=318 y=215}) line 418
CMiniDockFrameWnd::OnNcLButtonDown(unsigned int 2, CPoint {x=318 y=215}) line 908
CWnd::OnWndMsg(unsigned int 161, unsigned int 2, long 14090558, long * 0x0012fd5c) line 1954
CWnd::WindowProc(unsigned int 161, unsigned int 2, long 14090558) line 1575 + 30 bytes
AfxCallWndProc(CWnd * 0x0068f120 {CWnd hWnd=0xdddddddd}, HWND__ * 0x00b70984, unsigned int 161, unsigned int 2, long 14090558) line 217 + 26 bytes
AfxWndProc(HWND__ * 0x00b70984, unsigned int 161, unsigned int 2, long 14090558) line 371
AfxWndProcBase(HWND__ * 0x00b70984, unsigned int 161, unsigned int 2, long 14090558) line 203 + 21 bytes
USER32! 77e71820()
What do I need to do so that I can select another Frame Window in the same app by clicking a MiniFrameWnd in that Window?
Reply