SPPPropertyGridInplaceList.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /********************************************
  2. ** 工作室:S&P工作室
  3. ** 作者 :张东斌
  4. ** 日期 :2007年6月
  5. *********************************************/
  6. #include "stdafx.h"
  7. #include "SPDrawHelpers.h"
  8. #include "SPVC80Helpers.h"
  9. #include "SPPropertyGridInplaceEdit.h"
  10. #include "SPPropertyGridInplaceButton.h"
  11. #include "SPPropertyGridInplaceList.h"
  12. #include "SPPropertyGridItem.h"
  13. #include "SPPropertyGridInplaceList.h"
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CSPPropertyGridInplaceList
  21. CSPPropertyGridInplaceList::CSPPropertyGridInplaceList() : m_pItem( 0 )
  22. {
  23. }
  24. CSPPropertyGridInplaceList::~CSPPropertyGridInplaceList()
  25. {
  26. }
  27. IMPLEMENT_DYNAMIC( CSPPropertyGridInplaceList , CListBox )
  28. BEGIN_MESSAGE_MAP(CSPPropertyGridInplaceList, CListBox)
  29. //{{AFX_MSG_MAP(CSPPropertyGridInplaceList)
  30. ON_WM_KILLFOCUS()
  31. ON_WM_LBUTTONUP()
  32. ON_WM_KEYDOWN()
  33. ON_WM_SYSKEYDOWN()
  34. ON_WM_MOUSEACTIVATE()
  35. //}}AFX_MSG_MAP
  36. END_MESSAGE_MAP()
  37. void CSPPropertyGridInplaceList::Create( CSPPropertyGridItem * pItem , CRect rect )
  38. {
  39. ASSERT( pItem && pItem->GetGrid() );
  40. CRect rcValue = pItem->GetValueRect();
  41. CWnd * pParent = ( CWnd * ) pItem->GetGrid();
  42. DestroyWindow();
  43. if ( !m_hWnd )
  44. {
  45. 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 );
  46. SetOwner( pParent );
  47. }
  48. SetFont( pParent->GetFont() );
  49. ResetContent();
  50. CSPPropertyGridItemConstraints *pList = pItem->GetConstraints();
  51. int nIndex = 0;
  52. int dx = rect.right - rcValue.left;
  53. CWindowDC dc ( pParent );
  54. CSPFontDC font ( &dc,pParent->GetFont() );
  55. SetItemHeight( 0,dc.GetTextExtent( _T( " " ) ).cy + 3 );
  56. int nThumbLength = GetSystemMetrics( SM_CXHTHUMB );
  57. for ( int i = 0; i < pList->GetCount(); i++ )
  58. {
  59. CString str = pList->GetAt( i );
  60. AddString( str );
  61. dx = __max( dx,dc.GetTextExtent( str ).cx + nThumbLength * 2 );
  62. if ( pItem->GetValue() == str )
  63. SetCurSel( nIndex );
  64. nIndex++;
  65. }
  66. int nHeight = GetItemHeight( 0 );
  67. rect.top = rect.bottom;
  68. rect.bottom += nHeight * __min( 10,GetCount() ) + 2;
  69. rect.left = rect.right - __min( dx,rect.Width() - SP_PGI_EXPAND_BORDER );
  70. pParent->ClientToScreen( &rect );
  71. CRect rcWork = CSPDrawHelpers::GetWorkArea( rcValue );
  72. if ( rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y )
  73. {
  74. rect.OffsetRect( 0,-rect.Height() - rcValue.Height() - 3 );
  75. }
  76. if ( rect.left < rcWork.left )
  77. {
  78. rect.OffsetRect( rcWork.left - rect.left,0 );
  79. }
  80. if ( rect.right > rcWork.right )
  81. {
  82. rect.OffsetRect( rcWork.right - rect.right,0 );
  83. }
  84. SetFocus();
  85. #ifdef SP_SITENOTIFY_ONFOCUS
  86. SP_SITENOTIFY_ONFOCUS( pParent,pParent,TRUE )
  87. #endif
  88. SetWindowLong( m_hWnd,GWL_HWNDPARENT,0 );
  89. ModifyStyle( WS_CHILD,WS_POPUP );
  90. SetWindowLongPtr( m_hWnd,GWL_HWNDPARENT,( LONG_PTR ) pParent->m_hWnd );
  91. SetWindowPos( 0,rect.left,rect.top,rect.Width(),rect.Height(),SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE );
  92. CSPMouseMonitor::SetupHook( this );
  93. m_pItem = pItem;
  94. }
  95. /////////////////////////////////////////////////////////////////////////////
  96. // CSPPropertyGridInplaceList message handlers
  97. void CSPPropertyGridInplaceList::OnKillFocus( CWnd * pNewWnd )
  98. {
  99. CListBox::OnKillFocus( pNewWnd );
  100. ShowWindow( SW_HIDE );
  101. CSPMouseMonitor::SetupHook( NULL );
  102. #ifdef SP_SITENOTIFY_ONFOCUS
  103. SP_SITENOTIFY_ONFOCUS( GetOwner(),GetOwner(),FALSE )
  104. #endif
  105. }
  106. int CSPPropertyGridInplaceList::OnMouseActivate( CWnd* /*pDesktopWnd*/ , UINT /*nHitTest*/ , UINT /*message*/ )
  107. {
  108. return MA_NOACTIVATE;
  109. }
  110. void CSPPropertyGridInplaceList::PostNcDestroy()
  111. {
  112. CSPMouseMonitor::SetupHook( NULL );
  113. CListBox::PostNcDestroy();
  114. }
  115. void CSPPropertyGridInplaceList::OnLButtonUp( UINT , CPoint point )
  116. {
  117. CSPClientRect rc ( this );
  118. if ( rc.PtInRect( point ) )
  119. {
  120. Apply();
  121. }
  122. else
  123. {
  124. Cancel();
  125. }
  126. }
  127. void CSPPropertyGridInplaceList::Cancel( void )
  128. {
  129. GetOwner()->SetFocus();
  130. }
  131. void CSPPropertyGridInplaceList::Apply( void )
  132. {
  133. int nIndex = GetCurSel();
  134. if ( nIndex != LB_ERR )
  135. {
  136. CSPPropertyGridItemConstraints *pList = m_pItem->GetConstraints();
  137. pList->SetCurrent( nIndex );
  138. CString str;
  139. GetText( nIndex,str );
  140. if ( str != m_pItem->GetValue() )
  141. m_pItem->OnValueChanged( str );
  142. }
  143. GetOwner()->SetFocus();
  144. }
  145. void CSPPropertyGridInplaceList::OnKeyDown( UINT nChar , UINT nRepCnt , UINT nFlags )
  146. {
  147. if ( nChar == VK_ESCAPE )
  148. {
  149. Cancel();
  150. }
  151. else if ( nChar == VK_RETURN || nChar == VK_F4 )
  152. {
  153. Apply();
  154. }
  155. else
  156. {
  157. CListBox::OnKeyDown( nChar,nRepCnt,nFlags );
  158. }
  159. }
  160. void CSPPropertyGridInplaceList::OnSysKeyDown( UINT nChar , UINT nRepCnt , UINT nFlags )
  161. {
  162. if ( nChar == VK_DOWN || nChar == VK_UP )
  163. {
  164. Apply();
  165. return;
  166. }
  167. CListBox::OnSysKeyDown( nChar,nRepCnt,nFlags );
  168. }
  169. void CSPPropertyGridInplaceList::DestroyItem()
  170. {
  171. // reset variables to defaults.
  172. m_pItem = NULL;
  173. CSPMouseMonitor::SetupHook( NULL );
  174. // destroy the window.
  175. //DestroyWindow( );
  176. if ( ::IsWindow( m_hWnd ) )
  177. {
  178. ShowWindow( SW_HIDE );
  179. }
  180. }