System menu fix for floating toolbar

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);
#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);

...
}

Download demo project - 17KB

Download demo only - 8KB



Comments

  • "afxChNil" undeclared identifier in vc++.net

    Posted by Legacy on 09/17/2002 12:00am

    Originally posted by: ghj1976

    vs.net can not build in
    
    

    if (!CMiniFrameWnd::CreateEx(dwExStyle,
    NULL, &afxChNil, dwStyle, rectDefault, pParent))


    "afxChNil" undeclared identifier in vc++.net

    • even i am having this problem

      Posted by nidhinidhi on 06/24/2008 06:02am

      even i am having this problem

      Reply
    Reply
  • Multiple Frame Wnd Problems

    Posted by Legacy on 11/03/1999 12:00am

    Originally 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
  • VC6.0 made this article obsolete.

    Posted by Legacy on 11/03/1999 12:00am

    Originally 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.
    By the way, this bug appears only with WinNT4.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

Most Popular Programming Stories

More for Developers

RSS Feeds