📄 staticsplitterwnd.cpp
字号:
else
xyNewSplitPos = yPos - m_rcSplitter.top - m_cxyDragOffset;
if(xyNewSplitPos == -1) // avoid -1, that means middle
xyNewSplitPos = -2;
if(m_xySplitterPos != xyNewSplitPos)
{
if(m_bFullDrag)
{
if(SetSplitterPos(xyNewSplitPos, TRUE))
UpdateWindow();
}
else
{
DrawGhostBar();
SetSplitterPos(xyNewSplitPos, FALSE);
DrawGhostBar();
}
}
}
else // not dragging, just set cursor
{
if(IsOverSplitterBar(xPos, yPos))
::SetCursor(m_hCursor);
CWnd::OnMouseMove(nFlags, point);
}
}
void CStaticSplitterWnd::OnLButtonDown( UINT nFlags, CPoint point )
{
int xPos = point.x;
int yPos = point.y;
if(IsOverSplitterBar(xPos, yPos))
{
SetCapture();
::SetCursor(m_hCursor);
if(!m_bFullDrag)
DrawGhostBar();
if(m_bVertical)
m_cxyDragOffset = xPos - m_rcSplitter.left - m_xySplitterPos;
else
m_cxyDragOffset = yPos - m_rcSplitter.top - m_xySplitterPos;
}
CWnd::OnLButtonDown(nFlags, point);
}
void CStaticSplitterWnd::OnLButtonUp( UINT nFlags, CPoint point )
{
if(!m_bFullDrag)
{
DrawGhostBar();
UpdateSplitterLayout();
UpdateWindow();
}
::ReleaseCapture();
CWnd::OnLButtonUp(nFlags, point);
}
void CStaticSplitterWnd::OnLButtonDblClk( UINT nFlags, CPoint point )
{
SetSplitterPos(); // middle
CWnd::OnLButtonDblClk(nFlags, point);
}
void CStaticSplitterWnd::OnSetFocus( CWnd* pOldWnd )
{
if(m_nSinglePane == SPLIT_PANE_NONE)
{
if(m_nDefActivePane == SPLIT_PANE_LEFT || m_nDefActivePane == SPLIT_PANE_RIGHT)
::SetFocus(m_hWndPane[m_nDefActivePane]);
else
CWnd::OnSetFocus(pOldWnd);
}
else
{
::SetFocus(m_hWndPane[m_nSinglePane]);
}
}
int CStaticSplitterWnd::OnMouseActivate( CWnd* pDesktopWnd, UINT nHitTest, UINT message )
{
LRESULT lRet = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
if(lRet == MA_ACTIVATE || lRet == MA_ACTIVATEANDEAT)
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
CRect rcPane;
for(int nPane = 0; nPane < m_nPanesCount; nPane++)
{
if(GetSplitterPaneRect(nPane, &rcPane) && ::PtInRect(&rcPane, pt))
{
m_nDefActivePane = nPane;
break;
}
}
}
return lRet;
}
LRESULT CStaticSplitterWnd::OnDisplayChange(WPARAM, LPARAM)
{
GetSystemSettings(TRUE);
return 0;
}
// Implementation - internal helpers
void CStaticSplitterWnd::UpdateSplitterLayout()
{
if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1)
return;
CRect rect = CRect(0, 0, 0, 0);
if(m_nSinglePane == SPLIT_PANE_NONE)
{
if(GetSplitterBarRect(&rect))
InvalidateRect(&rect);
for(int nPane = 0; nPane < m_nPanesCount; nPane++)
{
if(GetSplitterPaneRect(nPane, &rect))
{
if(m_hWndPane[nPane] != NULL)
::SetWindowPos(m_hWndPane[nPane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
else
InvalidateRect(&rect);
}
}
}
else
{
if(GetSplitterPaneRect(m_nSinglePane, &rect))
{
if(m_hWndPane[m_nSinglePane] != NULL)
::SetWindowPos(m_hWndPane[m_nSinglePane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
else
InvalidateRect(&rect);
}
}
}
BOOL CStaticSplitterWnd::GetSplitterBarRect(LPRECT lpRect) const
{
ASSERT(lpRect != NULL);
if(m_nSinglePane != SPLIT_PANE_NONE || m_xySplitterPos == -1)
return FALSE;
if(m_bVertical)
{
lpRect->left = m_rcSplitter.left + m_xySplitterPos;
lpRect->top = m_rcSplitter.top;
lpRect->right = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
lpRect->bottom = m_rcSplitter.bottom;
}
else
{
lpRect->left = m_rcSplitter.left;
lpRect->top = m_rcSplitter.top + m_xySplitterPos;
lpRect->right = m_rcSplitter.right;
lpRect->bottom = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
}
return TRUE;
}
BOOL CStaticSplitterWnd::GetSplitterPaneRect(int nPane, LPRECT lpRect) const
{
ASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT);
ASSERT(lpRect != NULL);
BOOL bRet = TRUE;
if(m_nSinglePane != SPLIT_PANE_NONE)
{
if(nPane == m_nSinglePane)
*lpRect = m_rcSplitter;
else
bRet = FALSE;
}
else if(nPane == SPLIT_PANE_LEFT)
{
if(m_bVertical)
{
lpRect->left = m_rcSplitter.left;
lpRect->top = m_rcSplitter.top;
lpRect->right = m_rcSplitter.left + m_xySplitterPos;
lpRect->bottom = m_rcSplitter.bottom;
}
else
{
lpRect->left = m_rcSplitter.left;
lpRect->top = m_rcSplitter.top;
lpRect->right = m_rcSplitter.right;
lpRect->bottom = m_rcSplitter.top + m_xySplitterPos;
}
}
else if(nPane == SPLIT_PANE_RIGHT)
{
if(m_bVertical)
{
lpRect->left = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
lpRect->top = m_rcSplitter.top;
lpRect->right = m_rcSplitter.right;
lpRect->bottom = m_rcSplitter.bottom;
}
else
{
lpRect->left = m_rcSplitter.left;
lpRect->top = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge;
lpRect->right = m_rcSplitter.right;
lpRect->bottom = m_rcSplitter.bottom;
}
}
else
{
bRet = FALSE;
}
return bRet;
}
BOOL CStaticSplitterWnd::IsOverSplitterRect(int x, int y) const
{
// -1 == don't check
return ((x == -1 || (x >= m_rcSplitter.left && x <= m_rcSplitter.right)) &&
(y == -1 || (y >= m_rcSplitter.top && y <= m_rcSplitter.bottom)));
}
BOOL CStaticSplitterWnd::IsOverSplitterBar(int x, int y) const
{
if(m_nSinglePane != SPLIT_PANE_NONE)
return FALSE;
if(m_xySplitterPos == -1 || !IsOverSplitterRect(x, y))
return FALSE;
int xy = m_bVertical ? x : y;
int xyOff = m_bVertical ? m_rcSplitter.left : m_rcSplitter.top;
return ((xy >= (xyOff + m_xySplitterPos)) && (xy < xyOff + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge));
}
void CStaticSplitterWnd::DrawGhostBar()
{
CRect rect = CRect(0, 0, 0, 0);
if(GetSplitterBarRect(&rect))
{
// invert the brush pattern (looks just like frame window sizing)
CWindowDC dc(this);
CBrush *pBrush = CDC::GetHalftoneBrush();
if(pBrush != NULL)
{
CBrush* pOldBrush = dc.SelectObject(pBrush);
dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
dc.SelectObject(pOldBrush);
}
}
}
void CStaticSplitterWnd::GetSystemSettings(BOOL bUpdate)
{
m_cxySplitBar = ::GetSystemMetrics(m_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME);
if((GetExStyle() & WS_EX_CLIENTEDGE))
{
m_cxyBarEdge = 2 * ::GetSystemMetrics(m_bVertical ? SM_CXEDGE : SM_CYEDGE);
m_cxyMin = 0;
}
else
{
m_cxyBarEdge = 0;
m_cxyMin = 2 * ::GetSystemMetrics(m_bVertical ? SM_CXEDGE : SM_CYEDGE);
}
::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0);
if(bUpdate)
UpdateSplitterLayout();
}
BOOL CStaticSplitterWnd::IsProportional() const
{
return ((m_dwExtendedStyle & SPLIT_PROPORTIONAL) != 0);
}
void CStaticSplitterWnd::StoreProportionalPos()
{
int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
if(cxyTotal > 0)
m_nProportionalPos = ::MulDiv(m_xySplitterPos, m_nPropMax, cxyTotal);
else
m_nProportionalPos = 0;
// TRACE2(TraceUI, 0, _T("CStaticSplitterWnd::StoreProportionalPos - %i\n"), m_nProportionalPos);
}
void CStaticSplitterWnd::UpdateProportionalPos()
{
int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
if(cxyTotal > 0)
{
int xyNewPos = ::MulDiv(m_nProportionalPos, cxyTotal, m_nPropMax);
m_bUpdateProportionalPos = FALSE;
SetSplitterPos(xyNewPos, FALSE);
}
}
BOOL CStaticSplitterWnd::IsRightAligned() const
{
return ((m_dwExtendedStyle & SPLIT_RIGHTALIGNED) != 0);
}
void CStaticSplitterWnd::StoreRightAlignPos()
{
int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
if(cxyTotal > 0)
m_nProportionalPos = cxyTotal - m_xySplitterPos;
else
m_nProportionalPos = 0;
// TRACE2(TraceUI, 0, _T("CStaticSplitterWnd::StoreRightAlignPos - %i\n"), m_nProportionalPos);
}
void CStaticSplitterWnd::UpdateRightAlignPos()
{
int cxyTotal = m_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge);
if(cxyTotal > 0)
{
m_bUpdateProportionalPos = FALSE;
SetSplitterPos(cxyTotal - m_nProportionalPos, FALSE);
}
}
BOOL CStaticSplitterWnd::IsInteractive() const
{
return ((m_dwExtendedStyle & SPLIT_NONINTERACTIVE) == 0);
}
void CStaticSplitterWnd::OnSize(UINT nType, int cx, int cy )
{
if(nType != SIZE_MINIMIZED)
SetSplitterRect();
CWnd::OnSize(nType, cx, cy);
}
BOOL CStaticSplitterWnd::CreateVertical(CWnd *pParent, DWORD dwStyle, UINT nID)
{
return Create(pParent, TRUE, dwStyle, nID);
}
BOOL CStaticSplitterWnd::CreateHorizonal(CWnd *pParent, DWORD dwStyle, UINT nID)
{
return Create(pParent, FALSE, dwStyle, nID);
}
BOOL CStaticSplitterWnd::Create(CWnd* pParent, BOOL bVertical, DWORD dwStyle, UINT nID)
{
ASSERT(pParent != NULL);
ASSERT((dwStyle & WS_CHILD) == WS_CHILD);
m_bVertical = bVertical;
return CWnd::Create(NULL, NULL, dwStyle, CRect(0, 0, 0, 0), pParent, nID);
}
BOOL CStaticSplitterWnd::PreCreateWindow(CREATESTRUCT &cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
return TRUE;
}
BOOL CStaticSplitterWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo )
{
for ( int i = 0; i < m_nPanesCount; i ++ )
{
if ( IsWindow(m_hWndPane[i]) )
{
CWnd* pWnd = CWnd::FromHandle(m_hWndPane[i]);
if ( pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo) )
return TRUE;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -