/******************************************** ** 工作室:S&P工作室 ** 作者 :张东斌 ** 日期 :2007年6月 *********************************************/ #include "stdafx.h" #include "SPDrawHelpers.h" #include "SPVC80Helpers.h" #include "SPPropertyGridInplaceEdit.h" #include "SPPropertyGridInplaceButton.h" #include "SPPropertyGridInplaceList.h" #include "SPPropertyGridItem.h" #include "SPPropertyGridInplaceList.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSPPropertyGridInplaceList CSPPropertyGridInplaceList::CSPPropertyGridInplaceList() : m_pItem( 0 ) { } CSPPropertyGridInplaceList::~CSPPropertyGridInplaceList() { } IMPLEMENT_DYNAMIC( CSPPropertyGridInplaceList , CListBox ) BEGIN_MESSAGE_MAP(CSPPropertyGridInplaceList, CListBox) //{{AFX_MSG_MAP(CSPPropertyGridInplaceList) ON_WM_KILLFOCUS() ON_WM_LBUTTONUP() ON_WM_KEYDOWN() ON_WM_SYSKEYDOWN() ON_WM_MOUSEACTIVATE() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CSPPropertyGridInplaceList::Create( CSPPropertyGridItem * pItem , CRect rect ) { ASSERT( pItem && pItem->GetGrid() ); CRect rcValue = pItem->GetValueRect(); CWnd * pParent = ( CWnd * ) pItem->GetGrid(); DestroyWindow(); if ( !m_hWnd ) { CListBox::CreateEx( WS_EX_TOOLWINDOW | pParent->GetExStyle() & WS_EX_LAYOUTRTL,_T( "LISTBOX" ),_T( "" ),LBS_NOTIFY | WS_CHILD | WS_BORDER | WS_VSCROLL,CRect( 0,0,0,0 ),pParent,0 ); SetOwner( pParent ); } SetFont( pParent->GetFont() ); ResetContent(); CSPPropertyGridItemConstraints *pList = pItem->GetConstraints(); int nIndex = 0; int dx = rect.right - rcValue.left; CWindowDC dc ( pParent ); CSPFontDC font ( &dc,pParent->GetFont() ); SetItemHeight( 0,dc.GetTextExtent( _T( " " ) ).cy + 3 ); int nThumbLength = GetSystemMetrics( SM_CXHTHUMB ); for ( int i = 0; i < pList->GetCount(); i++ ) { CString str = pList->GetAt( i ); AddString( str ); dx = __max( dx,dc.GetTextExtent( str ).cx + nThumbLength * 2 ); if ( pItem->GetValue() == str ) SetCurSel( nIndex ); nIndex++; } int nHeight = GetItemHeight( 0 ); rect.top = rect.bottom; rect.bottom += nHeight * __min( 10,GetCount() ) + 2; rect.left = rect.right - __min( dx,rect.Width() - SP_PGI_EXPAND_BORDER ); pParent->ClientToScreen( &rect ); CRect rcWork = CSPDrawHelpers::GetWorkArea( rcValue ); if ( rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y ) { rect.OffsetRect( 0,-rect.Height() - rcValue.Height() - 3 ); } if ( rect.left < rcWork.left ) { rect.OffsetRect( rcWork.left - rect.left,0 ); } if ( rect.right > rcWork.right ) { rect.OffsetRect( rcWork.right - rect.right,0 ); } SetFocus(); #ifdef SP_SITENOTIFY_ONFOCUS SP_SITENOTIFY_ONFOCUS( pParent,pParent,TRUE ) #endif SetWindowLong( m_hWnd,GWL_HWNDPARENT,0 ); ModifyStyle( WS_CHILD,WS_POPUP ); SetWindowLongPtr( m_hWnd,GWL_HWNDPARENT,( LONG_PTR ) pParent->m_hWnd ); SetWindowPos( 0,rect.left,rect.top,rect.Width(),rect.Height(),SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE ); CSPMouseMonitor::SetupHook( this ); m_pItem = pItem; } ///////////////////////////////////////////////////////////////////////////// // CSPPropertyGridInplaceList message handlers void CSPPropertyGridInplaceList::OnKillFocus( CWnd * pNewWnd ) { CListBox::OnKillFocus( pNewWnd ); ShowWindow( SW_HIDE ); CSPMouseMonitor::SetupHook( NULL ); #ifdef SP_SITENOTIFY_ONFOCUS SP_SITENOTIFY_ONFOCUS( GetOwner(),GetOwner(),FALSE ) #endif } int CSPPropertyGridInplaceList::OnMouseActivate( CWnd* /*pDesktopWnd*/ , UINT /*nHitTest*/ , UINT /*message*/ ) { return MA_NOACTIVATE; } void CSPPropertyGridInplaceList::PostNcDestroy() { CSPMouseMonitor::SetupHook( NULL ); CListBox::PostNcDestroy(); } void CSPPropertyGridInplaceList::OnLButtonUp( UINT , CPoint point ) { CSPClientRect rc ( this ); if ( rc.PtInRect( point ) ) { Apply(); } else { Cancel(); } } void CSPPropertyGridInplaceList::Cancel( void ) { GetOwner()->SetFocus(); } void CSPPropertyGridInplaceList::Apply( void ) { int nIndex = GetCurSel(); if ( nIndex != LB_ERR ) { CSPPropertyGridItemConstraints *pList = m_pItem->GetConstraints(); pList->SetCurrent( nIndex ); CString str; GetText( nIndex,str ); if ( str != m_pItem->GetValue() ) m_pItem->OnValueChanged( str ); } GetOwner()->SetFocus(); } void CSPPropertyGridInplaceList::OnKeyDown( UINT nChar , UINT nRepCnt , UINT nFlags ) { if ( nChar == VK_ESCAPE ) { Cancel(); } else if ( nChar == VK_RETURN || nChar == VK_F4 ) { Apply(); } else { CListBox::OnKeyDown( nChar,nRepCnt,nFlags ); } } void CSPPropertyGridInplaceList::OnSysKeyDown( UINT nChar , UINT nRepCnt , UINT nFlags ) { if ( nChar == VK_DOWN || nChar == VK_UP ) { Apply(); return; } CListBox::OnSysKeyDown( nChar,nRepCnt,nFlags ); } void CSPPropertyGridInplaceList::DestroyItem() { // reset variables to defaults. m_pItem = NULL; CSPMouseMonitor::SetupHook( NULL ); // destroy the window. //DestroyWindow( ); if ( ::IsWindow( m_hWnd ) ) { ShowWindow( SW_HIDE ); } }