📄 treepropsheetex.cpp
字号:
{
m_pSplitter->SetRealtimeUpdate( m_bIsRealtimeSplitterMode );
}
}
//////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetEx::IsRealTimeSplitter() const
{
return m_bIsRealtimeSplitterMode;
}
//////////////////////////////////////////////////////////////////////
// Overrides
//////////////////////////////////////////////////////////////////////
BOOL CTreePropSheetEx::SetTreeWidth(int nWidth)
{
// If the sheet is not resizable and already dispalyed, we cannot set the width.
if( !IsSettingWidthValid() )
{
ASSERT( FALSE );
return false;
}
if( nWidth < 0 )
{
// ASSERT: Tree width cannot be negative. Maximum range is not checked.
ASSERT( FALSE );
return FALSE;
}
m_nPageTreeWidth = nWidth;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// Overridables
//////////////////////////////////////////////////////////////////////
CTreePropSheetEx::tSplitterPtr CTreePropSheetEx::CreateSplitterObject() const
{
const int zMinSizes[2] = { m_nTreeMinimumSize, m_nFrameMinimumSize };
return tSplitterPtr(new tSplitter( 2, SSP_HORZ, zMinSizes, m_nSplitterWidth ) );
}
//////////////////////////////////////////////////////////////////////
//
CTreePropSheetEx::tLayoutManagerPtr CTreePropSheetEx::CreateLayoutManagerObject()
{
ASSERT( m_bIsResizable );
return tLayoutManagerPtr( new tLayoutManager( this ) );
}
//////////////////////////////////////////////////////////////////////
//
CTreePropSheetEx::tLayoutManager* CTreePropSheetEx::GetLayoutManagerObject() const
{
return m_pResizeHook.get();
}
//////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////
void CTreePropSheetEx::Init()
{
m_psh.dwFlags &= ~( PSH_HASHELP );
m_bIsResizable = true;
m_bIsTreeResizable = true;
m_bIsRealtimeSplitterMode = true;
m_bSkipEmptyPages = false;
m_eSizingMode = TSM_Fixed;
m_eContextMenuMode = TPS_PropertySheetControls;
m_sizeSheetMinimumSize = kInitializeSize;
m_sizeSheetMaximumSize = kInitializeSize;
m_nSplitterWidth = 5;
m_nTreeMinimumSize = 148;
m_nFrameMinimumSize = 148;
}
//////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetEx::IsSettingWidthValid() const
{
return !IsWindow( m_hWnd ) || IsResizable();
}
//////////////////////////////////////////////////////////////////////
//
void CTreePropSheetEx::UpdateSheetMinimumSize()
{
// If the window exists, update it.
if( ::IsWindow( m_hWnd ) &&
IsResizable() &&
kInitializeSize != m_sizeSheetMinimumSize &&
NULL != m_pResizeHook.get() )
{
// Just make sure that the provided minimum width is
// wide enough according to minimum pane width.
ASSERT( m_sizeSheetMinimumSize.cx >= m_nTreeMinimumSize + m_nFrameMinimumSize + m_nSplitterWidth );
m_pResizeHook->SetMinSize( CSize( __max( m_sizeSheetMinimumSize.cx, m_nTreeMinimumSize + m_nFrameMinimumSize + m_nSplitterWidth ),
m_sizeSheetMinimumSize.cy ) );
}
}
//////////////////////////////////////////////////////////////////////
//
void CTreePropSheetEx::UpdateSheetMaximumSize()
{
// If the window exists, update it.
if( ::IsWindow( m_hWnd ) &&
IsResizable() &&
kInitializeSize != m_sizeSheetMaximumSize &&
NULL != m_pResizeHook.get() )
{
// Just make sure that the provided maximum size is
// larger than the minimum size.
ASSERT( m_sizeSheetMinimumSize.cx <= m_sizeSheetMaximumSize.cx );
ASSERT( m_sizeSheetMinimumSize.cy <= m_sizeSheetMaximumSize.cy );
m_pResizeHook->SetMaxSize( CSize( __max( m_sizeSheetMinimumSize.cx, m_sizeSheetMaximumSize.cx ),
__max( m_sizeSheetMinimumSize.cy, m_sizeSheetMaximumSize.cy ) ) );
}
}
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CTreePropSheetEx, CTreePropSheetBase)
//{{AFX_MSG_MAP(CTreePropSheetEx)
ON_WM_CREATE()
ON_WM_CONTEXTMENU()
ON_WM_DESTROY()
ON_WM_HELPINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTreePropSheetEx message handlers
//////////////////////////////////////////////////////////////////////
int CTreePropSheetEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreePropSheetBase::OnCreate(lpCreateStruct) == -1)
return -1;
// If the sheet is resizable, update the sheet window style to allow resizing.
if( IsResizable() )
{
// Prepare the property sheet to be resizable.
// keep client area
CRect rect;
GetClientRect(&rect);
// Do not change the window style if it is a child window.
if( lpCreateStruct->style & WS_POPUP )
{
// set resizable style
ModifyStyle(DS_MODALFRAME, WS_POPUP | WS_THICKFRAME );
}
// adjust size to reflect new style
::AdjustWindowRectEx(&rect, GetStyle(),::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREPOSITION);
}
return 0;
}
//////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetEx::OnInitDialog()
{
CTreePropSheetBase::OnInitDialog();
// Add the panes to the splitter.
if( IsTreeViewMode() )
{
if( IsResizable() )
{
// Create the splitter object.
m_pSplitter = CreateSplitterObject();
ASSERT( m_pSplitter.get() );
// Compute the proper position for the splitter control, that is union of tree and frame.
CRect rectTree, rectTab, rectSplit;
GetPageTreeControl()->GetWindowRect( &rectTree );
GetFrameControl()->GetWnd()->GetWindowRect( &rectTab );
rectSplit.UnionRect( &rectTree, &rectTab );
ScreenToClient( &rectSplit );
// Create the splitter window.
m_pSplitter->Create( this, rectSplit );
// Set the pane
m_pSplitter->SetPane( 0, GetPageTreeControl() ); // Pane 0 is the tree control
m_pSplitter->SetPane( 1, GetFrameControl()->GetWnd() ); // Pane 1 is the frame
const int vert_splitter_sizes[2] = { rectTree.Width(), rectTab.Width() };
m_pSplitter->SetPaneSizes( vert_splitter_sizes );
// Set frozen panes.
SetTreeResizingMode( m_eSizingMode );
// Set realtime mode.
SetRealTimeSplitter( m_bIsRealtimeSplitterMode );
// Enable/disable resizing in splitter.
m_pSplitter->SetAllowUserResizing( m_bIsTreeResizable );
}
}
// Initialize the layout library.
if( IsResizable() )
{
m_pResizeHook = CreateLayoutManagerObject();
ASSERT( m_pResizeHook.get() );
m_pResizeHook->Initialize();
// Set the minimum size.
UpdateSheetMinimumSize();
// Set the maximum size.
UpdateSheetMaximumSize();
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//////////////////////////////////////////////////////////////////////
//
void CTreePropSheetEx::OnContextMenu(CWnd* pWnd, CPoint point)
{
/*! \internal Based on the context menu mode and the window, the
message is either trapped or passed to the parent.*/
// TPS_None: Eat all messages
if( TPS_None == m_eContextMenuMode )
return;
// TPS_All: Delegate everything to the parent (TreePropSheet mode).
if( TPS_All == m_eContextMenuMode )
CTreePropSheetBase::OnContextMenu( pWnd, point );
// TPS_PropertySheetControls: Eat the messages for the tree and the
// frame control. The other windows are own by the property sheets
// and therefore should be notified.
ASSERT( TPS_PropertySheetControls == m_eContextMenuMode );
if( pWnd->GetSafeHwnd() != GetPageTreeControl()->GetSafeHwnd() &&
GetFrameControl() && pWnd->GetSafeHwnd() != GetFrameControl()->GetWnd()->GetSafeHwnd() )
CTreePropSheetBase::OnContextMenu( pWnd, point );
}
//////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetEx::OnHelpInfo(HELPINFO* pHelpInfo)
{
/* Forward help notification to property page in order to keep behavior
consistent with CpropertyPage.
Thanks to pablo_mag for the suggestion
http://www.codeproject.com/property/TreePropSheetEx.asp?msg=973632#xx973632xx */
CPropertyPage* page = GetActivePage();
if( page != NULL )
{
page->SendMessage(WM_HELP, 0, reinterpret_cast<LPARAM>(pHelpInfo) );
return TRUE;
}
return CTreePropSheetBase::OnHelpInfo(pHelpInfo);
}
} // namespace TreePropSheet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -