📄 staticsplitterwnd.cpp
字号:
#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 + -