SPPPropertyGridItem.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. /********************************************
  2. ** 工作室:S&P工作室
  3. ** 作者 :张东斌
  4. ** 日期 :2007年6月
  5. *********************************************/
  6. #include "StdAfx.h"
  7. #include "SPVC80Helpers.h"
  8. #include "SPDrawHelpers.h"
  9. #include "SPPropertyGridInplaceEdit.h"
  10. #include "SPPropertyGridInplaceButton.h"
  11. #include "SPPropertyGridInplaceList.h"
  12. #include "SPPropertyGridItem.h"
  13. #include "SPPropertyGrid.h"
  14. #include "SPPropertyGridDefines.h"
  15. #define SAFE_CALLPTR(p, f) if (p) p->f
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CSPPropertyGridItem
  23. IMPLEMENT_DYNAMIC( CSPPropertyGridItem , CCmdTarget )
  24. CSPPropertyGridItem::CSPPropertyGridItem( CString strCaption , LPCTSTR strValue , CString * pBindString )
  25. {
  26. Init();
  27. SetPrompt( strCaption );
  28. m_strValue = strValue;
  29. BindToString( pBindString );
  30. }
  31. CSPPropertyGridItem::CSPPropertyGridItem( UINT nID , LPCTSTR strValue , CString * pBindString )
  32. {
  33. Init();
  34. m_nID = nID;
  35. CString strPrompt;
  36. if ( strPrompt.LoadString( nID ) )
  37. {
  38. SetPrompt( strPrompt );
  39. }
  40. m_strValue = strValue;
  41. BindToString( pBindString );
  42. }
  43. CSPPropertyGridItem::~CSPPropertyGridItem()
  44. {
  45. if ( m_pGrid && m_pGrid->m_pSelected == this )
  46. {
  47. m_pGrid->m_pSelected = NULL;
  48. }
  49. m_pChilds->Clear();
  50. if ( GetInplaceButton().m_pItem == this )
  51. {
  52. GetInplaceButton().DestroyItem();
  53. }
  54. if ( GetInplaceList().m_pItem == this )
  55. {
  56. GetInplaceList().DestroyItem();
  57. }
  58. if ( GetInplaceEdit().m_pItem == this )
  59. {
  60. GetInplaceEdit().DestroyItem();
  61. }
  62. m_pChilds->InternalRelease();
  63. m_pConstraints->m_pItem = NULL;
  64. m_pConstraints->InternalRelease();
  65. }
  66. void CSPPropertyGridItem::SetPrompt( CString strText )
  67. {
  68. int nIndex = strText.Find( '\n' );
  69. if ( nIndex == -1 )
  70. {
  71. m_strCaption = strText;
  72. }
  73. else
  74. {
  75. m_strCaption = strText.Left( nIndex );
  76. m_strDescription = strText.Mid( nIndex + 1 );
  77. }
  78. }
  79. void CSPPropertyGridItem::Init()
  80. {
  81. m_bExpanded = FALSE;
  82. m_nIndex = -1;
  83. m_bVisible = FALSE;
  84. m_pParent = 0;
  85. m_pGrid = 0;
  86. m_nIndent = 0;
  87. m_strValue = "";
  88. m_bReadOnly = FALSE;
  89. m_bCategory = FALSE;
  90. m_nID = 0;
  91. m_nFlags = SPGridItemHasEdit;
  92. m_pConstraints = new CSPPropertyGridItemConstraints( this );
  93. m_pConstraints->SetCurrent( -1 );
  94. m_pBindString = 0;
  95. m_bConstraintEdit = FALSE;
  96. m_bUseMask = FALSE;
  97. m_bPassword = FALSE;
  98. m_chPrompt = _T( '*' );
  99. m_dwData = 0;
  100. EnableAutomation();
  101. m_pChilds = new CSPPropertyGridItems();
  102. }
  103. CSPPropertyGridItem * CSPPropertyGridItem::AddChildItem( CSPPropertyGridItem * pItem )
  104. {
  105. return InsertChildItem( m_pChilds->GetCount(),pItem );
  106. }
  107. CSPPropertyGridItem * CSPPropertyGridItem::InsertChildItem( int nIndex , CSPPropertyGridItem * pItem )
  108. {
  109. ASSERT( !pItem->IsCategory() || IsCategory() );
  110. if ( nIndex < 0 || nIndex > m_pChilds->GetCount() )
  111. {
  112. nIndex = m_pChilds->GetCount();
  113. }
  114. m_pChilds->InsertAt( nIndex,pItem );
  115. pItem->m_pGrid = pItem->m_pChilds->m_pGrid = m_pGrid;
  116. ASSERT( pItem->m_pParent == NULL );
  117. pItem->m_pParent = this;
  118. pItem->m_nIndent = m_nIndent + 1;
  119. pItem->OnAddChildItem();
  120. if ( m_bVisible )
  121. {
  122. if ( m_bExpanded )
  123. {
  124. m_pGrid->SetPropertySort( m_pGrid->m_properetySort,TRUE );
  125. }
  126. else if ( m_pGrid->GetSafeHwnd() && m_pChilds->GetCount() == 1 )
  127. {
  128. m_pGrid->Invalidate( FALSE );
  129. }
  130. }
  131. return pItem;
  132. }
  133. void CSPPropertyGridItem::Collapse()
  134. {
  135. if ( !m_bExpanded )
  136. {
  137. return;
  138. }
  139. if ( m_pGrid->m_nLockUpdate == 0 )
  140. {
  141. if ( m_pGrid->GetSafeHwnd() && m_bVisible )
  142. {
  143. m_pGrid->_DoCollapse( this );
  144. m_pGrid->OnSelectionChanged();
  145. }
  146. }
  147. m_bExpanded = FALSE;
  148. if ( m_pGrid->GetSafeHwnd() )
  149. {
  150. m_pGrid->GetParent()->GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_ITEMEXPANDCHANGED,( LPARAM )this );
  151. }
  152. }
  153. void CSPPropertyGridItem::Expand()
  154. {
  155. if ( m_bExpanded )
  156. {
  157. return;
  158. }
  159. if ( m_pGrid->m_nLockUpdate == 0 )
  160. {
  161. if ( m_pGrid->GetSafeHwnd() && m_bVisible )
  162. {
  163. m_pGrid->_DoExpand( this,m_nIndex );
  164. m_pGrid->_RefreshIndexes();
  165. m_pGrid->OnSelectionChanged();
  166. }
  167. }
  168. m_bExpanded = TRUE;
  169. if ( m_pGrid->GetSafeHwnd() )
  170. {
  171. m_pGrid->GetParent()->GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_ITEMEXPANDCHANGED,( LPARAM )this );
  172. }
  173. }
  174. BOOL CSPPropertyGridItem::HasParent( CSPPropertyGridItem * pParent )
  175. {
  176. if ( m_pParent == NULL )
  177. {
  178. return FALSE;
  179. }
  180. if ( m_pParent == pParent )
  181. {
  182. return TRUE;
  183. }
  184. return m_pParent->HasParent( pParent );
  185. }
  186. void CSPPropertyGridItem::Select()
  187. {
  188. ASSERT( m_pGrid );
  189. if ( m_bVisible )
  190. {
  191. m_pGrid->SetCurSel( m_nIndex );
  192. m_pGrid->OnSelectionChanged();
  193. }
  194. }
  195. void CSPPropertyGridItem::OnDeselect()
  196. {
  197. GetInplaceButton().HideWindow();
  198. OnValidateEdit();
  199. }
  200. void CSPPropertyGridItem::OnValidateEdit()
  201. {
  202. GetInplaceEdit().HideWindow();
  203. if ( GetInplaceEdit().GetSafeHwnd() && GetInplaceEdit().m_pItem == this )
  204. {
  205. CString strValue;
  206. GetInplaceEdit().GetWindowText( strValue );
  207. if ( m_strValue != strValue )
  208. {
  209. OnValueChanged( strValue );
  210. }
  211. }
  212. }
  213. void CSPPropertyGridItem::SetEditText( CString str )
  214. {
  215. if ( !m_pGrid )
  216. {
  217. return;
  218. }
  219. if ( GetInplaceEdit().GetSafeHwnd() && GetInplaceEdit().m_pItem == this )
  220. {
  221. GetInplaceEdit().SetWindowText( str );
  222. }
  223. }
  224. void CSPPropertyGridItem::SetValue( CString strValue )
  225. {
  226. m_strValue = strValue;
  227. if ( m_pBindString )
  228. {
  229. *m_pBindString = strValue;
  230. }
  231. SetEditText( m_strValue );
  232. if ( m_pGrid && m_pGrid->m_hWnd )
  233. {
  234. m_pGrid->Invalidate( FALSE );
  235. }
  236. }
  237. void CSPPropertyGridItem::OnValueChanged( CString strValue )
  238. {
  239. SetValue( strValue );
  240. m_pGrid->Invalidate( FALSE );
  241. m_pGrid->GetParent()->GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_ITEMVALUE_CHANGED,( LPARAM )this );
  242. }
  243. void CSPPropertyGridItem::OnSelect()
  244. {
  245. ASSERT( m_bVisible );
  246. if ( !m_bReadOnly && ( m_nFlags & ( SPGridItemHasComboButton | SPGridItemHasExpandButton ) ) )
  247. {
  248. GetInplaceButton().Create( this,GetItemRect() );
  249. }
  250. else
  251. {
  252. GetInplaceButton().HideWindow();
  253. }
  254. if ( m_nFlags & SPGridItemHasEdit )
  255. {
  256. GetInplaceEdit().SetValue( m_strValue );
  257. GetInplaceEdit().Create( this,GetValueRect() );
  258. GetInplaceEdit().SetReadOnly( m_bReadOnly );
  259. }
  260. else
  261. {
  262. GetInplaceEdit().HideWindow();
  263. }
  264. }
  265. void CSPPropertyGridItem::OnInplaceButtonDown()
  266. {
  267. if ( GetReadOnly() )
  268. {
  269. return;
  270. }
  271. if ( m_pGrid->GetParent()->GetOwner()->SendMessage( SPWM_PROPERTYGRID_NOTIFY,SP_PGN_INPLACEBUTTONDOWN,( LPARAM )this ) == TRUE )
  272. {
  273. return;
  274. }
  275. if ( ( m_nFlags & SPGridItemHasComboButton ) && !m_pConstraints->IsEmpty() )
  276. {
  277. GetInplaceList().Create( this,GetItemRect() );
  278. m_pGrid->Invalidate( FALSE );
  279. }
  280. }
  281. CRect CSPPropertyGridItem::GetValueRect()
  282. {
  283. ASSERT( m_bVisible );
  284. CRect rc = GetItemRect();
  285. CRect rcValue ( m_pGrid->GetDividerPos() + 1,rc.top + 1,rc.right,rc.bottom - 1 );
  286. if ( m_nFlags & ( SPGridItemHasComboButton | SPGridItemHasExpandButton ) )
  287. {
  288. if ( GetInplaceButton().m_pItem == this && GetInplaceButton().GetStyle() & WS_VISIBLE )
  289. {
  290. rcValue.right -= GetSystemMetrics( SM_CXHTHUMB );
  291. }
  292. }
  293. return rcValue;
  294. }
  295. CRect CSPPropertyGridItem::GetItemRect()
  296. {
  297. CRect rc;
  298. m_pGrid->GetItemRect( m_nIndex,rc );
  299. return rc;
  300. }
  301. BOOL CSPPropertyGridItem::OnChar( UINT nChar )
  302. {
  303. ASSERT( nChar != VK_TAB );
  304. if ( m_nFlags & SPGridItemHasEdit )
  305. {
  306. OnSelect();
  307. GetInplaceEdit().SetFocus();
  308. GetInplaceEdit().SetSel( 0,-1 );
  309. if ( nChar != VK_TAB )
  310. GetInplaceEdit().SendMessage( WM_CHAR,nChar );
  311. return TRUE;
  312. }
  313. else if ( nChar == VK_TAB )
  314. {
  315. CSPPropertyGridInplaceButton& wndButton = GetInplaceButton();
  316. if ( wndButton.GetSafeHwnd() && wndButton.IsWindowVisible() && wndButton.GetItem() == this )
  317. {
  318. wndButton.SetFocus();
  319. }
  320. }
  321. return FALSE;
  322. }
  323. void CSPPropertyGridItem::OnLButtonDblClk()
  324. {
  325. if ( HasChilds() )
  326. {
  327. if ( m_bExpanded )
  328. {
  329. Collapse();
  330. }
  331. else
  332. {
  333. Expand();
  334. }
  335. }
  336. else
  337. {
  338. OnSelect();
  339. if ( m_nFlags & SPGridItemHasEdit )
  340. {
  341. if ( !GetReadOnly() && GetInplaceEdit().SelectConstraint( +1,TRUE ) )
  342. {
  343. OnValidateEdit();
  344. }
  345. else
  346. {
  347. GetInplaceEdit().SetFocus();
  348. GetInplaceEdit().SetSel( 0,-1 );
  349. }
  350. }
  351. else if ( !GetReadOnly() )
  352. {
  353. CSPPropertyGridItemConstraints *pList = GetConstraints();
  354. if ( pList->IsEmpty() )
  355. return ;
  356. int nIndex = pList->FindConstraint( m_strValue );
  357. nIndex += +1;
  358. if ( nIndex >= pList->GetCount() )
  359. nIndex = 0;
  360. if ( nIndex < 0 )
  361. nIndex = ( ULONG ) pList->GetCount() - 1;
  362. pList->SetCurrent( nIndex );
  363. OnValueChanged( pList->GetAt( nIndex ) );
  364. }
  365. }
  366. }
  367. BOOL CSPPropertyGridItem::OnLButtonDown( UINT , CPoint point )
  368. {
  369. Select();
  370. int nOffset = ( m_nIndent - ( IsCategory() ? 0 : 1 ) ) * SP_PGI_EXPAND_BORDER;
  371. if ( point.x >= nOffset && point.x <= SP_PGI_EXPAND_BORDER + nOffset )
  372. {
  373. if ( m_bExpanded )
  374. {
  375. Collapse();
  376. }
  377. else
  378. {
  379. Expand();
  380. }
  381. }
  382. CRect rc = GetValueRect();
  383. if ( ( m_nFlags & SPGridItemHasEdit ) && rc.PtInRect( point ) )
  384. {
  385. mouse_event( GetSystemMetrics( SM_SWAPBUTTON ) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN,0,0,0,0 );
  386. }
  387. return TRUE;
  388. }
  389. void CSPPropertyGridItem::BindToString( CString * pBindString )
  390. {
  391. m_pBindString = pBindString;
  392. if ( m_pBindString )
  393. {
  394. *m_pBindString = m_strValue;
  395. }
  396. }
  397. void CSPPropertyGridItem::OnBeforeInsert()
  398. {
  399. if ( m_pBindString && *m_pBindString != m_strValue )
  400. {
  401. m_strValue = *m_pBindString;
  402. }
  403. }
  404. CSPPropertyGridInplaceEdit & CSPPropertyGridItem::GetInplaceEdit()
  405. {
  406. if ( m_pGrid )
  407. {
  408. return m_pGrid->m_wndEdit;
  409. }
  410. static CSPPropertyGridInplaceEdit wndEdit;
  411. return wndEdit;
  412. }
  413. CSPPropertyGridInplaceButton & CSPPropertyGridItem::GetInplaceButton()
  414. {
  415. if ( m_pGrid )
  416. {
  417. return m_pGrid->m_wndButton;
  418. }
  419. static CSPPropertyGridInplaceButton wndButton;
  420. return wndButton;
  421. }
  422. CSPPropertyGridInplaceList & CSPPropertyGridItem::GetInplaceList()
  423. {
  424. if ( m_pGrid )
  425. {
  426. return m_pGrid->m_wndListBox;
  427. }
  428. static CSPPropertyGridInplaceList wndListBox;
  429. return wndListBox;
  430. }
  431. // Deletes the item.
  432. void CSPPropertyGridItem::Remove()
  433. {
  434. CSPPropertyGridItems * pItems = GetParentItem() == 0 ? m_pGrid->m_pCategories : GetParentItem()->m_pChilds;
  435. ASSERT( pItems );
  436. pItems->m_arrItems.RemoveAt( pItems->Find( this ) );
  437. m_pGrid->Refresh();
  438. InternalRelease();
  439. }
  440. BOOL CSPPropertyGridItem::IsSelected()
  441. {
  442. return m_pGrid && m_pGrid->GetSelectedItem() == this;
  443. }
  444. void CSPPropertyGridItem::Refresh( BOOL bInvalidate /*= TRUE*/ )
  445. {
  446. if ( m_pGrid && m_pGrid->GetSafeHwnd() )
  447. {
  448. if ( IsSelected() )
  449. {
  450. OnDeselect();
  451. OnSelect();
  452. }
  453. if ( bInvalidate )
  454. {
  455. m_pGrid->Invalidate( FALSE );
  456. }
  457. }
  458. }
  459. void CSPPropertyGridItem::SetReadOnly( BOOL bReadOnly )
  460. {
  461. if ( m_bReadOnly != bReadOnly )
  462. {
  463. m_bReadOnly = bReadOnly;
  464. Refresh( TRUE );
  465. }
  466. }
  467. void CSPPropertyGridItem::SetMask( LPCTSTR strMask , LPCTSTR strLiteral , TCHAR chPrompt /*= _T('_')*/ )
  468. {
  469. m_bUseMask = TRUE;
  470. m_strMask = strMask;
  471. m_strLiteral = strLiteral;
  472. m_chPrompt = chPrompt;
  473. Refresh( FALSE );
  474. }
  475. CString CSPPropertyGridItem::GetViewValue()
  476. {
  477. CString str = GetValue();
  478. if ( m_bPassword )
  479. {
  480. return CString( m_chPrompt,str.GetLength() );
  481. }
  482. return str;
  483. }
  484. CString CSPPropertyGridItem::GetMaskedText()
  485. {
  486. if ( m_bUseMask )
  487. {
  488. int nLength = m_strValue.GetLength();
  489. CString strBuffer;
  490. for ( int i = 0; i < nLength; ++i )
  491. {
  492. if ( m_strLiteral[i] == m_chPrompt )
  493. {
  494. strBuffer += m_strValue.GetAt( i );
  495. }
  496. }
  497. return strBuffer;
  498. }
  499. else
  500. {
  501. return m_strValue;
  502. }
  503. }
  504. void CSPPropertyGridItem::SetMaskedText( LPCTSTR lpszMaskedText )
  505. {
  506. CString strMaskedText = lpszMaskedText;
  507. if ( m_bUseMask )
  508. {
  509. int nLen = strMaskedText.GetLength();
  510. int x = 0;
  511. m_strValue = m_strLiteral;
  512. for ( int i = 0; ( i < m_strValue.GetLength() ) && ( x < nLen ); i++ )
  513. {
  514. if ( strMaskedText[x] == m_strValue[i] )
  515. {
  516. x ++;
  517. }
  518. else if ( m_strValue[i] == m_chPrompt )
  519. {
  520. m_strValue.SetAt( i,strMaskedText[x] );
  521. x ++;
  522. }
  523. }
  524. }
  525. else
  526. {
  527. m_strValue = strMaskedText;
  528. }
  529. SetValue( m_strValue );
  530. }
  531. void CSPPropertyGridItem::SetDescription( LPCTSTR lpszDescription )
  532. {
  533. m_strDescription = lpszDescription;
  534. if ( IsSelected() )
  535. {
  536. GetGrid()->GetParent()->Invalidate( FALSE );
  537. }
  538. }
  539. /////////////////////////////////////////////////////////////////////////////
  540. // CSPPropertyGridItems
  541. CSPPropertyGridItems::CSPPropertyGridItems()
  542. {
  543. m_pGrid = 0;
  544. }
  545. void CSPPropertyGridItems::Clear()
  546. {
  547. if ( m_pGrid )
  548. {
  549. if ( m_pGrid->m_nLockUpdate == 0 )
  550. m_pGrid->ResetContent();
  551. m_pGrid->m_nLockUpdate++;
  552. }
  553. for ( int i = 0; i < GetCount(); i++ )
  554. {
  555. m_arrItems[i]->InternalRelease();
  556. }
  557. m_arrItems.RemoveAll();
  558. if ( m_pGrid )
  559. {
  560. m_pGrid->m_nLockUpdate--;
  561. if ( m_pGrid->m_nLockUpdate == 0 )
  562. m_pGrid->Refresh();
  563. }
  564. }
  565. CSPPropertyGridItem * CSPPropertyGridItems::GetAt( int nIndex )
  566. {
  567. if ( nIndex >= 0 && nIndex < GetCount() )
  568. {
  569. return m_arrItems.GetAt( nIndex );
  570. }
  571. return 0;
  572. }
  573. void CSPPropertyGridItems::RemoveAt( int nIndex )
  574. {
  575. ASSERT( m_pGrid );
  576. CSPPropertyGridItem * pItem = GetAt( nIndex );
  577. if ( pItem )
  578. {
  579. m_arrItems.RemoveAt( nIndex );
  580. m_pGrid->Refresh();
  581. pItem->InternalRelease();
  582. }
  583. }
  584. int CSPPropertyGridItems::Find( CSPPropertyGridItem * pItem )
  585. {
  586. for ( int i = 0; i < GetCount(); i++ )
  587. {
  588. if ( m_arrItems[i] == pItem )
  589. {
  590. return i;
  591. }
  592. }
  593. return -1;
  594. }
  595. void CSPPropertyGridItems::AddTail( CSPPropertyGridItems * pItems )
  596. {
  597. ASSERT( this != pItems );
  598. for ( int i = 0; i < pItems->GetCount(); i++ )
  599. {
  600. AddTail( pItems->GetAt( i ) );
  601. }
  602. }
  603. int CSPPropertyGridItems::CompareFunc( const CSPPropertyGridItem ** ppItem1 , const CSPPropertyGridItem ** ppItem2 )
  604. {
  605. return ( *ppItem1 )->GetCaption().Compare( ( *ppItem2 )->GetCaption() );
  606. }
  607. void CSPPropertyGridItems::Sort()
  608. {
  609. typedef int ( _cdecl *GENERICCOMPAREFUNC )( const void * , const void * );
  610. qsort( m_arrItems.GetData(),m_arrItems.GetSize(),sizeof( CSPPropertyGridItem * ),( GENERICCOMPAREFUNC ) CompareFunc );
  611. }
  612. CSPPropertyGridItem * CSPPropertyGridItems::FindItem( CString strCaption )
  613. {
  614. for ( int i = 0; i < GetCount(); i++ )
  615. {
  616. CSPPropertyGridItem * pItem = GetAt( i );
  617. if ( pItem->GetCaption() == strCaption )
  618. return pItem;
  619. CSPPropertyGridItem * pChild = pItem->m_pChilds->FindItem( strCaption );
  620. if ( pChild )
  621. return pChild;
  622. }
  623. return NULL;
  624. }
  625. CSPPropertyGridItem * CSPPropertyGridItems::FindItem( UINT nID )
  626. {
  627. for ( int i = 0; i < GetCount(); i++ )
  628. {
  629. CSPPropertyGridItem * pItem = GetAt( i );
  630. if ( pItem->GetID() == nID )
  631. return pItem;
  632. CSPPropertyGridItem * pChild = pItem->m_pChilds->FindItem( nID );
  633. if ( pChild )
  634. return pChild;
  635. }
  636. return NULL;
  637. }
  638. //////////////////////////////////////////////////////////////////////////
  639. // CSPPropertyGridItemConstraint
  640. CSPPropertyGridItemConstraint::CSPPropertyGridItemConstraint()
  641. {
  642. m_nIndex = 0;
  643. m_dwData = 0;
  644. }
  645. /////////////////////////////////////////////////////////////////////////////
  646. // CSPPropertyGridItemConstraints
  647. // Summary: Constructs a CSPPropertyGridItemConstraints object
  648. CSPPropertyGridItemConstraints::CSPPropertyGridItemConstraints( CSPPropertyGridItem * pItem )
  649. {
  650. m_pItem = pItem;
  651. }
  652. CSPPropertyGridItemConstraints::~CSPPropertyGridItemConstraints()
  653. {
  654. RemoveAll();
  655. }
  656. CSPPropertyGridItemConstraint * CSPPropertyGridItemConstraints::AddConstraint( CString str , DWORD dwData )
  657. {
  658. CSPPropertyGridItemConstraint * pConstaint = new CSPPropertyGridItemConstraint();
  659. pConstaint->m_strConstraint = str;
  660. pConstaint->m_dwData = dwData;
  661. pConstaint->m_nIndex = ( int ) m_arrConstraints.Add( pConstaint );
  662. SAFE_CALLPTR( m_pItem,OnConstraintsChanged() );
  663. return pConstaint;
  664. }
  665. CString CSPPropertyGridItemConstraints::GetAt( int nIndex )
  666. {
  667. return nIndex >= 0 && nIndex < GetCount() ? m_arrConstraints.GetAt( nIndex )->m_strConstraint : _T( "" );
  668. }
  669. void CSPPropertyGridItemConstraints::RemoveAll()
  670. {
  671. for ( int i = 0; i < GetCount(); i++ )
  672. {
  673. m_arrConstraints[i]->InternalRelease();
  674. }
  675. m_arrConstraints.RemoveAll();
  676. SAFE_CALLPTR( m_pItem,OnConstraintsChanged() );
  677. }
  678. void CSPPropertyGridItemConstraints::RemoveAt( int nIndex )
  679. {
  680. m_arrConstraints[nIndex]->InternalRelease();
  681. m_arrConstraints.RemoveAt( nIndex );
  682. for ( int i = nIndex; i < GetCount(); i++ )
  683. {
  684. m_arrConstraints[i]->m_nIndex = i;
  685. }
  686. SAFE_CALLPTR( m_pItem,OnConstraintsChanged() );
  687. }
  688. int CSPPropertyGridItemConstraints::FindConstraint( CString str )
  689. {
  690. for ( int i = 0; i < GetCount(); i++ )
  691. {
  692. if ( str == GetAt( i ) )
  693. {
  694. return i;
  695. }
  696. }
  697. return -1;
  698. }
  699. int CSPPropertyGridItemConstraints::FindConstraint( DWORD dwData )
  700. {
  701. for ( int i = 0; i < GetCount(); i++ )
  702. {
  703. if ( dwData == GetConstraintAt( i )->m_dwData )
  704. {
  705. return i;
  706. }
  707. }
  708. return -1;
  709. }
  710. CSPPropertyGridItemConstraint * CSPPropertyGridItemConstraints::GetConstraintAt( int nIndex )
  711. {
  712. return m_arrConstraints[nIndex];
  713. }
  714. int CSPPropertyGridItemConstraints::CompareFunc( const CSPPropertyGridItemConstraint ** ppConstraint1 , const CSPPropertyGridItemConstraint ** ppConstraint2 )
  715. {
  716. return ( *ppConstraint1 )->m_strConstraint.Compare( ( *ppConstraint2 )->m_strConstraint );
  717. }
  718. void CSPPropertyGridItemConstraints::Sort()
  719. {
  720. typedef int ( _cdecl *GENERICCOMPAREFUNC )( const void * , const void * );
  721. qsort( m_arrConstraints.GetData(),( size_t ) m_arrConstraints.GetSize(),sizeof( CSPPropertyGridItemConstraint * ),( GENERICCOMPAREFUNC ) CompareFunc );
  722. }
  723. //////////////////////////////////////////////////////////////////////////
  724. // CSPPropertyGridItemCategory
  725. CSPPropertyGridItemCategory::CSPPropertyGridItemCategory( CString strCaption ) : CSPPropertyGridItem( strCaption )
  726. {
  727. m_bCategory = TRUE;
  728. m_nFlags = 0;
  729. }
  730. CSPPropertyGridItemCategory::CSPPropertyGridItemCategory( UINT nID ) : CSPPropertyGridItem( nID )
  731. {
  732. m_bCategory = TRUE;
  733. m_nFlags = 0;
  734. }
  735. ///////////////////////////////////////////////////////////////////////////////////
  736. // Acteve X Methods
  737. //