Click here to Skip to main content
15,885,546 members
Articles / Desktop Programming / MFC

Professional User Interface Suite

Rate me:
Please Sign up or sign in to vote.
4.99/5 (174 votes)
13 Jan 200423 min read 1.5M   23.6K   641  
MFC extension library enabling software to be provided with a professional UI
// This is part of the Professional User Interface Suite library.
// Copyright (C) 2001-2002 FOSS Software, Inc.
// All rights reserved.
//
// http://www.fossware.com
// mailto:foss@fossware.com
//
// This source code can be used, modified and redistributed
// under the terms of the license agreement that is included
// in the Professional User Interface Suite package.
//
// Warranties and Disclaimers:
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
// INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
// IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
// INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
// INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

#include "stdafx.h"

#if( !defined __EXTMINIDOCKFRAMEWND_H)
	#include "ExtMiniDockFrameWnd.h"
#endif

#if (!defined __EXTDOCKBAR_H)
	#include "ExtDockBar.h"
#endif

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	#if (!defined __EXT_CONTROLBAR_TABBED_FEATURES_H)
		#include "ExtControlBarTabbedFeatures.h"
	#endif // __EXT_CONTROLBAR_TABBED_FEATURES_H
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

#if (!defined __EXT_MEMORY_DC_H)
	#include <../Src/ExtMemoryDC.h>
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define __REMOVED_NONFIXMODE_STYLES \
	FWS_SNAPTOBARS
	//|MFS_THICKFRAME|MFS_4THICKFRAME
	//|MFS_MOVEFRAME|MFS_SYNCACTIVE

/////////////////////////////////////////////////////////////////////////////
// CExtMiniDockFrameWnd

bool CExtMiniDockFrameWnd::g_bOnWndPosChgProcessing = false;
bool CExtMiniDockFrameWnd::g_bAutoMakeTopmostOnMouseEvent = false;

IMPLEMENT_DYNCREATE(CExtMiniDockFrameWnd, CMiniDockFrameWnd);

BEGIN_MESSAGE_MAP(CExtMiniDockFrameWnd, CMiniDockFrameWnd)
    //{{AFX_MSG_MAP(CExtMiniDockFrameWnd)
	ON_WM_NCMOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_CLOSE()
	ON_WM_NCPAINT()
	ON_WM_NCACTIVATE()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_NCLBUTTONUP()
	ON_WM_NCRBUTTONDOWN()
    ON_WM_GETMINMAXINFO()
	ON_WM_WINDOWPOSCHANGING()
	ON_WM_WINDOWPOSCHANGED()
	ON_WM_SIZE()
	ON_WM_MOUSEMOVE()
	ON_WM_CAPTURECHANGED()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_ERASEBKGND()
	ON_WM_NCHITTEST()
	ON_WM_NCLBUTTONDBLCLK()
	ON_WM_CANCELMODE()
	ON_WM_PAINT()
	ON_WM_NCCALCSIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*
/// CMiniDockFrameWnd::Create replacement
BOOL CExtMiniDockFrameWnd::MDFW_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;
	if(	!MFW_CreateEx(
			dwExStyle,
			NULL,
			&afxChNil,
			dwStyle,
			rcDefault,
			pParent,
			0
			)
		)
	{
		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_MINIMIZE, MF_BYCOMMAND);
	pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
	pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
CString strHide;
	if( strHide.LoadString(AFX_IDS_HIDE) )
	{
		pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
		pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
	}

	// 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;
}

/// CMiniFrameWnd::CreateEx replacement
BOOL CExtMiniDockFrameWnd::MFW_CreateEx(
	DWORD dwExStyle,
	LPCTSTR lpClassName,
	LPCTSTR lpszWindowName,
	DWORD dwStyle,
	const RECT& rc,
	CWnd* pParentWnd,
	UINT nID
	)
{
	m_strCaption = lpszWindowName;
	return
		CWnd::CreateEx(
			dwExStyle,
			lpClassName ?
				lpClassName
				:
				AfxRegisterWndClass(
					CS_DBLCLKS, // | CS_SAVEBITS
					::LoadCursor(
					NULL,
					IDC_ARROW
					)
				),
			lpszWindowName,
			dwStyle,
			rc.left,
			rc.top,
			rc.right - rc.left,
			rc.bottom - rc.top,
			pParentWnd->GetSafeHwnd(),
			(HMENU)nID
			);
}
*/

BOOL CExtMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
//	if(!MDFW_Create(pParent, dwBarStyle))
//		return FALSE;
	if(!CMiniDockFrameWnd::Create(pParent, dwBarStyle))
		return FALSE;
	ModifyStyle( MFS_4THICKFRAME, 0 );
	ModifyStyleEx( 0, WS_EX_TOOLWINDOW );
	ModifyStyle( WS_SYSMENU, 0 );

	ModifyStyle( 0, WS_BORDER );
	
	SetTimer(1,1,NULL);

	EnableToolTips();
	m_wndToolTip.Create( this );
	m_wndToolTip.Activate( TRUE );

	return TRUE;
}

void CExtMiniDockFrameWnd::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
	if( _ResizingIsInProgress() )
	{
		_ResizingEnd();
		return;
	}
	
	if( CExtControlBar::_DraggingGetBar() != NULL )
		return;

CRect rcBarWnd;
	GetWindowRect( &rcBarWnd );
CPoint ptDevOffset = -rcBarWnd.TopLeft();
CPoint ptWnd( point + ptDevOffset );

CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar != NULL && pExtBar->m_bNcAreaBtnTracking )
	{
		INT nCountOfNcButtons = pExtBar->NcButtons_GetCount();
		for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
		{
			CExtBarNcAreaButton * pBtn =
				pExtBar->NcButtons_GetAt( nBtn );
			if( !pBtn->OnQueryVisibility() )
				continue;
			if( pBtn->OnNcAreaClicked( ptWnd ) )
				return;
		} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
		return;
	} // if( pExtBar != NULL && pExtBar->m_bNcAreaBtnTracking )

	if( m_rcBtnHideBar.PtInRect( ptWnd ) )
	{
		CControlBar * pBar =
			GetControlBar();
		if( pBar == NULL )
			return;
		ASSERT_VALID( pBar );
		GetParentFrame()->
			ShowControlBar(
				pBar,
				FALSE,
				FALSE
				);
		return;
	}

	CMiniDockFrameWnd::OnNcLButtonUp(nHitTest, point);
}

void CExtMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
CExtControlBar * pExtBar = GetControlBarExt();
CPoint p(point);
CRect rcWnd;
	GetWindowRect( &rcWnd );
	p.Offset( -rcWnd.left, -rcWnd.top );
	if( m_rcBtnHideBar.PtInRect( p ) )
		return;
	if( nHitTest == HTCAPTION )
	{
		ActivateTopParent();
		BringWindowToTop();
		if( (m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0 )
		{
			int nPos = 1;
			CControlBar* pBar = NULL;
			while(
				pBar == NULL
				&& nPos < m_wndDockBar.m_arrBars.GetSize()
				)
				pBar =
					reinterpret_cast < CExtDockBar & >
						(m_wndDockBar). GetDockedControlBar(nPos++);
			ASSERT(pBar != NULL);
			ASSERT_KINDOF( CControlBar, pBar );
			ASSERT( pBar->m_pDockContext != NULL );
			if( pExtBar == NULL
				|| (	pExtBar != NULL
					&&	pExtBar->IsFixedMode()
					&&	!pExtBar->_IsShowContentWhenDragging()
					)
				)
			{
				pBar->m_pDockContext->StartDrag(point);
				return;
			}
			int nCyGripper =
				min(
					pExtBar->m_rcGrip.Width(),
					pExtBar->m_rcGrip.Height()
					);
			pExtBar->_DraggingStart(
				point,
				point
					- rcWnd.TopLeft()
					- CPoint( nCyGripper, nCyGripper/2 )
				);
			return;
		}
	}
	else if( nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST )
	{
		ActivateTopParent();
		int nPos = 1;
		CControlBar * pBar = NULL;
		while(
			pBar == NULL
			&& nPos < m_wndDockBar.m_arrBars.GetSize()
			)
			pBar =
				reinterpret_cast < CExtDockBar & >
					(m_wndDockBar).GetDockedControlBar(nPos++);
		ASSERT(pBar != NULL);
		ASSERT_KINDOF(CControlBar, pBar);
		ASSERT(pBar->m_pDockContext != NULL);
		ASSERT( (m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0 );
		if(	!pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
			CMiniDockFrameWnd::OnNcLButtonDown( nHitTest, point);
		else
		{
			CExtControlBar * pExtBar =
				(CExtControlBar *)pBar;
			if( !pExtBar->_IsShowContentWhenDragging()
				&&	pExtBar->IsFixedMode()
				)
			{
				pBar->m_pDockContext->StartResize(nHitTest,point);
				return;
			}
			ClientToScreen( &point );
			_ResizingStart( nHitTest, point );
		}
		return;
	}
	else if( nHitTest == HTMINBUTTON
		|| nHitTest == HTMAXBUTTON
		|| nHitTest == HTGROWBOX
		)
		return;
	
	CMiniFrameWnd::OnNcLButtonDown( nHitTest, point );
}

void CExtMiniDockFrameWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint point) 
{
	if( nHitTest == HTCAPTION )
	{
		CRect rcWnd;
		GetWindowRect( &rcWnd );
		CPoint ptTestBtnHideBar( point - rcWnd.TopLeft() );
		if( m_rcBtnHideBar.PtInRect(ptTestBtnHideBar) )
			return;
	} // if( nHitTest == HTCAPTION )

CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar != NULL )
	{
		ASSERT_VALID( pExtBar );
		pExtBar->ToggleDocking();
		return;
	}

	CMiniDockFrameWnd::OnNcLButtonDblClk(nHitTest, point);
}

void CExtMiniDockFrameWnd::_ResizingStart(
	UINT nHitTest,
	const CPoint & point
	)
{
#ifdef _USRDLL
	// If this is a DLL, need to set up MFC state
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
#endif

	ASSERT( m_nResizingMode == HTNOWHERE );
	ASSERT( IsWindowVisible() );

	CExtPopupMenuWnd::CancelMenuTracking();

CExtControlBar * pExtBar = GetControlBarExt();
	ASSERT_VALID( pExtBar );
	if( !pExtBar->_IsShowContentWhenDragging()
		&&	pExtBar->IsFixedMode()
		)
	{
		m_nResizingMode = HTNOWHERE;
		pExtBar->m_pDockContext->StartResize(nHitTest, point);
		return;
	}

	switch( nHitTest )
	{
	case HTLEFT:
	case HTRIGHT:
	case HTTOP:
	case HTTOPLEFT:
	case HTTOPRIGHT:
	case HTBOTTOM:
	case HTBOTTOMLEFT:
	case HTBOTTOMRIGHT:
		m_nResizingMode = nHitTest;
	break;
	default:
		return;
	} // switch( nHitTest )

#ifdef _DEBUG
int nPos = 1;
CControlBar * pDebugDummyBar = NULL;
	while(
		pDebugDummyBar == NULL
		&& nPos < m_wndDockBar.m_arrBars.GetSize()
		)
		pDebugDummyBar =
			reinterpret_cast<CExtDockBar&>
				(m_wndDockBar).
					GetDockedControlBar(nPos++);
	ASSERT(pDebugDummyBar != NULL);
	ASSERT_KINDOF(CExtControlBar, pDebugDummyBar);
	ASSERT(pDebugDummyBar->m_pDockContext != NULL);
	// CBRS_SIZE_DYNAMIC toolbars cannot have the CBRS_FLOAT_MULTI style
	ASSERT((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0);
#endif // _DEBUG
	
	ASSERT( pExtBar == pDebugDummyBar );
	ASSERT(pExtBar->m_pDockContext != NULL);

	if( !pExtBar->IsFixedMode() )
		ModifyStyle(__REMOVED_NONFIXMODE_STYLES, 0);
	BringWindowToTop();
	SetCapture();
	GetWindowRect( &m_rcWndResizingStart );

	while( m_nResizingMode != HTNOWHERE )
	{
		::WaitMessage();
		MSG msg;
		// Process all the messages in the message queue
		while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			bool bStop = false;
			switch( msg.message )
			{
			case WM_ACTIVATEAPP:
			case WM_COMMAND:
				bStop = true;
			break;
			default:
				if(	WM_KEYFIRST <= msg.message
					&& msg.message <= WM_KEYLAST
					)
				bStop = true;
			break;
			} // switch( msg.message )
			if( (!bStop) &&
				GetCapture() != this
				)
				bStop = true;
			if( bStop )
			{
				_ResizingEnd();
				return;
			}
			if( !AfxGetApp()->PumpMessage() )
			{
				PostQuitMessage(0);
				return; // Signal WM_QUIT received
			} // if( !AfxGetApp()->PumpMessage() )
		} // while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		
		if( CExtControlBar::g_bEnableOnIdleCalls )
		{
			LONG lIdle = 0;
			while( AfxGetApp()->OnIdle(lIdle++) );
		}
	} // while( m_nResizingMode != HTNOWHERE )
}

void CExtMiniDockFrameWnd::_ResizingEnd()
{
	m_ptLastResizing.x = m_ptLastResizing.y = -1;
	//ASSERT( m_nResizingMode != HTNOWHERE );
	if( m_nResizingMode == HTNOWHERE )
		return;
	if( GetCapture() == this )
		ReleaseCapture();
CExtControlBar * pExtBar = GetControlBarExt();
	ASSERT_VALID( pExtBar );
	if( !pExtBar->IsFixedMode() )
		ModifyStyle(0, __REMOVED_NONFIXMODE_STYLES);
	m_nResizingMode = HTNOWHERE;
}

bool CExtMiniDockFrameWnd::g_bInResizingUpdateState = false;

void CExtMiniDockFrameWnd::_ResizingUpdateState(
	const CPoint & point
	)
{
	if( g_bInResizingUpdateState
		|| m_ptLastResizing == point
		)
		return;
	m_ptLastResizing = point;
	g_bInResizingUpdateState = true;

CPoint _pt( point );
	ASSERT( m_nResizingMode != HTNOWHERE );
CExtControlBar * pExtBar = GetControlBarExt();
	ASSERT_VALID( pExtBar );

	//BringWindowToTop();
CRect rcClient, rcClientOrg, rcWnd, rcWndOrg;
	GetClientRect( &rcClient );
	GetWindowRect( &rcWnd );
	rcClientOrg = rcClient;
	rcWndOrg = rcWnd;
CSize sizeDiff =
		rcWnd.Size() - rcClient.Size();
	ASSERT( sizeDiff.cx >= 0 && sizeDiff.cy >= 0 );
CSize sizeNcDiff( sizeDiff );

int nCalcMinHW = pExtBar->_CalcDesiredMinHW();
int nCalcMinVH = pExtBar->_CalcDesiredMinVH();
	if( sizeDiff.cx < nCalcMinHW )
		sizeDiff.cx = nCalcMinHW;
	if( sizeDiff.cy < nCalcMinVH )
		sizeDiff.cy = nCalcMinVH;

UINT nHit = m_nResizingMode;
bool	bLeft = false, bTop = false, bHorz = false,
		bInvTop = false, bInvLeft = false;
CPoint ptOffsetWnd( 0, 0 );
	if( pExtBar->IsFixedMode() )
	{
		switch( nHit )
		{
		case HTTOPLEFT:
		case HTTOPRIGHT:
			nHit = HTTOP;
		break;
		case HTBOTTOMLEFT:
		case HTBOTTOMRIGHT:
			nHit = HTBOTTOM;
		break;
		} // switch( nHit )
		switch( nHit )
		{
		case HTTOP:
			_pt.y =
				rcWndOrg.bottom
				+ rcWndOrg.top - _pt.y;
			nHit = HTBOTTOM;
			bInvLeft = true;
			bInvTop = true;
		break;
		case HTLEFT:
			_pt.x =
				rcWndOrg.right
				+ rcWndOrg.left - _pt.x;
			nHit = HTRIGHT;
			bInvLeft = true;
			bInvTop = true;
		break;
		} // switch( nHit )
	} // if( pExtBar->IsFixedMode() )
	if( bInvLeft || bInvTop || (!pExtBar->IsFixedMode()) )
	{
		CRect rcWnd( rcWndOrg );
		ScreenToClient( & rcWnd );
		if( bInvLeft || (!pExtBar->IsFixedMode()) )
			ptOffsetWnd.x =
				abs( rcWnd.left - rcClientOrg.left );
		if( bInvTop || (!pExtBar->IsFixedMode()) )
			ptOffsetWnd.y =
				abs( rcWnd.top - rcClientOrg.top );
	} // if( bInvLeft || bInvTop )

	switch( nHit )
	{
	case HTLEFT:
		bHorz = true;
		rcWnd.left = min( _pt.x, rcWnd.right );
		bLeft = true;
	break;
	case HTRIGHT:
		bHorz = true;
		rcWnd.right = max( _pt.x, rcWnd.left );
	break;
	case HTTOP:
		rcWnd.top = min( _pt.y, rcWnd.bottom );
		bTop = true;
	break;
	case HTTOPLEFT:
		rcWnd.left = min( _pt.x, rcWnd.right );
		rcWnd.top = min( _pt.y, rcWnd.bottom );
		bLeft = true;
		bTop = true;
	break;
	case HTTOPRIGHT:
		rcWnd.right = max( _pt.x, rcWnd.left );
		rcWnd.top = min( _pt.y, rcWnd.bottom );
		bTop = true;
	break;
	case HTBOTTOM:
		rcWnd.bottom = max( _pt.y, rcWnd.top );
	break;
	case HTBOTTOMLEFT:
		rcWnd.left = min( _pt.x, rcWnd.right );
		rcWnd.bottom = max( _pt.y, rcWnd.top );
		bLeft = true;
	break;
	case HTBOTTOMRIGHT:
		rcWnd.right = max( _pt.x, rcWnd.left );
		rcWnd.bottom = max( _pt.y, rcWnd.top );
	break;
	default:
		ASSERT( FALSE );
		g_bInResizingUpdateState = false;
		return;
	} // switch( nHit )

	if( rcWnd.Width() < sizeDiff.cx )
		rcWnd.right = rcWnd.left + sizeDiff.cx;
	if( rcWnd.Height() < sizeDiff.cy )
		rcWnd.bottom = rcWnd.top + sizeDiff.cy;
	if( rcWnd.right > rcWndOrg.right
		&& bLeft
		)
		rcWnd.OffsetRect(
			rcWndOrg.right - rcWnd.right,
			0
			);
	if( rcWnd.bottom > rcWndOrg.bottom
		&& bTop
		)
		rcWnd.OffsetRect(
			0,
			rcWndOrg.bottom - rcWnd.bottom
			);
	rcClient.SetRect(
		rcWnd.left - (rcClient.left-rcWndOrg.left),
		rcWnd.top - (rcClient.top-rcWndOrg.top),
		rcWnd.right - (rcClient.right-rcWndOrg.right),
		rcWnd.bottom - (rcClient.bottom-rcWndOrg.bottom)
		);


	if( !pExtBar->IsFixedMode() )
	{
		ASSERT( (GetStyle() & __REMOVED_NONFIXMODE_STYLES) == 0 );
		CSize _sizeMinFloated =
			pExtBar->_CalcDesiredMinFloatedSize();
		CSize _size = rcWnd.Size();
		if( _size.cx < _sizeMinFloated.cx )
			_size.cx = _sizeMinFloated.cx;
		if( _size.cy < _sizeMinFloated.cy )
			_size.cy = _sizeMinFloated.cy;
		CRect rcValidated( rcWnd.TopLeft(), _size );
		pExtBar->m_sizeFloated = _size - ptOffsetWnd;
		MoveWindow( &rcValidated );
		SendMessage( WM_NCPAINT );
		DelayRecalcLayout();
		SetTimer( 3, 20, NULL );
		g_bInResizingUpdateState = false;
		return;
	} // if( !pExtBar->IsFixedMode() )

DWORD dwMode = LM_HORZ|LM_COMMIT;
LONG nLendth = 0;
	if( bHorz )	
		nLendth = rcClient.Width();
	else
	{
		dwMode |= LM_LENGTHY;
		nLendth = rcClient.Height();
	}
CSize _sizeFloatedPrev = pExtBar->m_sizeFloated;
CSize _size =
		pExtBar->CalcDynamicLayout( nLendth, dwMode );
	if( _sizeFloatedPrev == _size )
	{
		g_bInResizingUpdateState = false;
		return;
	}

//	if( _size.cx < _sizeMinFloated.cx )
//		_size.cx = _sizeMinFloated.cx;
//	if( _size.cy < _sizeMinFloated.cy )
//		_size.cy = _sizeMinFloated.cy;

	pExtBar->m_sizeFloated = _size;

	if( bInvTop )
	{
		ASSERT( rcWnd.top == rcWndOrg.top );
		rcWnd.bottom = m_rcWndResizingStart.bottom;
		rcWnd.top =
			rcWnd.bottom - _size.cy - ptOffsetWnd.y;
	}
	if( bInvLeft )
	{
		ASSERT( rcWnd.left == rcWndOrg.left );
		rcWnd.right = m_rcWndResizingStart.right;
		rcWnd.left =
			rcWnd.right - _size.cx - ptOffsetWnd.x;
	}

	ASSERT( pExtBar->m_pDockSite != NULL );
	ASSERT( pExtBar->m_pDockBar != NULL );
	pExtBar->m_ptFloatHelper = rcWnd.TopLeft();

	_size += sizeNcDiff;
DWORD dwStyle = GetStyle();
	if( dwStyle&(MFS_4THICKFRAME|MFS_THICKFRAME|WS_THICKFRAME) )
	{
		_size.cx -= GetSystemMetrics( SM_CXFRAME );
		_size.cy -= GetSystemMetrics( SM_CYFRAME );
	} // if( dwStyle&(MFS_4THICKFRAME|MFS_THICKFRAME|WS_THICKFRAME) )
	else
	{
		_size.cx -= GetSystemMetrics( SM_CXBORDER );
		_size.cy -= GetSystemMetrics( SM_CYBORDER );
	} // else from if( dwStyle&(MFS_4THICKFRAME|MFS_THICKFRAME|WS_THICKFRAME) )

CRect rcToMoveMinFrame(
		pExtBar->m_ptFloatHelper,
		_size
		);

	MoveWindow( &rcToMoveMinFrame );
	SendMessage( WM_NCPAINT );
	RecalcLayout();
	g_bInResizingUpdateState = false;
}

CControlBar * CExtMiniDockFrameWnd::GetControlBar()
{
CWnd* pTempWnd = GetWindow( GW_CHILD );
    if( pTempWnd == NULL )
        return NULL;
	pTempWnd = pTempWnd->GetWindow( GW_CHILD );
    if( pTempWnd == NULL )
        return NULL;
    if( !pTempWnd->IsKindOf( RUNTIME_CLASS(CControlBar) ) )
        return NULL;
    return reinterpret_cast < CControlBar * >( pTempWnd );
}

const CControlBar * CExtMiniDockFrameWnd::GetControlBar() const
{
CControlBar * pBar =
		( const_cast < CExtMiniDockFrameWnd * > ( this ) ) ->
			GetControlBar();
	return pBar;
}

CExtControlBar * CExtMiniDockFrameWnd::GetControlBarExt()
{
CControlBar * pTempWnd = GetControlBar();
    if( pTempWnd == NULL )
        return NULL;
//	ASSERT_KINDOF( CExtControlBar, pTempWnd );
    if( !pTempWnd->IsKindOf( RUNTIME_CLASS(CExtControlBar) ) )
        return NULL;
    return reinterpret_cast < CExtControlBar * >( pTempWnd );
}

const CExtControlBar * CExtMiniDockFrameWnd::GetControlBarExt() const
{
CExtControlBar * pExtBar =
		( const_cast < CExtMiniDockFrameWnd * > ( this ) ) ->
			GetControlBarExt();
	return pExtBar;
}

void CExtMiniDockFrameWnd::OnNcRButtonDown(UINT nHitTest, CPoint point)
{
	if( _ResizingIsInProgress() )
	{
		_ResizingEnd();
		return;
	}
	if( nHitTest == HTCAPTION )
	{
		CExtControlBar * pExtBar =
			GetControlBarExt();
		if( pExtBar != NULL )
		{
			pExtBar->_ContextMenuTrack();
			return;
		} // if( pExtBar != NULL )
	} // if( nHitTest == HTCAPTION )
	CMiniDockFrameWnd::OnNcRButtonDown(nHitTest,point);
}

void CExtMiniDockFrameWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
	CMiniDockFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
//CRect & rcClient = (CRect &)(lpncsp->rgrc[0]);
//	rcClient.DeflateRect( 2, 2 );

}

void CExtMiniDockFrameWnd::OnNcPaint() 
{

CExtControlBar * pExtBar =
		GetControlBarExt();
bool bExtBar = false;
	if( pExtBar != NULL
		&& !pExtBar->IsFixedMode()
		)
	{
//		if( pExtBar->IsKindOf( RUNTIME_CLASS(CExtDynamicControlBar) ) )
//		{
//			Default();
//			return;
//		}
		bExtBar = true;
	}

CRect rcClient, rcBar;
	GetClientRect(rcClient);
	ClientToScreen(rcClient);
	GetWindowRect(rcBar);
	rcClient.OffsetRect(-rcBar.TopLeft());
	rcBar.OffsetRect(-rcBar.TopLeft());

CWindowDC dc( this );
	dc.ExcludeClipRect(rcClient);
CExtMemoryDC dcWin(&dc);

	g_PaintManager->PaintDockingFrame(
		dcWin,
		rcBar,
		rcClient,
		true,
		bExtBar
		);
bool bEnableCaptionText = true;
CString sCaption;
	if( pExtBar != NULL )
	{
		if( pExtBar->IsKindOf(RUNTIME_CLASS(CExtDynamicControlBar))
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			&& ( !pExtBar->IsKindOf(RUNTIME_CLASS(CExtDynamicTabbedControlBar)) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			)
			bEnableCaptionText = false;
		else
			pExtBar->GetWindowText(sCaption);
	}
	if( !bEnableCaptionText )
	{
		if( pExtBar != NULL
			&& pExtBar->IsKindOf(RUNTIME_CLASS(CExtDynamicControlBar))
			)
			bEnableCaptionText =
				_GetSingleVisibleCaptionText(
					sCaption
					);
	}
	else
		if( bEnableCaptionText && sCaption.IsEmpty() )
			GetWindowText(sCaption);

CRect rcCapt( m_rcFrameCaption );
CRect rcText( m_rcFrameCaption );
	rcText.right = m_rcBtnHideBar.left;

	if( pExtBar != NULL )
		pExtBar->NcButtons_CalcGripperTextLocation( rcText );

bool bActive = false;
HWND hTmpWndFocus = ::GetFocus();
	if( hTmpWndFocus != NULL
		&& (  GetSafeHwnd() == hTmpWndFocus
			  || ::IsChild( GetSafeHwnd(), hTmpWndFocus )
			)
		)
		bActive = true;

	rcText.DeflateRect(2,0);
	g_PaintManager->PaintGripper(
		dcWin,
		rcCapt,
		rcText,
		bActive,
		true,
		false,
		bExtBar,
		sCaption.IsEmpty() ? NULL : (LPCTSTR)sCaption
		);

	if( pExtBar != NULL )
	{
		pExtBar->NcButtons_Paint( dcWin );
	} // if( pExtBar != NULL )
	else
	{
		bool bPushed = false, bEnabled = true;
		g_PaintManager->PaintDockingCaptionButton(
			dcWin,
			m_rcBtnHideBar,
			CExtPaintManager::__DCBT_CLOSE,
			m_bBtnHideBar,
			bPushed,
			bEnabled,
			bExtBar,
			bActive,
			true
			);
	} // else from if( pExtBar != NULL )

}

bool CExtMiniDockFrameWnd::_GetSingleVisibleCaptionText( CString & sCaption )
{
	sCaption = _T("");
CFrameWnd * pDockSite = GetParentFrame();
	if( pDockSite == NULL )
		return false;
	ASSERT( !pDockSite->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
POSITION pos = pDockSite->m_listControlBars.GetHeadPosition();
	for( ; pos != NULL; )
	{
		CExtControlBar * pBar =
			DYNAMIC_DOWNCAST(
				CExtControlBar,
				((CControlBar *)(pDockSite->m_listControlBars.GetNext(pos)))
				);
		if(		pBar == NULL
			||	pBar->m_pDockSite == NULL
			||	pBar->IsFixedMode()
			||	(	pBar->IsKindOf(RUNTIME_CLASS(CExtDynamicControlBar))
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
					&& !pBar->IsKindOf(RUNTIME_CLASS(CExtDynamicTabbedControlBar))
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
				)
			||	pBar->GetParentFrame() != this
			||	pBar->IsFloating()
			||	!pBar->IsVisible()
			)
			continue;
		ASSERT( pBar->m_pDockBar != NULL );
		if(
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDynamicTabbedDockBar))
			||
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			!pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar))
			)
			continue;
		if( !pBar->_IsSingleVisibleInFloatingPalette() )
			return false;
		pBar->GetWindowText( sCaption );
		return sCaption.IsEmpty() ? false : true;
	}
	return false;
}

BOOL CExtMiniDockFrameWnd::OnNcActivate(BOOL bActive) 
{
BOOL rc = CMiniDockFrameWnd::OnNcActivate(bActive);
	SendMessage( WM_NCPAINT );
	if( bActive )
	{
		CExtControlBar * pExtBar =
			GetControlBarExt();
		if( pExtBar != NULL )
			pExtBar->RedrawWindow(
				NULL,
				NULL,
				RDW_INVALIDATE|RDW_UPDATENOW
					|RDW_ERASE|RDW_ALLCHILDREN
				);
	} // if( bActive )
	return rc;
}

void CExtMiniDockFrameWnd::OnSize(UINT nType, int cx, int cy) 
{
//	if( _ResizingIsInProgress() )
//		return;

	CMiniDockFrameWnd::OnSize(nType, cx, cy);


DWORD dwStyle = GetStyle();
CSize sizeFrame =
		(dwStyle & WS_THICKFRAME)
			?	CSize(
					GetSystemMetrics(SM_CXSIZEFRAME),
					GetSystemMetrics(SM_CYSIZEFRAME)
					)
			:	CSize(
					GetSystemMetrics(SM_CXFIXEDFRAME),
					GetSystemMetrics(SM_CYFIXEDFRAME)
		);
CRect rcFrameCaption;
	GetWindowRect( &rcFrameCaption );
	rcFrameCaption -= rcFrameCaption.TopLeft();
	rcFrameCaption.left  += sizeFrame.cx;
	rcFrameCaption.right -= sizeFrame.cx;
	rcFrameCaption.top   += sizeFrame.cy;
	rcFrameCaption.bottom =
		rcFrameCaption.top
		+ ::GetSystemMetrics(SM_CYSMCAPTION)
		- ::GetSystemMetrics(SM_CYSMSIZE);
	rcFrameCaption.bottom =
		rcFrameCaption.top
		+ ::GetSystemMetrics(SM_CYSMSIZE);
	m_rcFrameCaption = rcFrameCaption;

int nDummyMetric = ::GetSystemMetrics(SM_CXSMSIZE) - 1;
int nRight =
		m_rcFrameCaption.right - nDummyMetric - 1;
	m_rcBtnHideBar.SetRect(
		nRight,
		m_rcFrameCaption.top + 2,
		nRight + nDummyMetric - 2,
		m_rcFrameCaption.bottom - 2
		);

CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar != NULL )
	{
		pExtBar->OnNcAreaButtonsReinitialize();
		pExtBar->OnNcAreaButtonsReposition();
	} // if( pExtBar != NULL )

	if( !_ResizingIsInProgress() )
		RedrawWindow(
			NULL,
			NULL,
			RDW_FRAME|RDW_INVALIDATE|RDW_ERASE
				|RDW_UPDATENOW|RDW_ALLCHILDREN
			);
}

void CExtMiniDockFrameWnd::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) 
{
	CMiniDockFrameWnd::OnWindowPosChanged(lpwndpos);
	if(		_ResizingIsInProgress()
		||	g_bOnWndPosChgProcessing
		||	(lpwndpos->flags & SWP_NOMOVE) != 0
		)
		return;
CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar == NULL || !pExtBar->IsFloating() )
		return;
CRect rcWnd;
	GetWindowRect( &rcWnd );
CRect rcDesktop;
	::SystemParametersInfo( SPI_GETWORKAREA, 0, &rcDesktop, 0 );
	ASSERT( !g_bOnWndPosChgProcessing );
	if( rcWnd.top < rcDesktop.top )
	{
		rcWnd.top = rcDesktop.top;
		g_bOnWndPosChgProcessing = true;
	}
	else if( rcWnd.top + ::GetSystemMetrics(SM_CYSMCAPTION) > rcDesktop.bottom )
	{
		rcWnd.top =
			max(
			rcDesktop.top, 
			rcDesktop.bottom
				- ::GetSystemMetrics(SM_CYSMCAPTION)
			);
		g_bOnWndPosChgProcessing = true;
	}
	if( !g_bOnWndPosChgProcessing )
		return;
	SetWindowPos(
		NULL,
		rcWnd.left, rcWnd.top, -1, -1,
		SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE
		);

	pExtBar->OnNcAreaButtonsReposition();
	PostMessage( WM_NCPAINT );
	
	g_bOnWndPosChgProcessing = false;
}

void CExtMiniDockFrameWnd::OnWindowPosChanging( WINDOWPOS* lpwndpos )
{
	CMiniDockFrameWnd::OnWindowPosChanging( lpwndpos );
	ModifyStyle( WS_SYSMENU, 0 );
}

void CExtMiniDockFrameWnd::_AnalyzeButtonsHover(CPoint point)
{
CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar != NULL )
	{
		pExtBar->NcButtons_HitTest( point );
		return;
	}
CRect rcClient, rcBar;
	GetClientRect( &rcClient );
	ClientToScreen( &rcClient );
	GetWindowRect( &rcBar );
	rcClient.OffsetRect( -rcBar.TopLeft() );
	rcBar.OffsetRect (-rcBar.TopLeft() );
	ScreenToClient( &point );
	point.y -= rcBar.top - rcClient.top;
bool bBtnHideBarHover = false;
	if( m_rcBtnHideBar.PtInRect(point) )
		bBtnHideBarHover = true;
	if(	m_bBtnHideBar != bBtnHideBarHover )
	{
		m_bBtnHideBar = bBtnHideBarHover;
		SendMessage( WM_NCPAINT );
	}
	if( m_bBtnHideBar || bBtnHideBarHover )
		SetTimer(2,20,NULL);
	else
		KillTimer(2);
}

void CExtMiniDockFrameWnd::OnNcMouseMove( UINT nHitTest, CPoint point )
{
	if( g_bAutoMakeTopmostOnMouseEvent
		&& (!CExtPopupMenuWnd::IsMenuTracking())
		&& (CExtControlBar::_DraggingGetBar() == NULL)
		)
		BringWindowToTop();
	if( _ResizingIsInProgress() )
	{
		return;
	}
	CMiniDockFrameWnd::OnNcMouseMove( nHitTest, point );
	_AnalyzeButtonsHover(point);
}

void CExtMiniDockFrameWnd::OnTimer( UINT nIDEvent )
{
CExtControlBar * pExtBar = GetControlBarExt();
	if( nIDEvent == 1 )
	{
		if( pExtBar == NULL )
			return;
		KillTimer(1);
		pExtBar->OnNcAreaButtonsReposition();
		SetWindowPos(
			NULL,0,0,0,0,
			SWP_NOMOVE|SWP_NOACTIVATE // |SWP_NOSIZE
				|SWP_NOZORDER|SWP_NOOWNERZORDER 
				|SWP_FRAMECHANGED
			);
		return;
	}
	if( nIDEvent == 2 )
	{
		_AnalyzeButtonsHover();
		return;
	}
	if( nIDEvent == 3 )
	{
		if( pExtBar == NULL
			|| _ResizingIsInProgress()
			)
			return;
		KillTimer(3);
		RecalcLayout();
		pExtBar->OnNcAreaButtonsReposition();
		SendMessage( WM_NCPAINT );
		return;
	}

	if( pExtBar == NULL )
		return;
	ASSERT_VALID( pExtBar );
	if( nIDEvent == (UINT)pExtBar->GetDlgCtrlID() )
	{
		if( _ResizingIsInProgress() )
			return;
		CPoint pt;
		VERIFY( GetCursorPos( &pt ) );
		CWnd * pTempWnd = WindowFromPoint( pt );
		int IsMouseInsideTheWindow =
			IsChild( pTempWnd ) || pTempWnd->m_hWnd == m_hWnd;

		if(	IsMouseInsideTheWindow
			|| IsChild(GetFocus())  
			|| (GetCapture() && pExtBar->m_hWnd == GetCapture()->m_hWnd) 
			|| CExtPopupMenuWnd::IsMenuTracking()
			) 
		{

			if(	IsMouseInsideTheWindow 
				&& !CExtPopupMenuWnd::IsMenuTracking()
				&& IsWindowEnabled()
				&& GetFocus()
				) 
				BringWindowToTop();
		}
	} // if( nIDEvent == (UINT)pExtBar->GetDlgCtrlID() )
}

void CExtMiniDockFrameWnd::OnClose() 
{
	CMiniDockFrameWnd::OnClose();
}

void CExtMiniDockFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
    CMiniDockFrameWnd::OnGetMinMaxInfo(lpMMI);
}

void CExtMiniDockFrameWnd::OnMouseMove(UINT nFlags, CPoint point) 
{
	if( g_bAutoMakeTopmostOnMouseEvent
		&& (!CExtPopupMenuWnd::IsMenuTracking())
		)
		BringWindowToTop();
	if( _ResizingIsInProgress() )
	{
		ClientToScreen( &point );
		_ResizingUpdateState( point );
		return;
	}
	CMiniDockFrameWnd::OnMouseMove(nFlags, point);
}

void CExtMiniDockFrameWnd::OnCaptureChanged(CWnd *pWnd) 
{
	if( _ResizingIsInProgress()
		&& pWnd != this
		)
	{
		_ResizingEnd();
		return;
	}
	CMiniDockFrameWnd::OnCaptureChanged(pWnd);
}

void CExtMiniDockFrameWnd::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if( _ResizingIsInProgress() )
	{
		_ResizingEnd();
		return;
	}
	CMiniDockFrameWnd::OnLButtonUp(nFlags, point);
}

void CExtMiniDockFrameWnd::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if( _ResizingIsInProgress() )
	{
		_ResizingEnd();
		return;
	}
	CMiniDockFrameWnd::OnRButtonDown(nFlags, point);
}

BOOL CExtMiniDockFrameWnd::OnEraseBkgnd(CDC* pDC) 
{
	pDC;
	return TRUE;
}

UINT CExtMiniDockFrameWnd::OnNcHitTest(CPoint point) 
{
	if( GetStyle() & MFS_MOVEFRAME )
		ModifyStyle( MFS_MOVEFRAME, 0 );

UINT nHit = CMiniDockFrameWnd::OnNcHitTest(point);
CExtControlBar * pExtBar = GetControlBarExt();
	if( pExtBar != NULL )
	{
		UINT nHT = pExtBar->NcButtons_HitTest( point );
		if( nHT != HTCLIENT )
		{
			pExtBar->m_bNcAreaBtnTracking = true;
			return nHT;
		}
		ASSERT_VALID( pExtBar );
		if( pExtBar->IsFixedMode() )
		{
			switch( nHit )
			{
			case HTTOPLEFT:
			case HTTOPRIGHT:
				nHit = HTTOP;
			break;
			case HTBOTTOMLEFT:
			case HTBOTTOMRIGHT:
				nHit = HTBOTTOM;
			break;
			} // switch( nHit )
		} // if( pExtBar->IsFixedMode() )
	} // if( pExtBar != NULL )
	return nHit;
}

void CExtMiniDockFrameWnd::OnCancelMode() 
{
	CMiniDockFrameWnd::OnCancelMode();
	CExtPopupMenuWnd::CancelMenuTracking();
//	ASSERT( !CExtPopupMenuWnd::IsMenuTracking() );
	if( _ResizingIsInProgress() )
		_ResizingEnd();
}

void CExtMiniDockFrameWnd::OnPaint() 
{
CPaintDC dcPaint( this );
	return;
//CRect rcClient;
//	GetClientRect( &rcClient );
//	if( rcClient.IsRectEmpty()
//		|| !dcPaint.RectVisible( &rcClient )
//		)
//		return;
//	CExtPaintManager::stat_ExcludeChildAreas(
//		dcPaint.GetSafeHdc(),
//		GetSafeHwnd()
//		);
//COLORREF clrBack =
//		g_PaintManager->GetColor(
//			CExtPaintManager::CLR_3DFACE_OUT
//			);
//	dcPaint.FillSolidRect( &rcClient, clrBack );
}

int CExtMiniDockFrameWnd::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	) const
{
	ASSERT_VALID( this );
	
	if( pTI == NULL || m_wndToolTip.GetSafeHwnd() == NULL )
		return -1;

const CControlBar * pBar = GetControlBar();
	if( pBar == NULL )
		return -1;
	ASSERT_VALID( pBar );
	if( (pBar->m_dwStyle & CBRS_TOOLTIPS) == NULL )
		return -1;

int nRet = pBar->OnToolHitTest( point, pTI );
	if( nRet < 0 )
		return -1;

	if( pTI->lpszText != NULL )
	{
		CExtMiniDockFrameWnd * pNCT = (CExtMiniDockFrameWnd *)this;
		VERIFY(
			pNCT->m_wndToolTip.AddTool(
				pNCT,
				pTI->lpszText,
				&pTI->rect,
				1
				)
			);
	}
	
	return -1;
}

BOOL CExtMiniDockFrameWnd::PreTranslateMessage( MSG* pMsg ) 
{
	if( m_wndToolTip.GetSafeHwnd() != NULL )
		m_wndToolTip.RelayEvent( pMsg );
	return CMiniDockFrameWnd::PreTranslateMessage( pMsg );
}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Foss Software Inc
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions