📄 treepropsheetsplitter.cpp
字号:
// RealTimeSplitter.cpp
//
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 by Yves Tkaczyk
// (http://www.tkaczyk.net - yves@tkaczyk.net)
//
// The contents of this file are subject to the Artistic License (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.opensource.org/licenses/artistic-license.html
//
// Documentation: http://www.codeproject.com/property/treepropsheetex.asp
// CVS tree: http://sourceforge.net/projects/treepropsheetex
//
// /********************************************************************
// *
// * This code is an update of SimpleSplitter written by Robert A. T. Kaldy and
// * published on code project at http://www.codeproject.com/splitter/kaldysimplesplitter.asp.
// *
// *********************************************************************/
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TreePropSheetSplitter.h"
namespace TreePropSheet
{
#define FULL_SIZE 32768
inline int MulDivRound(int x, int mul, int div)
{
return (x * mul + div / 2) / div;
}
BEGIN_MESSAGE_MAP(CTreePropSheetSplitter, CWnd)
//{{AFX_MSG_MAP(CTreePropSheetSplitter)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_NCCREATE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CTreePropSheetSplitter::CTreePropSheetSplitter(const int nPanes, const UINT nOrientation, const int nMinSize, const int nBarThickness):
m_nPanes(nPanes),
m_nOrientation(nOrientation),
m_nBarThickness(nBarThickness),
m_nFrozenPaneCount(0),
m_bRealtimeUpdate(false),
m_bAllowUserResizing(true)
{
ASSERT(nMinSize >= 0);
// Common initialization
CommonInit();
// Set minimum pane sizes
for (int iPaneCnt = 0; iPaneCnt < m_nPanes; iPaneCnt++)
{
// Initialize minimum pane sizes.
m_pzMinSize[iPaneCnt] = nMinSize;
}
}
CTreePropSheetSplitter::CTreePropSheetSplitter(const int nPanes, const UINT nOrientation, const int* pzMinSize, const int nBarThickness):
m_nPanes(nPanes),
m_nOrientation(nOrientation),
m_nBarThickness(nBarThickness),
m_nFrozenPaneCount(0),
m_bRealtimeUpdate(false),
m_bAllowUserResizing(true)
{
// Common initialization
CommonInit();
// Set minimum pane sizes
for (int iPaneCnt = 0; iPaneCnt < m_nPanes; iPaneCnt++)
{
// Initialize minimum pane sizes.
m_pzMinSize[iPaneCnt] = pzMinSize[iPaneCnt];
}
}
CTreePropSheetSplitter::~CTreePropSheetSplitter()
{
delete[] m_pane;
delete[] m_size;
delete[] m_orig;
delete[] m_frozen;
delete[] m_pzMinSize;
}
///////////////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetSplitter::Create(CWnd* pParent, const CRect& rect, UINT nID)
{
ASSERT(pParent);
BOOL bRet = CreateEx(0, AfxRegisterWndClass(CS_DBLCLKS, GetCursorHandle(), NULL, NULL), NULL, WS_CHILD | WS_VISIBLE, rect, pParent, nID, NULL);
return bRet;
}
///////////////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetSplitter::Create(CWnd* pParent, UINT nID)
{
CRect rcOuter;
ASSERT(pParent);
pParent->GetClientRect(&rcOuter);
return Create( pParent, rcOuter, nID );
}
///////////////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetSplitter::CreatePane(int nIndex, CWnd* pPaneWnd, DWORD dwStyle, DWORD dwExStyle, LPCTSTR lpszClassName)
{
CRect rcPane;
ASSERT((nIndex >= 0) && (nIndex < m_nPanes));
m_pane[nIndex] = pPaneWnd;
dwStyle |= WS_CHILD | WS_VISIBLE;
GetPaneRect(nIndex, rcPane);
return pPaneWnd->CreateEx(dwExStyle, lpszClassName, NULL, dwStyle, rcPane, this, AFX_IDW_PANE_FIRST + nIndex);
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetPane(int nIndex, CWnd* pPaneWnd)
{
CRect rcPane;
ASSERT((nIndex >= 0) && (nIndex < m_nPanes));
ASSERT(pPaneWnd);
ASSERT(pPaneWnd->m_hWnd);
m_pane[nIndex] = pPaneWnd;
GetPaneRect(nIndex, rcPane);
pPaneWnd->MoveWindow(rcPane, false);
}
///////////////////////////////////////////////////////////////////////////////
//
CWnd* CTreePropSheetSplitter::GetPane(int nIndex) const
{
ASSERT((nIndex >= 0) && (nIndex < m_nPanes));
return m_pane[nIndex];
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetActivePane(int nIndex)
{
ASSERT((nIndex >= 0) && (nIndex < m_nPanes));
m_pane[nIndex]->SetFocus();
}
///////////////////////////////////////////////////////////////////////////////
//
CWnd* CTreePropSheetSplitter::GetActivePane(int& nIndex) const
{
for (int i = 0; i < m_nPanes; i++)
if (m_pane[i]->GetFocus())
{
nIndex = i;
return m_pane[i];
}
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetPaneSizes(const int* sizes)
{
int i, total = 0, total_in = 0;
for (i = 0; i < m_nPanes; i++)
{
ASSERT(sizes[i] >= 0);
total += sizes[i];
}
for (i = 0; i < m_nPanes - 1; i++)
{
m_size[i] = MulDivRound(sizes[i], FULL_SIZE, total);
total_in += m_size[i];
}
m_size[m_nPanes - 1] = FULL_SIZE - total_in;
RecalcLayout();
ResizePanes();
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::GetPaneRect(int nIndex, CRect& rcPane) const
{
ASSERT(nIndex >= 0 && nIndex < m_nPanes);
GetAdjustedClientRect(&rcPane);
if (m_nOrientation == SSP_HORZ)
{
rcPane.left = m_orig[nIndex];
rcPane.right = m_orig[nIndex + 1] - m_nBarThickness;
}
else
{
rcPane.top = m_orig[nIndex];
rcPane.bottom = m_orig[nIndex + 1] - m_nBarThickness;
}
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::GetBarRect(int nIndex, CRect& rcBar) const
{
ASSERT(nIndex > 0 && nIndex < m_nPanes - 1);
GetAdjustedClientRect(&rcBar);
if (m_nOrientation == SSP_HORZ)
{
rcBar.left = m_orig[nIndex];
rcBar.right = m_orig[nIndex + 1] - m_nBarThickness;
}
else
{
rcBar.top = m_orig[nIndex];
rcBar.bottom = m_orig[nIndex + 1] - m_nBarThickness;
}
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetFrozenPanes(const bool* frozenPanes)
{
m_nFrozenPaneCount = 0;
for( int i = 0; i < m_nPanes; ++i )
{
m_frozen[i] = frozenPanes[i];
if( frozenPanes[i] )
++m_nFrozenPaneCount;
}
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::ResetFrozenPanes()
{
for( int i = 0; i < m_nPanes; ++i )
{
m_frozen[i] = false;
}
m_nFrozenPaneCount = 0;
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetRealtimeUpdate(const bool bRealtime)
{
m_bRealtimeUpdate = bRealtime;
}
///////////////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetSplitter::IsRealtimeUpdate() const
{
return m_bRealtimeUpdate;
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::SetAllowUserResizing(const bool bAllowUserResizing)
{
m_bAllowUserResizing = bAllowUserResizing;
// If the window exists, reset the cursor.
if( ::IsWindow( GetSafeHwnd() ) )
{
::SetClassLong( GetSafeHwnd(), GCL_HCURSOR, (LONG)GetCursorHandle() );
}
}
///////////////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetSplitter::IsAllowUserResizing() const
{
return m_bAllowUserResizing;
}
///////////////////////////////////////////////////////////////////////////////
// Overridables
///////////////////////////////////////////////////////////////////////////////
void CTreePropSheetSplitter::UpdateParentRect(LPCRECT lpRectUpdate)
{
GetParent()->RedrawWindow( lpRectUpdate, NULL, RDW_UPDATENOW | RDW_INVALIDATE );
}
///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////
HCURSOR CTreePropSheetSplitter::GetCursorHandle() const
{
HCURSOR hCursor;
LPCTSTR lpszCursor = IDC_ARROW;
if( m_bAllowUserResizing )
lpszCursor = m_nOrientation == SSP_HORZ ? IDC_SIZEWE : IDC_SIZENS;
hCursor = (HCURSOR)::LoadImage(0, lpszCursor, IMAGE_CURSOR, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_SHARED );
return hCursor;
}
///////////////////////////////////////////////////////////////////////////////
//
void CTreePropSheetSplitter::CommonInit()
{
ASSERT(m_nPanes > 0);
ASSERT(m_nOrientation == SSP_HORZ || m_nOrientation == SSP_VERT);
ASSERT(m_nBarThickness >= 0);
int total = 0;
m_pane = new CWnd*[m_nPanes];
m_size = new int[m_nPanes];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -