www.pudn.com > MarkupDemo.rar > DividerCtrl.cpp


// DividerCtrl.cpp : implementation file 
// 
// Markup Release 6.1 Lite 
// Copyright (C) 1999-2001 First Objective Software, Inc. All rights reserved 
// This entire notice must be retained in this source code 
// Redistributing this source code requires written permission 
// This software is provided "as is", with no warranty. 
// Latest fixes enhancements and documentation at www.firstobject.com 
 
#include "stdafx.h" 
#include "DividerCtrl.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDividerCtrl 
 
CDividerCtrl::CDividerCtrl() 
{ 
	m_bHasCapture = FALSE; 
	m_enumOrientation = NoOrientation; 
	m_nOffset = 0; 
	m_nFractionOf1000 = 0; 
	m_nMinFraction = 0; 
	m_nMaxFraction = 1000; 
	m_bDisappearingBar = FALSE; 
	m_nWidth = 8; 
	m_nMinWidthFromEdge = 30; 
	m_hCursor = NULL; 
} 
 
CDividerCtrl::~CDividerCtrl() 
{ 
} 
 
BEGIN_MESSAGE_MAP(CDividerCtrl, CStatic) 
	//{{AFX_MSG_MAP(CDividerCtrl) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	ON_WM_CAPTURECHANGED() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void CDividerCtrl::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	UNREFERENCED_PARAMETER( nFlags ); 
 
	// Capture mouse move messages 
	SetSplitterCursor(); 
	SetCapture(); 
	m_bHasCapture = TRUE; 
 
	// Figure out original x coordinate 
	m_pointOrig = point; 
 
	// CStatic::OnLButtonDown(nFlags, point); 
} 
 
void CDividerCtrl::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	SetSplitterCursor(); 
	if ( m_bHasCapture ) 
		::ReleaseCapture(); 
	else 
		CStatic::OnLButtonUp(nFlags, point); 
} 
 
void CDividerCtrl::SetSplitterCursor()  
{ 
 
	// AFX Cursors 
	if ( ! m_hCursor ) 
	{ 
		if ( m_enumOrientation == MoveHorizontal ) 
			m_hCursor = AfxGetApp()->LoadCursor(AFX_IDC_HSPLITBAR); 
		else if ( m_enumOrientation == MoveVertical ) 
			m_hCursor = AfxGetApp()->LoadCursor(AFX_IDC_VSPLITBAR); 
	} 
 
	// If AFX Cursors not available, use standard windows cursors 
	if ( ! m_hCursor ) 
	{ 
		if ( m_enumOrientation == MoveHorizontal ) 
			m_hCursor = LoadCursor( NULL, IDC_SIZEWE ); 
		else if ( m_enumOrientation == MoveVertical ) 
			m_hCursor = LoadCursor( NULL, IDC_SIZENS ); 
	} 
 
	// Set cursor 
	if ( m_hCursor ) 
		::SetCursor(m_hCursor); 
 
} 
 
void CDividerCtrl::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	SetSplitterCursor(); 
 
	if ( m_bHasCapture ) 
	{ 
		m_pointNew = point; 
		if ( m_enumOrientation == NoOrientation  && m_pointNew != m_pointOrig || 
			 m_enumOrientation == MoveHorizontal && m_pointNew.x != m_pointOrig.x || 
			 m_enumOrientation == MoveVertical && m_pointNew.y != m_pointOrig.y 
			 ) 
		{ 
			CRect rect; 
			GetParent()->GetClientRect( &rect ); 
			GetParent()->SendMessage( 
				WM_SIZE, 
				SIZE_RESTORED, 
				MAKELPARAM(rect.Width(),rect.Height()) 
				); 
		} 
	} 
	else 
		CStatic::OnMouseMove(nFlags, point); 
} 
 
void CDividerCtrl::OnCaptureChanged(CWnd *pWnd)  
{ 
	m_bHasCapture = FALSE; 
	CStatic::OnCaptureChanged(pWnd); 
} 
 
int CDividerCtrl::GetWidth() 
{ 
	if ( m_bDisappearingBar && ( m_bAtHighEnd || m_bAtLowEnd ) ) 
		return 0; 
	else 
		return m_nWidth; 
} 
 
int CDividerCtrl::CalculateOffset( int nSizeOfRange ) 
{ 
	// During resize, the divider offset is adjusted here 
	// If not in mouse capture mode, maintain per cent in given range 
	// If in mouse capture mode, adjust by mouse movement 
	if ( m_bHasCapture ) 
	{ 
		int nAdjust = 0; 
		if ( m_enumOrientation == MoveHorizontal ) 
			nAdjust = m_pointNew.x - m_pointOrig.x; 
		else if ( m_enumOrientation == MoveVertical ) 
			nAdjust = m_pointNew.y - m_pointOrig.y; 
		m_nOffset += nAdjust; 
		m_nFractionOf1000 = m_nOffset * 1000 / nSizeOfRange; 
	} 
	else 
	{ 
		m_nOffset = m_nFractionOf1000 * nSizeOfRange / 1000; 
	} 
 
	// Max and min only affect within snap-to 
	if ( m_nMinFraction > 0 ) 
	{ 
		int nMinOffset = m_nMinFraction * nSizeOfRange / 1000; 
		if ( m_nOffset < nMinOffset ) 
			m_nOffset = nMinOffset; 
	} 
	if ( m_nMaxFraction < 1000 ) 
	{ 
		int nMaxOffset = m_nMaxFraction * nSizeOfRange / 1000; 
		if ( m_nOffset > nMaxOffset ) 
			m_nOffset = nMaxOffset; 
	} 
 
	// Keep divider within edges 
	// Slap to edge if under min width from edge 
	// Keep at zero if nSizeOfRange too small 
	m_bAtLowEnd = FALSE; 
	m_bAtHighEnd = FALSE; 
	if ( m_nOffset > nSizeOfRange - m_nMinWidthFromEdge - m_nWidth ) 
	{ 
		if ( m_bDisappearingBar ) 
			m_nOffset = nSizeOfRange; 
		else 
			m_nOffset = nSizeOfRange - m_nWidth; 
		m_bAtHighEnd = TRUE; 
	} 
	if ( m_nOffset < m_nMinWidthFromEdge ) 
	{ 
		m_nOffset = 0; 
		m_bAtLowEnd = TRUE; 
	} 
 
	return m_nOffset; 
}