/******************************************** ** 工作室:S&P工作室 ** 作者 :张东斌 ** 日期 :2007年6月 *********************************************/ #include "stdafx.h" #include "SPVC80Helpers.h" #include "SPDrawHelpers.h" #include "resource.h" #include "SPPropertyGridInplaceEdit.h" #include "SPPropertyGridInplaceButton.h" #include "SPPropertyGridInplaceList.h" #include "SPPropertyGridItem.h" #include "SPPropertyGrid.h" #include "SPPropertyGridDefines.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif const int SPLITTER_HEIGHT = 3; const int TOOLBAR_HEIGHT = 25; ////////////////////////////////////////////////////////////////////////// // CSPPropertyGridUpdateContext CSPPropertyGridUpdateContext::CSPPropertyGridUpdateContext() { } ////////////////////////////////////////////////////////////////////////// // CSPPropertyGridVerb CSPPropertyGridVerb::CSPPropertyGridVerb() { } ////////////////////////////////////////////////////////////////////////// // CSPPropertyGridVerbs CSPPropertyGridVerbs::CSPPropertyGridVerbs() { } CSPPropertyGridVerbs::~CSPPropertyGridVerbs() { for ( int i = 0; i < m_arrVerbs.GetSize(); i++ ) { m_arrVerbs[i]->InternalRelease(); } } void CSPPropertyGridVerbs::RemoveAll() { if ( IsEmpty() ) { return; } for ( int i = 0; i < m_arrVerbs.GetSize(); i++ ) { m_arrVerbs[i]->InternalRelease(); } m_arrVerbs.RemoveAll(); m_pGrid->OnVerbsChanged(); } int CSPPropertyGridVerbs::GetCount() { return ( int ) m_arrVerbs.GetSize(); } void CSPPropertyGridVerbs::Add( LPCTSTR strCaption , UINT nID ) { CSPPropertyGridVerb * pVerb = new CSPPropertyGridVerb(); pVerb->m_nID = nID; pVerb->m_strCaption = strCaption; pVerb->m_pVerbs = this; pVerb->m_rcPart.SetRectEmpty(); pVerb->m_ptClick = CPoint( 0 ); pVerb->m_nIndex = ( UINT ) m_arrVerbs.Add( pVerb ); m_pGrid->OnVerbsChanged(); } ///////////////////////////////////////////////////////////////////////////// // CSPPropertyGridToolBar CSPPropertyGridToolBar::CSPPropertyGridToolBar() { m_cxLeftBorder = m_cxRightBorder = m_cyBottomBorder = m_cyTopBorder = 0; } BEGIN_MESSAGE_MAP(CSPPropertyGridToolBar, CToolBar) //{{AFX_MSG_MAP(CToolBar) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_NCCALCSIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CSPPropertyGridToolBar::OnEraseBkgnd( CDC * ) { return TRUE; } void CSPPropertyGridToolBar::OnNcCalcSize( BOOL /*bCalcValidRects*/ , NCCALCSIZE_PARAMS* /*lpncsp*/ ) { } void CSPPropertyGridToolBar::OnPaint() { CPaintDC dc ( this ); CSPClientRect rc ( this ); CSPBufferDC memDC ( dc,rc ); memDC.FillSolidRect( rc,GetXtremeColor( COLOR_3DFACE ) ); CToolBar::DefWindowProc( WM_PAINT,( WPARAM ) memDC.m_hDC,0 ); } void CSPPropertyGridToolBar::OnUpdateCmdUI( CFrameWnd* /*pTarget*/ , BOOL /*bDisableIfNoHndler*/ ) { } ///////////////////////////////////////////////////////////////////////////// // CSPPropertyGrid CSPPropertyGrid::CSPPropertyGrid() : m_bHelpVisible( TRUE ) , m_bToolBarVisible( FALSE ) , m_nHelpHeight( 58 ) { m_pView = 0; m_hCursorSplit = AfxGetApp()->LoadCursor( SP_IDC_VSPLITBAR ); m_hCursorHand = ::LoadCursor( 0,MAKEINTRESOURCE( 32649 ) ); if ( m_hCursorHand == 0 ) { m_hCursorHand = AfxGetApp()->LoadCursor( MAKEINTRESOURCE( SP_IDC_HAND ) ); } m_pPaintManager = new CSPPropertyGridPaintManager( this ); m_themeCurrent = SPGridThemeDefault; m_pVerbs = new CSPPropertyGridVerbs; m_pVerbs->m_pGrid = this; m_nVerbsHeight = 25; m_nFocusedVerb = -1; m_bVerbActivate = FALSE; m_bVerbsVisible = FALSE; m_bTabItems = FALSE; } CSPPropertyGrid::~CSPPropertyGrid() { delete m_pPaintManager; if ( m_pView ) { delete m_pView; } m_pVerbs->InternalRelease(); } CSPPropertyGridView * CSPPropertyGrid::CreateView() { return new CSPPropertyGridView(); } CSPPropertyGridView & CSPPropertyGrid::GetGridView() { if ( m_pView == 0 ) { m_pView = CreateView(); m_pView->m_pGrid = this; } return *m_pView; } IMPLEMENT_DYNAMIC( CSPPropertyGrid , CWnd ) BEGIN_MESSAGE_MAP(CSPPropertyGrid, CWnd) //{{AFX_MSG_MAP(CSPPropertyGrid) ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_SETFOCUS() ON_WM_KILLFOCUS() ON_WM_SIZE() ON_WM_SETCURSOR() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_KEYDOWN() ON_COMMAND(SP_IDC_SORT_ALPHABETIC, OnSortAlphabetic) ON_COMMAND(SP_IDC_SORT_CATEGORIZED, OnSortCategorized) ON_WM_SYSCOLORCHANGE() ON_WM_GETDLGCODE() //}}AFX_MSG_MAP END_MESSAGE_MAP() UINT CSPPropertyGrid::OnGetDlgCode() { return DLGC_WANTALLKEYS; } BOOL CSPPropertyGrid::Create( const RECT & rect , CWnd * pParentWnd , UINT nID , DWORD dwListStyle /*= LBS_OWNERDRAWFIXED| LBS_NOINTEGRALHEIGHT*/ ) { LPCTSTR pszCreateClass = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW,::LoadCursor( NULL,IDC_ARROW ) ); CSPEmptyRect rc; if ( !CreateEx( 0,pszCreateClass,_T( "" ),WS_TABSTOP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_GROUP,rc,pParentWnd,nID ) ) { return FALSE; } if ( !GetGridView().CreateEx( WS_EX_STATICEDGE,_T( "LISTBOX" ),NULL,WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_TABSTOP | dwListStyle,rc,this,0 ) ) { return FALSE; } GetGridView().ResetContent(); SetWindowPos( 0,rect.left,rect.top,rect.right - rect.left,rect.bottom - rect.top,SWP_SHOWWINDOW | SWP_NOZORDER ); SetStandardColors(); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CSPPropertyGrid message handlers BOOL CSPPropertyGrid::OnEraseBkgnd( CDC * ) { return TRUE; } void CSPPropertyGrid::OnPaint() { CPaintDC dcPaint ( this ); CSPClientRect rc ( this ); CSPBufferDC dc ( dcPaint,rc ); m_pPaintManager->FillPropertyGrid( &dc ); } CWnd * CSPPropertyGrid::GetNextGridTabItem( BOOL bForward ) { CWnd * pParent = this; if ( !pParent || !pParent->GetParent() ) { ASSERT( FALSE ); return 0 ; } CWnd * pNextItem = pParent->GetParent()->GetNextDlgTabItem( pParent,bForward ); if ( pNextItem == pParent ) { return 0; } return pNextItem; } void CSPPropertyGrid::OnNavigate( SPPropertyGridUI nUIElement , BOOL bForward , CSPPropertyGridItem * pItem ) { int nNextElement = bForward ? +1 : -1; int nUI = nUIElement + nNextElement; if ( pItem == NULL ) { pItem = GetGridView().GetSelectedItem(); } while ( nUI != nUIElement ) { if ( nUI == SPGridUIViewPrev ) { nUI += nNextElement; if ( m_bTabItems ) { int nIndex = !bForward && pItem ? pItem->m_nIndex - 1 : 0; if ( nIndex >= 0 ) { GetGridView().SetFocus(); GetGridView().SetCurSel( nIndex ); GetGridView().OnSelectionChanged(); if ( bForward ) return; nUI = SPGridUIInplaceButton; pItem = GetGridView().GetSelectedItem(); } } } if ( nUI == SPGridUIView ) { GetGridView().SetFocus(); return; } if ( nUI == SPGridUIInplaceEdit ) { if ( pItem && pItem->GetFlags() & SPGridItemHasEdit ) { pItem->OnSelect(); pItem->GetInplaceEdit().SetFocus(); pItem->GetInplaceEdit().SetSel( 0,-1 ); return; } nUI += nNextElement; } if ( nUI == SPGridUIInplaceButton ) { if ( pItem && pItem->GetInplaceButton().GetSafeHwnd() && pItem->GetInplaceButton().IsWindowVisible() && pItem->GetInplaceButton().GetItem() == pItem ) { pItem->GetInplaceButton().SetFocus(); return; } nUI += nNextElement; } if ( nUI == SPGridUIViewNext ) { if ( m_bTabItems ) { int nIndex = bForward ? ( pItem ? pItem->m_nIndex + 1 : 0 ) : GetGridView().GetCount() - 1; if ( nIndex < GetGridView().GetCount() ) { GetGridView().SetFocus(); GetGridView().SetCurSel( nIndex ); GetGridView().OnSelectionChanged(); if ( bForward ) return; pItem = GetGridView().GetSelectedItem(); } } nUI += nNextElement; } if ( nUI == SPGridUIVerb ) { if ( IsVerbsVisible() ) { m_nFocusedVerb = bForward ? 0 : m_pVerbs->GetCount() - 1; m_bVerbActivate = TRUE; SetFocus(); m_bVerbActivate = FALSE; Invalidate( FALSE ); return; } nUI += nNextElement; } if ( nUI == SPGridUIParentNext || nUI == SPGridUIParentPrev ) { CWnd * pWndNext = GetNextGridTabItem( !bForward ); if ( pWndNext != NULL ) { pWndNext->SetFocus(); return; } if ( nUI == SPGridUIParentNext ) nUI = SPGridUIViewPrev; else nUI = SPGridUIVerb; } if ( nUI < SPGridUIParentPrev || nUI > SPGridUIParentNext ) { ASSERT( FALSE ); return; } } } void CSPPropertyGrid::OnKeyDown( UINT nChar , UINT nRepCnt , UINT nFlags ) { if ( m_nFocusedVerb != -1 && IsVerbsVisible() ) { if ( m_nFocusedVerb >= m_pVerbs->GetCount() ) m_nFocusedVerb = m_pVerbs->GetCount() - 1; BOOL bForward = GetKeyState( VK_SHIFT ) >= 0; if ( ( nChar == VK_TAB ) && bForward && ( m_nFocusedVerb == m_pVerbs->GetCount() - 1 ) ) { OnNavigate( SPGridUIVerb,TRUE,NULL ); return; } else if ( ( nChar == VK_TAB ) && !bForward && ( m_nFocusedVerb == 0 ) ) { OnNavigate( SPGridUIVerb,FALSE,NULL ); return; } else if ( nChar == VK_RIGHT || nChar == VK_DOWN || ( ( nChar == VK_TAB ) && bForward ) ) { m_nFocusedVerb ++; if ( m_nFocusedVerb >= m_pVerbs->GetCount() ) m_nFocusedVerb = 0; Invalidate( FALSE ); } else if ( nChar == VK_LEFT || nChar == VK_UP || nChar == VK_TAB ) { m_nFocusedVerb --; if ( m_nFocusedVerb < 0 ) m_nFocusedVerb = m_pVerbs->GetCount() - 1; Invalidate( FALSE ); } else if ( nChar == VK_RETURN ) { CRect rcPart = m_pVerbs->GetAt( m_nFocusedVerb )->GetPart(); OnVerbClick( m_nFocusedVerb,CPoint( rcPart.left,rcPart.bottom ) ); } } CWnd::OnKeyDown( nChar,nRepCnt,nFlags ); } void CSPPropertyGrid::OnKillFocus( CWnd * pNewWnd ) { if ( m_nFocusedVerb != -1 ) { m_nFocusedVerb = -1; Invalidate( FALSE ); } CWnd::OnKillFocus( pNewWnd ); } void CSPPropertyGrid::OnSetFocus( CWnd * pOldWnd ) { if ( !m_bVerbActivate ) { if ( pOldWnd && pOldWnd == GetNextGridTabItem( FALSE ) && GetKeyState( VK_SHIFT ) < 0 ) { OnNavigate( SPGridUIParentNext,FALSE,NULL ); } else if ( pOldWnd && pOldWnd == GetNextGridTabItem( TRUE ) && GetKeyState( VK_SHIFT ) >= 0 ) { OnNavigate( SPGridUIParentPrev,TRUE,NULL ); } else { GetGridView().SetFocus(); } } else { CWnd::OnSetFocus( pOldWnd ); } } void CSPPropertyGrid::OnSize( UINT nType , int cx , int cy ) { CWnd::OnSize( nType,cx,cy ); if ( !GetGridView().GetSafeHwnd() ) { return; } Reposition( cx,cy ); } int CSPPropertyGrid::HitTest( CPoint pt ) { CSPClientRect rc ( this ); if ( m_bHelpVisible ) { CRect rcSplitter ( CPoint( rc.left,rc.bottom - SPLITTER_HEIGHT - m_nHelpHeight ),CSize( rc.Width(),SPLITTER_HEIGHT ) ); if ( rcSplitter.PtInRect( pt ) ) return SPGridHitHelpSplitter; rc.bottom -= SPLITTER_HEIGHT + m_nHelpHeight; } if ( IsVerbsVisible() ) { CRect rcSplitter ( CPoint( rc.left,rc.bottom - SPLITTER_HEIGHT - m_nVerbsHeight ),CSize( rc.Width(),SPLITTER_HEIGHT ) ); if ( rcSplitter.PtInRect( pt ) ) return SPGridHitVerbsSplitter; CRect rcVerbs ( rc ); rcVerbs.top = rc.bottom - m_nVerbsHeight; if ( rcVerbs.PtInRect( pt ) ) { CWindowDC dc ( this ); int nIndex = m_pPaintManager->HitTestVerbs( &dc,rcVerbs,pt ); if ( nIndex != -1 ) { return SPGridHitFirstVerb + nIndex; } } } return SPGridHitError; } BOOL CSPPropertyGrid::OnSetCursor( CWnd * pWnd , UINT nHitTest , UINT message ) { if ( nHitTest == HTCLIENT ) { CPoint point; GetCursorPos( &point ); ScreenToClient( &point ); int nHitTest = HitTest( point ); if ( nHitTest == SPGridHitHelpSplitter || nHitTest == SPGridHitVerbsSplitter ) { SetCursor( m_hCursorSplit ); return TRUE; } if ( ( nHitTest != -1 ) && ( nHitTest >= SPGridHitFirstVerb ) ) { SetCursor( m_hCursorHand ); return TRUE; } } return CWnd::OnSetCursor( pWnd,nHitTest,message ); } void CSPPropertyGrid::OnInvertTracker( CRect rect ) { ASSERT_VALID( this ); ASSERT( !rect.IsRectEmpty() ); ASSERT( ( GetStyle() & WS_CLIPCHILDREN ) == 0 ); // pat-blt without clip children on CDC * pDC = GetDC(); CBrush brush ( GetXtremeColor( COLOR_3DFACE ) ); CBrush *pBrush = ( CBrush * ) pDC->SelectObject( &brush ); pDC->PatBlt( rect.left,rect.top,rect.Width(),rect.Height(),PATINVERT ); pDC->SelectObject( pBrush ); ReleaseDC( pDC ); } void CSPPropertyGrid::OnSelectionChanged( CSPPropertyGridItem * pItem ) { CSPClientRect rc ( this ); CRect rcHelp ( rc ); rcHelp.top = rc.bottom - m_nHelpHeight; if ( pItem ) { GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_SELECTION_CHANGED,( LPARAM ) pItem ); } InvalidateRect( rcHelp,FALSE ); } void CSPPropertyGrid::OnVerbsChanged() { if ( m_bVerbsVisible != IsVerbsVisible() && GetGridView().m_nLockUpdate == 0 ) { CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } else if ( GetSafeHwnd() && GetGridView().m_nLockUpdate == 0 ) { Invalidate( FALSE ); } } void CSPPropertyGrid::OnVerbClick( int nIndex , CPoint pt ) { ClientToScreen( &pt ); ASSERT( nIndex < m_pVerbs->GetCount() ); CSPPropertyGridVerb * pVerb = m_pVerbs->GetAt( nIndex ); pVerb->m_ptClick = pt; GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_VERB_CLICK,( LPARAM ) pVerb ); } void CSPPropertyGrid::OnLButtonUp( UINT nFlags , CPoint point ) { if ( ( m_nFocusedVerb != -1 ) && ( m_nFocusedVerb == HitTest( point ) - SPGridHitFirstVerb ) ) { OnVerbClick( m_nFocusedVerb,point ); } else { CWnd::OnLButtonUp( nFlags,point ); } } void CSPPropertyGrid::OnLButtonDown( UINT nFlags , CPoint point ) { int nHitTest = HitTest( point ); if ( ( nHitTest != -1 ) && ( nHitTest >= SPGridHitFirstVerb ) ) { m_nFocusedVerb = nHitTest - SPGridHitFirstVerb; m_bVerbActivate = TRUE; SetFocus(); m_bVerbActivate = FALSE; Invalidate( FALSE ); return; } SetFocus(); if ( ( nHitTest == SPGridHitHelpSplitter ) || ( nHitTest == SPGridHitVerbsSplitter ) ) { SetCapture(); CSPClientRect rc ( this ); BOOL bHelpHitTest = nHitTest == SPGridHitHelpSplitter; CRect rcAvail = bHelpHitTest ? CRect( 0,20 + TOOLBAR_HEIGHT,rc.right,rc.bottom ) : CRect( 0,20 + TOOLBAR_HEIGHT,rc.right,rc.bottom - ( IsHelpVisible() ? m_nHelpHeight + SPLITTER_HEIGHT : 0 ) ); ModifyStyle( WS_CLIPCHILDREN | WS_CLIPSIBLINGS,0,FALSE ); m_rectTracker.SetRect( 0,point.y,rc.Width(),point.y + 3 ); OnInvertTracker( m_rectTracker ); BOOL bAccept = FALSE; while ( GetCapture() == this ) { MSG msg; if ( !GetMessage( &msg,NULL,0,0 ) ) break; if ( msg.message == WM_MOUSEMOVE ) { point = CPoint( msg.lParam ); point.y = __min( point.y,rcAvail.bottom - 20 ); point.y = __max( ( int ) point.y,int( rcAvail.top ) ); if ( m_rectTracker.top != point.y ) { OnInvertTracker( m_rectTracker ); m_rectTracker.OffsetRect( 0,point.y - m_rectTracker.top ); OnInvertTracker( m_rectTracker ); } } else if ( msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE ) break; else if ( msg.message == WM_LBUTTONUP ) { bAccept = TRUE; break; } else ::DispatchMessage( &msg ); } ReleaseCapture(); if ( bAccept ) { if ( bHelpHitTest ) m_nHelpHeight = rcAvail.bottom - m_rectTracker.top - 2; else m_nVerbsHeight = rcAvail.bottom - m_rectTracker.top - 2; Reposition( rc.Width(),rc.Height() ); } Invalidate( FALSE ); ModifyStyle( 0,WS_CLIPCHILDREN | WS_CLIPSIBLINGS,FALSE ); return; } CWnd::OnLButtonDown( nFlags,point ); } void CSPPropertyGrid::Reposition( int cx , int cy ) { if ( GetGridView().m_nLockUpdate > 0 ) { return; } if ( GetSafeHwnd() == 0 ) { return; } CRect rcView ( 0,0,cx,cy ); if ( m_bHelpVisible ) { rcView.bottom -= m_nHelpHeight + SPLITTER_HEIGHT; } if ( IsVerbsVisible() ) { rcView.bottom -= m_nVerbsHeight + SPLITTER_HEIGHT; } m_bVerbsVisible = IsVerbsVisible(); if ( m_bToolBarVisible ) { ASSERT( m_wndToolbar.GetSafeHwnd() ); CRect rcToolBar ( 1,1,cx - 1,TOOLBAR_HEIGHT - 1 ); m_wndToolbar.MoveWindow( rcToolBar ); rcView.top += TOOLBAR_HEIGHT; } GetGridView().MoveWindow( rcView ); Invalidate( FALSE ); } void CSPPropertyGrid::CreateToolbar() { #if _MSC_VER < 1200 m_wndToolbar.Create( this,TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE | CBRS_TOOLTIPS | WS_BORDER,0 ); #else m_wndToolbar.CreateEx( this,TBSTYLE_FLAT,WS_BORDER | WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS ); #endif VERIFY( m_wndToolbar.LoadToolBar( SP_IDR_TBAR_PROPGRID ) ); } void CSPPropertyGrid::ShowToolBar( BOOL bShow ) { if ( bShow && !m_wndToolbar.GetSafeHwnd() ) { CreateToolbar(); } else { if ( m_wndToolbar.GetSafeHwnd() ) { m_wndToolbar.ShowWindow( bShow ? SW_SHOW : SW_HIDE ); } } m_bToolBarVisible = bShow; CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); RefreshToolBarButtons(); } void CSPPropertyGrid::RefreshToolBarButtons() { if ( m_bToolBarVisible ) { m_wndToolbar.GetToolBarCtrl().SetState( SP_IDC_SORT_CATEGORIZED,TBSTATE_ENABLED | ( GetGridView().m_properetySort == SPGridSortCategorized ? TBSTATE_CHECKED : 0 ) ); m_wndToolbar.GetToolBarCtrl().SetState( SP_IDC_SORT_ALPHABETIC,TBSTATE_ENABLED | ( GetGridView().m_properetySort == SPGridSortAlphabetical ? TBSTATE_CHECKED : 0 ) ); } } void CSPPropertyGrid::ShowHelp( BOOL bShow ) { m_bHelpVisible = bShow; CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } void CSPPropertyGrid::OnSortAlphabetic() { SetPropertySort( SPGridSortAlphabetical ); } void CSPPropertyGrid::OnSortCategorized() { SetPropertySort( SPGridSortCategorized ); } void CSPPropertyGrid::OnSortChanged() { RefreshToolBarButtons(); OnSelectionChanged( NULL ); GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_SORTORDER_CHANGED,( LPARAM ) GetDlgCtrlID() ); } void CSPPropertyGrid::SetStandardColors() { m_clrHelpBack.SetDefaultValue(); m_clrHelpFore.SetDefaultValue(); GetGridView().m_clrLine.SetDefaultValue(); GetGridView().m_clrBack.SetDefaultValue(); GetGridView().m_clrFore.SetDefaultValue(); GetGridView().m_clrReadOnlyFore.SetDefaultValue(); GetGridView().m_clrCategoryFore.SetDefaultValue(); m_pPaintManager->RefreshMetrics(); RedrawWindow( NULL,NULL,RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE ); } void CSPPropertyGrid::SetCustomColors( COLORREF clrHelpBack , COLORREF clrHelpFore , COLORREF clrViewLine , COLORREF clrViewBack , COLORREF clrViewFore , COLORREF clrCategoryFore ) { m_clrHelpBack.SetCustomValue( clrHelpBack ); m_clrHelpFore.SetCustomValue( clrHelpFore ); GetGridView().m_clrLine.SetCustomValue( clrViewLine ); GetGridView().m_clrBack.SetCustomValue( clrViewBack ); GetGridView().m_clrFore.SetCustomValue( clrViewFore ); GetGridView().m_clrCategoryFore.SetCustomValue( clrCategoryFore ); RedrawWindow( NULL,NULL,RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE ); } void CSPPropertyGrid::ResetContent() { m_pVerbs->RemoveAll(); GetGridView().ResetContent(); GetGridView().m_nLockUpdate++; GetGridView().m_pCategories->Clear(); GetGridView().m_nLockUpdate--; } CSPPropertyGridItems * CSPPropertyGrid::GetCategories() { return GetGridView().m_pCategories; } CSPPropertyGridItem * CSPPropertyGrid::AddCategory( int nID ) { CString strCaption; VERIFY( strCaption.LoadString( nID ) ); CSPPropertyGridItem * pItem = GetGridView().AddCategory( strCaption ); pItem->SetID( nID ); return pItem; } CSPPropertyGridItem * CSPPropertyGrid::InsertCategory( int nIndex , int nID ) { CString strCaption; VERIFY( strCaption.LoadString( nID ) ); CSPPropertyGridItem * pItem = GetGridView().InsertCategory( nIndex,strCaption ); pItem->SetID( nID ); return pItem; } void CSPPropertyGrid::SetFont( CFont * pFont ) { LOGFONT lf; if ( pFont->GetLogFont( &lf ) ) { GetGridView().m_fontNormal.DeleteObject(); GetGridView().m_fontBold.DeleteObject(); lf.lfWeight = FW_NORMAL; VERIFY( GetGridView().m_fontNormal.CreateFontIndirect( &lf ) ); lf.lfWeight = FW_BOLD; VERIFY( GetGridView().m_fontBold.CreateFontIndirect( &lf ) ); if ( GetGridView().m_wndEdit.GetSafeHwnd() ) { GetGridView().m_wndEdit.SetFont( &GetGridView().m_fontNormal ); } Refresh(); } } void CSPPropertyGrid::Refresh() { GetGridView().SetPropertySort( GetPropertySort(),TRUE ); } void CSPPropertyGrid::SaveExpandingState( CSPPropertyGridItems * pItems , CMap< UINT, UINT, BOOL, BOOL& > * pState , UINT & nSelected ) { for ( int nItem = 0; nItem < pItems->GetCount(); nItem++ ) { CSPPropertyGridItem * pItem = pItems->GetAt( nItem ); if ( pItem->GetID() != 0 ) { if ( pItem->HasChilds() ) { BOOL bExpanded = pItem->IsExpanded(); pState->SetAt( pItem->GetID(),bExpanded ); } if ( pItem->IsSelected() ) nSelected = pItem->GetID(); } SaveExpandingState( pItem->GetChilds(),pState,nSelected ); } } void CSPPropertyGrid::RestoreExpandingState( CSPPropertyGridItems * pItems , CMap< UINT, UINT, BOOL, BOOL& > * pState ) { for ( int nItem = 0; nItem < pItems->GetCount(); nItem++ ) { CSPPropertyGridItem * pItem = pItems->GetAt( nItem ); BOOL bExpanded; if ( pItem->GetID() != 0 && pState->Lookup( pItem->GetID(),bExpanded ) ) { if ( bExpanded ) pItem->Expand(); else pItem->Collapse(); } RestoreExpandingState( pItem->GetChilds(),pState ); } } void CSPPropertyGrid::BeginUpdate( CSPPropertyGridUpdateContext & context ) { GetGridView().m_nLockUpdate = 1; context.m_nSelected = 0; SaveExpandingState( GetCategories(),&context.m_mapState,context.m_nSelected ); context.m_propertySort = GetPropertySort(); ResetContent(); } void CSPPropertyGrid::EndUpdate( CSPPropertyGridUpdateContext & context ) { RestoreExpandingState( GetCategories(),&context.m_mapState ); GetGridView().m_nLockUpdate = 0; GetGridView().SetPropertySort( context.m_propertySort,TRUE ); if ( context.m_nSelected > 0 ) { for ( int i = 0; i < GetGridView().GetCount(); i++ ) { CSPPropertyGridItem * pItem = ( CSPPropertyGridItem * ) GetGridView().GetItemDataPtr( i ); if ( pItem && pItem->GetID() == context.m_nSelected ) { pItem->Select(); break; } } } CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } void CSPPropertyGrid::SetVerbsHeight( int nHeight ) { ASSERT( nHeight > 0 ); m_nVerbsHeight = nHeight; if ( GetSafeHwnd() ) { CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } } void CSPPropertyGrid::SetHelpHeight( int nHeight ) { ASSERT( nHeight > 0 ); m_nHelpHeight = nHeight; if ( GetSafeHwnd() ) { CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } } void CSPPropertyGrid::SetViewDivider( double dDivider ) { ASSERT( dDivider > 0 && dDivider < 1 ); GetGridView().m_dDivider = dDivider; if ( GetSafeHwnd() ) { CSPClientRect rc ( this ); Reposition( rc.Width(),rc.Height() ); } } CSPPropertyGridItem * CSPPropertyGrid::GetSelectedItem() { return GetGridView().GetSelectedItem(); } void CSPPropertyGrid::SetTheme( SPPropertyGridPaintTheme paintTheme ) { ASSERT( m_pPaintManager ); delete m_pPaintManager; if ( paintTheme == SPGridThemeDefault ) { m_pPaintManager = new CSPPropertyGridPaintManager( this ); } else if ( paintTheme == SPGridThemeCool ) { m_pPaintManager = new CSPPropertyGridCoolTheme( this ); } else if ( paintTheme == SPGridThemeDelphi ) { m_pPaintManager = new CSPPropertyGridDelphiTheme( this ); } else if ( paintTheme == SPGridThemeNativeWinXP ) { m_pPaintManager = new CSPPropertyGridNativeXPTheme( this ); } else if ( paintTheme == SPGridThemeOffice2003 ) { m_pPaintManager = new CSPPropertyGridOffice2003Theme( this ); } else if ( paintTheme == SPGridThemeSimple ) { m_pPaintManager = new CSPPropertyGridSimpleTheme( this ); } else if ( paintTheme == SPGridThemeWhidbey ) { m_pPaintManager = new CSPPropertyGridWhidbeyTheme( this ); } else { ASSERT( FALSE ); } m_themeCurrent = paintTheme; if ( GetSafeHwnd() ) { RedrawWindow( NULL,NULL,RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE ); } } void CSPPropertyGrid::SetCustomTheme( CSPPropertyGridPaintManager * pPaintManager ) { ASSERT( m_pPaintManager ); delete m_pPaintManager; m_pPaintManager = pPaintManager; if ( GetSafeHwnd() ) { RedrawWindow( NULL,NULL,RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE ); } } void CSPPropertyGrid::OnSysColorChange() { CWnd::OnSysColorChange(); m_pPaintManager->RefreshMetrics(); }