⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 staticsplitterwnd.cpp

📁 MFC类库祥解, MFC类库祥解
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "StaticSplitterWnd.h"

// Constructor
CStaticSplitterWnd::CStaticSplitterWnd()
{
	m_xySplitterPos = -1;
	m_nDefActivePane = SPLIT_PANE_NONE;
	m_cxySplitBar = m_cxyMin = m_cxyBarEdge = 0;
	m_bFullDrag = TRUE;
	m_cxyDragOffset = 0;
	m_nProportionalPos = m_nPropMax / 2;
	m_bUpdateProportionalPos = TRUE;
	m_dwExtendedStyle = SPLIT_PROPORTIONAL;
	m_nSinglePane = SPLIT_PANE_NONE;
	m_bVertical = TRUE;

	m_hWndPane[SPLIT_PANE_LEFT] = NULL;
	m_hWndPane[SPLIT_PANE_RIGHT] = NULL;

	::SetRectEmpty(&m_rcSplitter);
}

CStaticSplitterWnd::~CStaticSplitterWnd()
{

}

void CStaticSplitterWnd::SetSplitterRect(LPRECT lpRect, BOOL bUpdate)
{
	if(lpRect == NULL)
		GetClientRect(&m_rcSplitter);
	else
		m_rcSplitter = *lpRect;

	if ( IsProportional() )
		UpdateProportionalPos();
	else
	{
		if( IsRightAligned() )
			UpdateRightAlignPos();
	}

	if(bUpdate)
		UpdateSplitterLayout();
}

void CStaticSplitterWnd::GetSplitterRect(LPRECT lpRect) const
{
	ASSERT(lpRect != NULL);
	*lpRect = m_rcSplitter;
}

BOOL CStaticSplitterWnd::SetSplitterPos(int xyPos, BOOL bUpdate)
{
	if(xyPos == -1) 	// -1 == middle
	{
		if(m_bVertical)
			xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2;
		else
			xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2;
	}

	// Adjust if out of valid range
	int cxyMax = 0;
	if(m_bVertical)
		cxyMax = m_rcSplitter.right - m_rcSplitter.left;
	else
		cxyMax = m_rcSplitter.bottom - m_rcSplitter.top;

	if(xyPos < m_cxyMin + m_cxyBarEdge)
		xyPos = m_cxyMin;
	else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin))
		xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin;

	// Set new position and update if requested
	BOOL bRet = (m_xySplitterPos != xyPos);
	m_xySplitterPos = xyPos;

	if(m_bUpdateProportionalPos)
	{
		if(IsProportional())
			StoreProportionalPos();
		else if(IsRightAligned())
			StoreRightAlignPos();
	}
	else
	{
		m_bUpdateProportionalPos = TRUE;
	}

	if(bUpdate && bRet)
		UpdateSplitterLayout();

	return bRet;
}

int CStaticSplitterWnd::GetSplitterPos() const
{
	return m_xySplitterPos;
}

BOOL CStaticSplitterWnd::SetSinglePaneMode(int nPane)
{
	ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE);
	if(!(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE))
		return FALSE;

	if(nPane != SPLIT_PANE_NONE)
	{
		if(!::IsWindowVisible(m_hWndPane[nPane]))
			::ShowWindow(m_hWndPane[nPane], SW_SHOW);
		int nOtherPane = (nPane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT;
		::ShowWindow(m_hWndPane[nOtherPane], SW_HIDE);
		if(m_nDefActivePane != nPane)
			m_nDefActivePane = nPane;
	}
	else if(m_nSinglePane != SPLIT_PANE_NONE)
	{
		int nOtherPane = (m_nSinglePane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT;
		::ShowWindow(m_hWndPane[nOtherPane], SW_SHOW);
	}

	m_nSinglePane = nPane;
	UpdateSplitterLayout();
	return TRUE;
}

int CStaticSplitterWnd::GetSinglePaneMode() const
{
	return m_nSinglePane;
}

DWORD CStaticSplitterWnd::GetSplitterExtendedStyle() const
{
	return m_dwExtendedStyle;
}

DWORD CStaticSplitterWnd::SetSplitterExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask)
{
	DWORD dwPrevStyle = m_dwExtendedStyle;
	if(dwMask == 0)
		m_dwExtendedStyle = dwExtendedStyle;
	else
		m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
/*
#ifdef _DEBUG
	if(IsProportional() && IsRightAligned())
		TRACE2(TraceUI, 0, _T("CStaticSplitterWnd::SetSplitterExtendedStyle - SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED are mutually exclusive, defaulting to SPLIT_PROPORTIONAL.\n"));
#endif //_DEBUG
*/
	return dwPrevStyle;
}

// Splitter operations
void CStaticSplitterWnd::SetSplitterPanes(CWnd* pWndLeftTop, CWnd* pWndRightBottom, BOOL bUpdate)
{
	ASSERT(pWndLeftTop != NULL);
	ASSERT(pWndRightBottom != NULL);

	m_hWndPane[SPLIT_PANE_LEFT] = pWndLeftTop->GetSafeHwnd();
	m_hWndPane[SPLIT_PANE_RIGHT] = pWndRightBottom->GetSafeHwnd();
	ASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]);
	if(bUpdate)
		UpdateSplitterLayout();
}

BOOL CStaticSplitterWnd::SetSplitterPane(int nPane, CWnd* pWnd, BOOL bUpdate)
{
	ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT);

	if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
		return FALSE;

	ASSERT(pWnd != NULL);
	if ( pWnd == NULL )
		return FALSE;

	m_hWndPane[nPane] = pWnd->GetSafeHwnd();
	ASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]);
	if(bUpdate)
		UpdateSplitterLayout();
	return TRUE;
}

HWND CStaticSplitterWnd::GetSplitterPane(int nPane) const
{
	ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT);

	if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
		return FALSE;
	return m_hWndPane[nPane];
}

BOOL CStaticSplitterWnd::SetActivePane(int nPane)
{
	ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT);

	if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
		return FALSE;
	if(m_nSinglePane != SPLIT_PANE_NONE && nPane != m_nSinglePane)
		return FALSE;
	::SetFocus(m_hWndPane[nPane]);
	m_nDefActivePane = nPane;
	return TRUE;
}

int CStaticSplitterWnd::GetActivePane() const
{
	int nRet = SPLIT_PANE_NONE;
	HWND hWndFocus = ::GetFocus();
	if(hWndFocus != NULL)
	{
		for(int nPane = 0; nPane < m_nPanesCount; nPane++)
		{
			if(hWndFocus == m_hWndPane[nPane] || ::IsChild(m_hWndPane[nPane], hWndFocus))
			{
				nRet = nPane;
				break;
			}
		}
	}
	return nRet;
}

BOOL CStaticSplitterWnd::ActivateNextPane(BOOL bNext)
{
	int nPane = m_nSinglePane;
	if(nPane == SPLIT_PANE_NONE)
	{
		switch(GetActivePane())
		{
		case SPLIT_PANE_LEFT:
			nPane = SPLIT_PANE_RIGHT;
			break;
		case SPLIT_PANE_RIGHT:
			nPane = SPLIT_PANE_LEFT;
			break;
		default:
			nPane = bNext ? SPLIT_PANE_LEFT : SPLIT_PANE_RIGHT;
			break;
		}
	}
	return SetActivePane(nPane);
}

BOOL CStaticSplitterWnd::SetDefaultActivePane(int nPane)
{
	ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT);

	if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT)
		return FALSE;
	m_nDefActivePane = nPane;
	return TRUE;
}

BOOL CStaticSplitterWnd::SetDefaultActivePane(CWnd* pWnd)
{
	ASSERT(pWnd != NULL);
	if ( pWnd == NULL )
		return FALSE;
	HWND hWnd = pWnd->GetSafeHwnd();

	for(int nPane = 0; nPane < m_nPanesCount; nPane++)
	{
		if(hWnd == m_hWndPane[nPane])
		{
			m_nDefActivePane = nPane;
			return TRUE;
		}
	}
	return FALSE;	// not found
}

int CStaticSplitterWnd::GetDefaultActivePane() const
{
	return m_nDefActivePane;
}

void CStaticSplitterWnd::DrawSplitter(CDC* pDC)
{
	ASSERT(pDC->m_hDC != NULL);
	if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
		return;

	if(m_nSinglePane == SPLIT_PANE_NONE)
	{
		DrawSplitterBar(pDC);

		for(int nPane = 0; nPane < m_nPanesCount; nPane++)
		{
			if(m_hWndPane[nPane] == NULL)
				DrawSplitterPane(pDC, nPane);
		}
	}
	else
	{
		if(m_hWndPane[m_nSinglePane] == NULL)
			DrawSplitterPane(pDC, m_nSinglePane);
	}
}

// Overrideables
void CStaticSplitterWnd::DrawSplitterBar(CDC* pDC)
{
	CRect rect;
	if(GetSplitterBarRect(&rect))
	{
		pDC->FillSolidRect(&rect, GetSysColor(COLOR_3DFACE));
		// draw 3D edge if needed
		
		if((GetExStyle() & WS_EX_CLIENTEDGE) != 0)
			pDC->DrawEdge(&rect, EDGE_RAISED, m_bVertical ? (BF_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM));
	}
}

// called only if pane is empty
void CStaticSplitterWnd::DrawSplitterPane(CDC* pDC, int nPane)
{
	CRect rect;
	if(GetSplitterPaneRect(nPane, &rect))
	{
		
		if((GetExStyle() & WS_EX_CLIENTEDGE) == 0)
			pDC->DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
		pDC->FillSolidRect(&rect, GetSysColor(COLOR_APPWORKSPACE));
	}
}

BEGIN_MESSAGE_MAP(CStaticSplitterWnd, CWnd)
	//{{AFX_MSG_MAP(CSplitterWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_SETCURSOR()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_SETFOCUS()
	ON_WM_MOUSEACTIVATE()
	ON_WM_SETTINGCHANGE()
	ON_WM_ERASEBKGND()
	ON_WM_SIZE()
	ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
	ON_MESSAGE(WM_WININICHANGE, OnDisplayChange)
	ON_MESSAGE(WM_SETTINGCHANGE, OnDisplayChange)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

int CStaticSplitterWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	GetSystemSettings(FALSE);
	m_hCursor = LoadCursor(NULL, m_bVertical?IDC_SIZEWE:IDC_SIZENS);

	return CWnd::OnCreate(lpCreateStruct);
}

void CStaticSplitterWnd::OnPaint()
{
	// try setting position if not set
	if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
		SetSplitterPos();
	// do painting
	CPaintDC dc(this);
	DrawSplitter(&dc);
}

BOOL CStaticSplitterWnd::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
	
	if( pWnd->m_hWnd == m_hWnd && nHitTest == HTCLIENT)
	{
		CPoint ptPos;
		GetCursorPos(&ptPos);
		ScreenToClient(&ptPos);
		if(IsOverSplitterBar(ptPos.x, ptPos.y))
			return TRUE;
	}
	
	return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

void CStaticSplitterWnd::OnMouseMove( UINT nFlags, CPoint point )
{
	
	int xPos = point.x;
	int yPos = point.y;
	if((nFlags & MK_LBUTTON) && ::GetCapture() == m_hWnd)
	{
		int xyNewSplitPos = 0;
		if(m_bVertical)
			xyNewSplitPos = xPos - m_rcSplitter.left - m_cxyDragOffset;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -