XTPPropertyGridItem.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:34k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPPropertyGridItem.cpp : implementation of the CXTPPropertyGridItem class.
  2. //
  3. // This file is a part of the XTREME PROPERTYGRID MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "StdAfx.h"
  21. #include "Common/XTPVC80Helpers.h"
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "Common/XTPImageManager.h"
  24. #include "Common/XTPMarkupRender.h"
  25. #include "XTPPropertyGridInplaceEdit.h"
  26. #include "XTPPropertyGridInplaceButton.h"
  27. #include "XTPPropertyGridInplaceList.h"
  28. #include "XTPPropertyGridItem.h"
  29. #include "XTPPropertyGrid.h"
  30. #include "XTPPropertyGridDefines.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CXTPPropertyGridItem
  38. IMPLEMENT_DYNAMIC(CXTPPropertyGridItem, CCmdTarget)
  39. CXTPPropertyGridItem::CXTPPropertyGridItem(LPCTSTR lpszCaption, LPCTSTR strValue, CString* pBindString)
  40. {
  41. Init();
  42. SetPrompt(lpszCaption);
  43. m_strDefaultValue = m_strValue = strValue;
  44. BindToString(pBindString);
  45. }
  46. CXTPPropertyGridItem::CXTPPropertyGridItem(UINT nID, LPCTSTR strValue, CString* pBindString)
  47. {
  48. Init();
  49. m_nID = nID;
  50. CString strPrompt;
  51. if (strPrompt.LoadString(nID))
  52. {
  53. SetPrompt(strPrompt);
  54. }
  55. m_strDefaultValue = m_strValue = strValue;
  56. BindToString(pBindString);
  57. }
  58. CXTPPropertyGridItem::~CXTPPropertyGridItem()
  59. {
  60. Clear();
  61. XTPMarkupReleaseElement(m_pMarkupUIElement);
  62. }
  63. void CXTPPropertyGridItem::Clear()
  64. {
  65. if (m_pGrid && m_pGrid->m_pSelected == this)
  66. {
  67. m_pGrid->m_pSelected = NULL;
  68. }
  69. if (m_pGrid && m_pGrid->m_pHotButton && m_pInplaceButtons)
  70. {
  71. for (int i = 0; i < m_pInplaceButtons->GetCount(); i++)
  72. {
  73. if (m_pInplaceButtons->GetAt(i) == m_pGrid->m_pHotButton)
  74. {
  75. m_pGrid->m_pHotButton = NULL;
  76. break;
  77. }
  78. }
  79. }
  80. if (m_pGrid && GetInplaceList().m_pItem == this)
  81. {
  82. GetInplaceList().DestroyItem();
  83. }
  84. if (m_pGrid && GetInplaceEdit().m_pItem == this)
  85. {
  86. GetInplaceEdit().DestroyItem();
  87. }
  88. if (m_pChilds)
  89. {
  90. m_pChilds->Clear();
  91. CMDTARGET_RELEASE(m_pChilds);
  92. }
  93. if (m_pConstraints)
  94. {
  95. m_pConstraints->m_pItem = NULL;
  96. CMDTARGET_RELEASE(m_pConstraints);
  97. }
  98. CMDTARGET_RELEASE(m_pValueMetrics);
  99. CMDTARGET_RELEASE(m_pCaptionMetrics);
  100. CMDTARGET_RELEASE(m_pInplaceButtons);
  101. SAFE_DELETE(m_pInplaceControls);
  102. m_pGrid = NULL;
  103. }
  104. void CXTPPropertyGridItem::SetPrompt(LPCTSTR lpszPrompt)
  105. {
  106. if (lpszPrompt == 0)
  107. return;
  108. LPCTSTR lpszDescription = _tcschr(lpszPrompt, _T('n'));
  109. CString strCaption;
  110. if (lpszDescription == NULL)
  111. {
  112. strCaption = lpszPrompt;
  113. }
  114. else
  115. {
  116. int nLen = (int)(lpszDescription - lpszPrompt);
  117. LPTSTR lpszCaption = strCaption.GetBufferSetLength(nLen);
  118. MEMCPY_S(lpszCaption, lpszPrompt, nLen * sizeof(TCHAR));
  119. m_strDescription = lpszDescription + 1;
  120. }
  121. SetCaption(strCaption);
  122. }
  123. void CXTPPropertyGridItem::Init()
  124. {
  125. m_bHidden = FALSE;
  126. m_bExpanded = FALSE;
  127. m_nIndex = -1;
  128. m_bVisible = FALSE;
  129. m_pParent = 0;
  130. m_pGrid = 0;
  131. m_nIndent = 0;
  132. m_strValue = "";
  133. m_bReadOnly = FALSE;
  134. m_bCategory = FALSE;
  135. m_nID = 0;
  136. m_nFlags = xtpGridItemHasEdit;
  137. m_pConstraints = new CXTPPropertyGridItemConstraints(this);
  138. m_pInplaceButtons = new CXTPPropertyGridInplaceButtons(this);
  139. m_pInplaceControls = new CXTPPropertyGridInplaceControls();
  140. m_pConstraints->SetCurrent(-1);
  141. m_pBindString = 0;
  142. m_bConstraintEdit = FALSE;
  143. m_bAutoComplete = FALSE;
  144. m_nLinesCount = 1;
  145. m_nHeight = -1;
  146. m_nDropDownItemCount = 10;
  147. m_bExpandable = TRUE;
  148. m_bUseMask = FALSE;
  149. m_bPassword = FALSE;
  150. m_chPrompt = _T('*');
  151. m_dwData = 0;
  152. m_dwEditStyle = ES_AUTOHSCROLL;
  153. m_pMarkupUIElement = NULL;
  154. EnableAutomation();
  155. m_pValueMetrics = 0;
  156. m_pCaptionMetrics = 0;
  157. m_pChilds = new CXTPPropertyGridItems();
  158. }
  159. void CXTPPropertyGridItem::OnAddChildItem()
  160. {
  161. if (!m_bCategory) SetFlags(m_nFlags);
  162. }
  163. void CXTPPropertyGridItem::SetFlags(UINT nFlags)
  164. {
  165. ASSERT(!m_bCategory || ((nFlags & xtpGridItemHasEdit) == 0));
  166. m_nFlags = nFlags;
  167. m_pInplaceButtons->Remove(XTP_ID_PROPERTYGRID_EXPANDBUTTON);
  168. m_pInplaceButtons->Remove(XTP_ID_PROPERTYGRID_COMBOBUTTON);
  169. if (m_nFlags & xtpGridItemHasExpandButton)
  170. m_pInplaceButtons->AddExpandButton();
  171. if (m_nFlags & xtpGridItemHasComboButton)
  172. m_pInplaceButtons->AddComboButton();
  173. }
  174. UINT CXTPPropertyGridItem::GetFlags() const
  175. {
  176. return m_nFlags;
  177. }
  178. CXTPPropertyGridItemMetrics* CXTPPropertyGridItem::GetValueMetrics() const
  179. {
  180. if (m_pValueMetrics == 0)
  181. m_pValueMetrics = new CXTPPropertyGridItemMetrics(m_pGrid->GetPaintManager());
  182. return m_pValueMetrics;
  183. }
  184. CXTPPropertyGridItemMetrics* CXTPPropertyGridItem::GetCaptionMetrics() const
  185. {
  186. if (m_pCaptionMetrics == 0)
  187. m_pCaptionMetrics = new CXTPPropertyGridItemMetrics(m_pGrid->GetPaintManager());
  188. return m_pCaptionMetrics;
  189. }
  190. CXTPPropertyGridItemMetrics* CXTPPropertyGridItem::GetMetrics(BOOL bValueMetrics, BOOL bCreate /*= TRUE*/) const
  191. {
  192. if (bCreate)
  193. return bValueMetrics ? GetValueMetrics() : GetCaptionMetrics();
  194. return bValueMetrics ? m_pValueMetrics : m_pCaptionMetrics;
  195. }
  196. CXTPPropertyGridItem* CXTPPropertyGridItem::AddChildItem(CXTPPropertyGridItem* pItem)
  197. {
  198. return InsertChildItem(m_pChilds->GetCount(), pItem);
  199. }
  200. void CXTPPropertyGridItem::SetIndent(int nIndent)
  201. {
  202. m_nIndent = nIndent;
  203. for (int i = 0; i < m_pChilds->GetCount(); i++)
  204. {
  205. m_pChilds->GetAt(i)->SetIndent(nIndent + 1);
  206. }
  207. }
  208. CXTPPropertyGridItem* CXTPPropertyGridItem::InsertChildItem(int nIndex, CXTPPropertyGridItem* pItem)
  209. {
  210. ASSERT(pItem);
  211. if (!pItem)
  212. return NULL;
  213. ASSERT(!pItem->IsCategory() || IsCategory());
  214. ASSERT(m_pGrid != NULL);
  215. if (!m_pGrid)
  216. return pItem;
  217. if (nIndex < 0 || nIndex > m_pChilds->GetCount())
  218. nIndex = m_pChilds->GetCount();
  219. m_pChilds->InsertAt(nIndex, pItem);
  220. pItem->m_pGrid = m_pGrid;
  221. ASSERT(pItem->m_pParent == NULL);
  222. pItem->m_pParent = this;
  223. pItem->SetIndent(m_nIndent + 1);
  224. pItem->OnCaptionChanged();
  225. pItem->OnAddChildItem();
  226. if (m_bVisible)
  227. {
  228. if (m_bExpanded) m_pGrid->SetPropertySort(m_pGrid->m_properetySort, TRUE);
  229. else if (m_pGrid->GetSafeHwnd() && m_pChilds->GetCount() == 1) m_pGrid->Invalidate(FALSE);
  230. }
  231. return pItem;
  232. }
  233. void CXTPPropertyGridItem::Move(CXTPPropertyGridItem* pParent, int nIndex /* = -1 */)
  234. {
  235. if (!pParent)
  236. return;
  237. InternalAddRef();
  238. Remove();
  239. pParent->InsertChildItem(nIndex, this);
  240. }
  241. void CXTPPropertyGridItem::Collapse()
  242. {
  243. if (!m_bExpanded) return;
  244. if (m_pGrid->m_nLockUpdate == 0)
  245. {
  246. if (m_pGrid->GetSafeHwnd() && m_bVisible)
  247. {
  248. m_pGrid->_DoCollapse(this);
  249. m_pGrid->OnSelectionChanged();
  250. }
  251. }
  252. m_bExpanded = FALSE;
  253. m_pGrid->SendNotifyMessage(XTP_PGN_ITEMEXPANDCHANGED, (LPARAM)this);
  254. }
  255. void CXTPPropertyGridItem::Expand()
  256. {
  257. if (m_bExpanded) return;
  258. if (m_pGrid->m_nLockUpdate == 0)
  259. {
  260. if (m_pGrid->GetSafeHwnd() && m_bVisible)
  261. {
  262. m_pGrid->_DoExpand(this, m_nIndex);
  263. m_pGrid->_RefreshIndexes();
  264. m_pGrid->OnSelectionChanged();
  265. }
  266. }
  267. m_bExpanded = TRUE;
  268. m_pGrid->SendNotifyMessage(XTP_PGN_ITEMEXPANDCHANGED, (LPARAM)this);
  269. }
  270. BOOL CXTPPropertyGridItem::HasParent(CXTPPropertyGridItem* pParent)
  271. {
  272. if (m_pParent == NULL) return FALSE;
  273. if (m_pParent == pParent) return TRUE;
  274. return m_pParent->HasParent(pParent);
  275. }
  276. void CXTPPropertyGridItem::Select()
  277. {
  278. ASSERT(m_pGrid);
  279. if (!m_pGrid)
  280. return;
  281. if (!m_bVisible)
  282. return;
  283. if (m_pGrid->GetStyle() & LBS_MULTIPLESEL)
  284. {
  285. m_pGrid->SelItemRange(FALSE, 0, m_pGrid->GetCount());
  286. m_pGrid->SetSel(m_nIndex);
  287. }
  288. else
  289. {
  290. m_pGrid->SetCurSel(m_nIndex);
  291. }
  292. m_pGrid->OnSelectionChanged();
  293. }
  294. void CXTPPropertyGridItem::OnDeselect()
  295. {
  296. if (m_pGrid) m_pGrid->FocusInplaceButton(NULL);
  297. OnValidateEdit();
  298. for (int i = m_pInplaceControls->GetCount() - 1; i >= 0; i--)
  299. {
  300. CXTPPropertyGridInplaceControl* pControl = m_pInplaceControls->GetAt(i);
  301. pControl->OnDestroyWindow();
  302. }
  303. }
  304. void CXTPPropertyGridItem::OnValidateEdit()
  305. {
  306. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  307. wndEdit.HideWindow();
  308. if (wndEdit.GetSafeHwnd() && wndEdit.m_pItem == this)
  309. {
  310. CString strValue;
  311. wndEdit.GetWindowText(strValue);
  312. wndEdit.m_pItem = NULL;
  313. if (wndEdit.m_bCancel)
  314. {
  315. OnCancelEdit();
  316. }
  317. else if (wndEdit.m_bEditMode && OnAfterEdit(strValue))
  318. {
  319. if (m_strValue != strValue && !wndEdit.m_bCancel)
  320. {
  321. OnValueChanged(strValue);
  322. }
  323. }
  324. }
  325. }
  326. void CXTPPropertyGridItem::SetEditText(const CString& str)
  327. {
  328. if (!m_pGrid) return;
  329. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  330. if (wndEdit.GetSafeHwnd() && wndEdit.m_pItem == this)
  331. {
  332. wndEdit.SetWindowText(str);
  333. }
  334. }
  335. void CXTPPropertyGridItem::SetMultiLinesCount(int nLinesCount)
  336. {
  337. if (m_nLinesCount == nLinesCount)
  338. return;
  339. m_nLinesCount = nLinesCount;
  340. RefreshHeight();
  341. }
  342. void CXTPPropertyGridItem::SetHeight(int nHeight)
  343. {
  344. if (m_nHeight == nHeight)
  345. return;
  346. m_nHeight = nHeight;
  347. RefreshHeight();
  348. }
  349. void CXTPPropertyGridItem::RefreshHeight()
  350. {
  351. if (IsVisible() && m_pGrid->GetSafeHwnd() && m_pGrid->GetStyle() & LBS_OWNERDRAWVARIABLE && m_nIndex >= 0)
  352. {
  353. MEASUREITEMSTRUCT measureItemStruct =
  354. {
  355. ODT_LISTBOX, 0, m_nIndex, 0, 0, (ULONG_PTR)this
  356. };
  357. m_pGrid->MeasureItem(&measureItemStruct);
  358. m_pGrid->SetItemHeight(m_nIndex, measureItemStruct.itemHeight);
  359. m_pGrid->Invalidate(FALSE);
  360. }
  361. }
  362. void CXTPPropertyGridItem::SetValue(CString strValue)
  363. {
  364. m_strValue = strValue;
  365. if (m_pBindString)
  366. {
  367. *m_pBindString = strValue;
  368. }
  369. SetEditText(m_strValue);
  370. for (int i = m_pInplaceControls->GetCount() - 1; i >= 0; i--)
  371. {
  372. CXTPPropertyGridInplaceControl* pControl = m_pInplaceControls->GetAt(i);
  373. pControl->OnValueChanged();
  374. }
  375. SAFE_INVALIDATE(m_pGrid);
  376. }
  377. void CXTPPropertyGridItem::OnValueChanged(CString strValue)
  378. {
  379. if (!m_pGrid)
  380. return;
  381. SetValue(strValue);
  382. SAFE_INVALIDATE(m_pGrid);
  383. m_pGrid->SendNotifyMessage(XTP_PGN_ITEMVALUE_CHANGED, (LPARAM)this);
  384. }
  385. BOOL CXTPPropertyGridItem::OnRequestEdit()
  386. {
  387. XTP_PROPERTYGRID_NOTIFYEDIT notify;
  388. notify.bCancel = FALSE;
  389. notify.pItem = this;
  390. if (m_pGrid)
  391. {
  392. m_pGrid->SendNotifyMessage(XTP_PGN_REQUESTEDIT, (LPARAM)&notify);
  393. }
  394. return !notify.bCancel;
  395. }
  396. BOOL CXTPPropertyGridItem::OnAfterEdit(CString& strValue)
  397. {
  398. if (!m_pGrid)
  399. return FALSE;
  400. XTP_PROPERTYGRID_NOTIFYEDIT notify;
  401. notify.bCancel = FALSE;
  402. notify.strValue = strValue;
  403. notify.pItem = this;
  404. if (m_pGrid)
  405. {
  406. m_pGrid->SendNotifyMessage(XTP_PGN_AFTEREDIT, (LPARAM)&notify);
  407. strValue = notify.strValue;
  408. }
  409. return !notify.bCancel;
  410. }
  411. void CXTPPropertyGridItem::OnCancelEdit()
  412. {
  413. XTP_PROPERTYGRID_NOTIFYEDIT notify;
  414. notify.bCancel = FALSE;
  415. notify.pItem = this;
  416. if (m_pGrid)
  417. {
  418. m_pGrid->SendNotifyMessage(XTP_PGN_CANCELEDIT, (LPARAM)&notify);
  419. }
  420. }
  421. void CXTPPropertyGridItem::OnSelect()
  422. {
  423. ASSERT(m_bVisible);
  424. CString strValue(m_strValue);
  425. if (m_pInplaceControls->GetCount() > 0)
  426. {
  427. CRect rcValue(GetInplaceWindowsRect());
  428. for (int i = m_pInplaceControls->GetCount() - 1; i >= 0; i--)
  429. {
  430. CXTPPropertyGridInplaceControl* pControl = m_pInplaceControls->GetAt(i);
  431. pControl->OnCreateWindow(rcValue);
  432. }
  433. }
  434. if (m_nFlags & xtpGridItemHasEdit)
  435. {
  436. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  437. wndEdit.SetValue(strValue);
  438. wndEdit.Create(this, GetValueRect());
  439. wndEdit.SetReadOnly(GetReadOnly() || m_bConstraintEdit);
  440. }
  441. else
  442. {
  443. GetInplaceEdit().HideWindow();
  444. }
  445. }
  446. DWORD CXTPPropertyGridItem::GetEditStyle() const
  447. {
  448. return WS_CHILD | (m_bPassword ? ES_PASSWORD: 0) | (IsMultiLine() ? ES_MULTILINE : 0) | m_dwEditStyle;
  449. }
  450. void CXTPPropertyGridItem::OnInplaceButtonDown(CXTPPropertyGridInplaceButton* pButton)
  451. {
  452. if (GetReadOnly())
  453. return;
  454. if (m_pGrid->SendNotifyMessage(XTP_PGN_INPLACEBUTTONDOWN, (LPARAM)pButton) == TRUE)
  455. return;
  456. if ((pButton->GetID() == XTP_ID_PROPERTYGRID_COMBOBUTTON) && !m_pConstraints->IsEmpty() && OnRequestEdit())
  457. {
  458. GetInplaceList().Create(this, GetItemRect());
  459. m_pGrid->Invalidate(FALSE);
  460. }
  461. }
  462. CRect CXTPPropertyGridItem::GetInplaceWindowsRect()
  463. {
  464. ASSERT(m_bVisible);
  465. CRect rc = GetItemRect();
  466. CRect rcValue(m_pGrid->GetDividerPos() + 1, rc.top + 1, rc.right, rc.bottom - 1);
  467. if (IsInplaceButtonsVisible())
  468. {
  469. for (int i = 0; i < m_pInplaceButtons->GetCount(); i++)
  470. rcValue.right -= m_pInplaceButtons->GetAt(i)->GetWidth();
  471. }
  472. m_pGrid->GetPaintManager()->AdjustItemValueRect(this, rcValue);
  473. return rcValue;
  474. }
  475. CRect CXTPPropertyGridItem::GetValueRect()
  476. {
  477. CRect rcValue = GetInplaceWindowsRect();
  478. for (int i = m_pInplaceControls->GetCount() - 1; i >= 0; i--)
  479. {
  480. CXTPPropertyGridInplaceControl* pControl = m_pInplaceControls->GetAt(i);
  481. pControl->OnAdjustValueRect(rcValue);
  482. }
  483. return rcValue;
  484. }
  485. CRect CXTPPropertyGridItem::GetItemRect() const
  486. {
  487. CRect rc;
  488. m_pGrid->GetItemRect(m_nIndex, rc);
  489. return rc;
  490. }
  491. BOOL CXTPPropertyGridItem::OnChar(UINT nChar)
  492. {
  493. ASSERT(nChar != VK_TAB);
  494. if ((m_nFlags & xtpGridItemHasEdit) && (nChar != VK_ESCAPE))
  495. {
  496. OnSelect();
  497. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  498. if (wndEdit.GetSafeHwnd() && wndEdit.IsWindowVisible() && wndEdit.GetItem() == this)
  499. {
  500. wndEdit.SetFocus();
  501. wndEdit.SetSel(0, -1);
  502. if ((nChar != VK_TAB) && (wndEdit.GetItem() == this)) wndEdit.SendMessage(WM_CHAR, nChar);
  503. }
  504. return TRUE;
  505. }
  506. else if (nChar == VK_TAB)
  507. {
  508. if (m_pInplaceButtons->GetCount() > 0)
  509. {
  510. m_pGrid->GetPropertyGrid()->OnNavigate(xtpGridUIInplaceEdit, TRUE, this);
  511. }
  512. }
  513. return FALSE;
  514. }
  515. BOOL CXTPPropertyGridItem::IsValueChanged() const
  516. {
  517. return m_strDefaultValue != m_strValue;
  518. }
  519. void CXTPPropertyGridItem::ResetValue()
  520. {
  521. OnValueChanged(m_strDefaultValue);
  522. }
  523. void CXTPPropertyGridItem::SetDefaultValue(LPCTSTR lpszDefaultValue)
  524. {
  525. m_strDefaultValue = lpszDefaultValue;
  526. }
  527. void CXTPPropertyGridItem::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
  528. {
  529. }
  530. BOOL CXTPPropertyGridItem::PtInValueRect(CPoint point)
  531. {
  532. CRect rc(GetValueRect());
  533. return rc.PtInRect(point);
  534. }
  535. void CXTPPropertyGridItem::OnLButtonDblClk(UINT /*nFlags*/, CPoint point)
  536. {
  537. CXTPPropertyGridInplaceButton* pInplaceButton = m_pInplaceButtons->HitTest(point);
  538. if (pInplaceButton && IsInplaceButtonsVisible())
  539. {
  540. OnSelect();
  541. return;
  542. }
  543. if (HasChilds() && IsExpandable())
  544. {
  545. if (m_bExpanded)
  546. Collapse();
  547. else
  548. Expand();
  549. }
  550. else
  551. {
  552. OnSelect();
  553. if (m_nFlags & xtpGridItemHasEdit)
  554. {
  555. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  556. if (wndEdit.GetSafeHwnd() && wndEdit.IsWindowVisible() && wndEdit.GetItem() == this)
  557. {
  558. wndEdit.SetFocus();
  559. if (wndEdit.GetItem() == this && !GetReadOnly() && wndEdit.SelectConstraint(+1, TRUE))
  560. {
  561. OnValidateEdit();
  562. }
  563. else
  564. {
  565. wndEdit.SetSel(0, -1);
  566. }
  567. }
  568. }
  569. else if (!GetReadOnly())
  570. {
  571. SelectNextConstraint();
  572. }
  573. }
  574. }
  575. BOOL CXTPPropertyGridItem::SelectNextConstraint()
  576. {
  577. CXTPPropertyGridItemConstraints* pList = GetConstraints();
  578. if (pList->IsEmpty())
  579. return FALSE;
  580. if (!OnRequestEdit())
  581. return FALSE;
  582. int nIndex = pList->FindConstraint(m_strValue);
  583. nIndex += +1;
  584. if (nIndex >= pList->GetCount()) nIndex = 0;
  585. if (nIndex < 0) nIndex = (ULONG)pList->GetCount() - 1;
  586. CString strValue = pList->GetAt(nIndex);
  587. if (!OnAfterEdit(strValue))
  588. return FALSE;
  589. pList->SetCurrent(nIndex);
  590. OnValueChanged(strValue);
  591. return TRUE;
  592. }
  593. BOOL CXTPPropertyGridItem::OnLButtonDown(UINT nFlags, CPoint point)
  594. {
  595. BOOL bOldSelected = IsSelected();
  596. if (GetGrid()->GetStyle() & LBS_MULTIPLESEL)
  597. {
  598. GetGrid()->Default();
  599. GetGrid()->OnSelectionChanged();
  600. ReleaseCapture();
  601. }
  602. else
  603. Select();
  604. CXTPPropertyGridInplaceButton* pInplaceButton = m_pInplaceButtons->HitTest(point);
  605. if (pInplaceButton && IsInplaceButtonsVisible())
  606. {
  607. if (!bOldSelected && !m_pGrid->GetPropertyGrid()->GetShowInplaceButtonsAlways())
  608. return TRUE;
  609. pInplaceButton->OnLButtonDown(nFlags, point);
  610. return TRUE;
  611. }
  612. int nOffset = (m_nIndent - (IsCategory() ? 0 : 1)) * XTP_PGI_EXPAND_BORDER;
  613. if ((point.x >= nOffset && point.x <= XTP_PGI_EXPAND_BORDER + nOffset) && IsExpandable())
  614. {
  615. if (m_bExpanded)
  616. Collapse();
  617. else
  618. Expand();
  619. }
  620. if ((m_nFlags & xtpGridItemHasEdit) && PtInValueRect(point))
  621. {
  622. mouse_event(GetSystemMetrics(SM_SWAPBUTTON) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
  623. }
  624. if (m_nFlags == xtpGridItemHasComboButton && PtInValueRect(point) && !GetReadOnly()
  625. && (m_pInplaceButtons->GetCount() == 1) && !IsCategory())
  626. {
  627. OnInplaceButtonDown(m_pInplaceButtons->GetAt(0));
  628. }
  629. return TRUE;
  630. }
  631. void CXTPPropertyGridItem::BindToString(CString* pBindString)
  632. {
  633. m_pBindString = pBindString;
  634. if (m_pBindString)
  635. {
  636. *m_pBindString = m_strValue;
  637. }
  638. }
  639. void CXTPPropertyGridItem::OnBeforeInsert()
  640. {
  641. if (m_pBindString && *m_pBindString != m_strValue)
  642. {
  643. m_strValue = *m_pBindString;
  644. }
  645. }
  646. void CXTPPropertyGridItem::EnsureVisible()
  647. {
  648. if (!m_bVisible)
  649. {
  650. CXTPPropertyGridItem* pItem = GetParentItem();
  651. while (pItem)
  652. {
  653. pItem->Expand();
  654. pItem = pItem->GetParentItem();
  655. }
  656. }
  657. if (!m_bVisible || (m_nIndex == -1))
  658. return;
  659. if (m_nIndex < m_pGrid->GetTopIndex())
  660. {
  661. m_pGrid->SetTopIndex(m_nIndex);
  662. return;
  663. }
  664. int top = 0;
  665. int nTopIndex = m_pGrid->GetTopIndex();
  666. int bottom = CXTPClientRect(m_pGrid).bottom;
  667. for (int i = nTopIndex; i < m_pGrid->GetCount(); i++)
  668. {
  669. int nRowHeight = m_pGrid->GetItemHeight(i);
  670. if (top + nRowHeight > bottom)
  671. break;
  672. if (i == m_nIndex)
  673. return;
  674. top += nRowHeight;
  675. }
  676. int nHeight = bottom;
  677. for (top = m_nIndex; top >= 0; top--)
  678. {
  679. int nRowHeight = m_pGrid->GetItemHeight(top);
  680. if (nHeight - nRowHeight < 0)
  681. {
  682. if (top != m_nIndex)
  683. top++;
  684. break;
  685. }
  686. nHeight -= nRowHeight;
  687. }
  688. m_pGrid->SetTopIndex(top);
  689. }
  690. CXTPPropertyGridInplaceEdit& CXTPPropertyGridItem::GetInplaceEdit()
  691. {
  692. if (m_pGrid) return *m_pGrid->m_pGrid->m_pInplaceEdit;
  693. static CXTPPropertyGridInplaceEdit  wndEdit;
  694. return wndEdit;
  695. }
  696. CXTPPropertyGridInplaceList& CXTPPropertyGridItem::GetInplaceList()
  697. {
  698. if (m_pGrid) return *m_pGrid->m_pGrid->m_pInplaceListBox;
  699. static CXTPPropertyGridInplaceList  wndListBox;
  700. return wndListBox;
  701. }
  702. BOOL CXTPPropertyGridItem::IsInplaceButtonsVisible() const
  703. {
  704. if (!m_pGrid)
  705. return FALSE;
  706. if (!IsSelected() && !m_pGrid->GetPropertyGrid()->GetShowInplaceButtonsAlways())
  707. return FALSE;
  708. return !GetReadOnly() && m_pInplaceButtons->GetCount() > 0;
  709. }
  710. CXTPPropertyGridInplaceButtons* CXTPPropertyGridItem::GetInplaceButtons() const
  711. {
  712. return m_pInplaceButtons;
  713. }
  714. CXTPPropertyGridInplaceControls* CXTPPropertyGridItem::GetInplaceControls() const
  715. {
  716. return m_pInplaceControls;
  717. }
  718. // Deletes the item.
  719. void CXTPPropertyGridItem::Remove()
  720. {
  721. if (!m_pGrid)
  722. return;
  723. CXTPPropertyGridItems* pItems = GetParentItem() == 0 ? m_pGrid->m_pCategories : GetParentItem()->m_pChilds;
  724. ASSERT(pItems);
  725. int nIndex = pItems ? pItems->Find(this) : -1;
  726. if (nIndex == -1)
  727. return;
  728. pItems->m_arrItems.RemoveAt(nIndex);
  729. m_pParent = NULL;
  730. if (m_pGrid) m_pGrid->Refresh();
  731. InternalRelease();
  732. }
  733. BOOL CXTPPropertyGridItem::IsHidden() const
  734. {
  735. return m_bHidden;
  736. }
  737. void CXTPPropertyGridItem::SetHidden(BOOL bHidden)
  738. {
  739. if (bHidden == m_bHidden)
  740. return;
  741. m_bHidden = bHidden;
  742. m_pGrid->Refresh();
  743. }
  744. BOOL CXTPPropertyGridItem::HasVisibleChilds() const
  745. {
  746. for (int i = 0; i < m_pChilds->GetCount(); i++)
  747. {
  748. if (!m_pChilds->GetAt(i)->IsHidden())
  749. return TRUE;
  750. }
  751. return FALSE;
  752. }
  753. BOOL CXTPPropertyGridItem::IsSelected() const
  754. {
  755. if (!m_pGrid->GetSafeHwnd())
  756. return FALSE;
  757. if (!m_bVisible)
  758. return FALSE;
  759. int nCount = m_pGrid->GetSelCount();
  760. if (nCount != LB_ERR && nCount > 1)
  761. {
  762. CArray<int,int> arr;
  763. arr.SetSize(nCount);
  764. m_pGrid->GetSelItems(nCount, arr.GetData());
  765. for (int i = 0; i < nCount; i++)
  766. {
  767. if (arr[i] == m_nIndex)
  768. return TRUE;
  769. }
  770. }
  771. return m_pGrid && m_pGrid->GetSelectedItem() == this;
  772. }
  773. void CXTPPropertyGridItem::Refresh(BOOL bInvalidate /*= TRUE*/)
  774. {
  775. if (m_pGrid && m_pGrid->GetSafeHwnd())
  776. {
  777. if (IsSelected())
  778. {
  779. OnDeselect();
  780. OnSelect();
  781. }
  782. if (bInvalidate)
  783. {
  784. m_pGrid->Invalidate(FALSE);
  785. }
  786. }
  787. }
  788. void CXTPPropertyGridItem::SetReadOnly(BOOL bReadOnly)
  789. {
  790. if (m_bReadOnly != bReadOnly)
  791. {
  792. m_bReadOnly = bReadOnly;
  793. Refresh(TRUE);
  794. }
  795. }
  796. void CXTPPropertyGridItem::SetMask(LPCTSTR strMask, LPCTSTR strLiteral, TCHAR chPrompt /*= _T('_')*/)
  797. {
  798. m_bUseMask = TRUE;
  799. m_strMask = strMask;
  800. m_strLiteral = strLiteral;
  801. m_chPrompt = chPrompt;
  802. Refresh(FALSE);
  803. }
  804. CString CXTPPropertyGridItem::GetViewValue()
  805. {
  806. CString str = GetValue();
  807. if (m_bPassword)
  808. {
  809. return CString(m_chPrompt, str.GetLength());
  810. }
  811. return str;
  812. }
  813. CString CXTPPropertyGridItem::GetMaskedText() const
  814. {
  815. if (m_bUseMask)
  816. {
  817. int nLength = m_strValue.GetLength();
  818. CString strBuffer;
  819. for (int i = 0; i < nLength; ++i)
  820. {
  821. if (m_strLiteral[i] == m_chPrompt)
  822. {
  823. strBuffer += m_strValue.GetAt(i);
  824. }
  825. }
  826. return strBuffer;
  827. }
  828. else
  829. {
  830. return m_strValue;
  831. }
  832. }
  833. void CXTPPropertyGridItem::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  834. {
  835. if (m_nHeight != -1)
  836. {
  837. lpMeasureItemStruct->itemHeight = m_nHeight;
  838. }
  839. else if (m_nLinesCount > 1)
  840. {
  841. lpMeasureItemStruct->itemHeight = (lpMeasureItemStruct->itemHeight - 4) * m_nLinesCount + 4;
  842. }
  843. }
  844. void CXTPPropertyGridItem::SetMaskedText(LPCTSTR lpszMaskedText)
  845. {
  846. CString strMaskedText = lpszMaskedText;
  847. if (m_bUseMask)
  848. {
  849. int nLen = strMaskedText.GetLength();
  850. int x = 0;
  851. m_strValue = m_strLiteral;
  852. for (int i = 0; (i < m_strValue.GetLength()) && (x < nLen); i++)
  853. {
  854. if (strMaskedText[x] == m_strValue[i])
  855. {
  856. x++;
  857. }
  858. else if (m_strValue[i] == m_chPrompt)
  859. {
  860. m_strValue.SetAt(i, strMaskedText[x]);
  861. x++;
  862. }
  863. }
  864. }
  865. else
  866. {
  867. m_strValue = strMaskedText;
  868. }
  869. SetValue(m_strValue);
  870. }
  871. void CXTPPropertyGridItem::SetDescription(LPCTSTR lpszDescription)
  872. {
  873. m_strDescription = lpszDescription;
  874. if (IsSelected()) GetGrid()->GetParent()->Invalidate(FALSE);
  875. }
  876. int CXTPPropertyGridItem::GetIndex() const
  877. {
  878. return m_nIndex;
  879. }
  880. void CXTPPropertyGridItem::OnDrawItemConstraint(CDC* pDC, CXTPPropertyGridItemConstraint* pConstraint, CRect rc, BOOL bSelected)
  881. {
  882. GetGrid()->GetPaintManager()->DrawInplaceListItem(pDC, pConstraint, rc, bSelected);
  883. }
  884. CSize CXTPPropertyGridItem::OnMergeItemConstraint(CDC* pDC, CXTPPropertyGridItemConstraint* pConstraint)
  885. {
  886. int nThumbLength = GetSystemMetrics(SM_CXHTHUMB);
  887. CSize sz = pDC->GetTextExtent(pConstraint->m_strConstraint);
  888. return CSize(sz.cx + nThumbLength * 2, sz.cy + 3);
  889. }
  890. void CXTPPropertyGridItem::SetFocusToInplaceControl()
  891. {
  892. CXTPPropertyGridInplaceEdit& wndEdit = GetInplaceEdit();
  893. if (wndEdit.GetSafeHwnd() && wndEdit.GetItem() == this)
  894. {
  895. wndEdit.SetFocus();
  896. wndEdit.SetSel(0, -1);
  897. }
  898. }
  899. void CXTPPropertyGridItem::AddComboButton()
  900. {
  901. GetInplaceButtons()->AddComboButton();
  902. }
  903. void CXTPPropertyGridItem::AddExpandButton()
  904. {
  905. GetInplaceButtons()->AddExpandButton();
  906. }
  907. CXTPPropertyGridInplaceSlider* CXTPPropertyGridItem::AddSliderControl()
  908. {
  909. CXTPPropertyGridInplaceSlider* pSlider = new CXTPPropertyGridInplaceSlider(this);
  910. m_pInplaceControls->Add(pSlider);
  911. return pSlider;
  912. }
  913. CXTPPropertyGridInplaceSpinButton* CXTPPropertyGridItem::AddSpinButton()
  914. {
  915. CXTPPropertyGridInplaceSpinButton* pSpinButton = new CXTPPropertyGridInplaceSpinButton(this);
  916. m_pInplaceControls->Add(pSpinButton);
  917. return pSpinButton;
  918. }
  919. void CXTPPropertyGridItem::OnCaptionChanged()
  920. {
  921. XTPMarkupReleaseElement(m_pMarkupUIElement);
  922. if (!m_pGrid || !m_pGrid->m_pGrid)
  923. return;
  924. if (m_pGrid->m_pGrid->GetMarkupContext())
  925. {
  926. m_pMarkupUIElement = XTPMarkupParseText(m_pGrid->m_pGrid->GetMarkupContext(), GetCaption());
  927. }
  928. if (m_bVisible && m_pGrid->GetSafeHwnd())
  929. m_pGrid->InvalidateRect(GetItemRect(), FALSE);
  930. }
  931. //////////////////////////////////////////////////////////////////////////
  932. // Accessible
  933. CCmdTarget* CXTPPropertyGridItem::GetAccessible()
  934. {
  935. return this;
  936. }
  937. HRESULT CXTPPropertyGridItem::GetAccessibleParent(IDispatch* FAR* ppdispParent)
  938. {
  939. SAFE_MANAGE_STATE(m_pModuleState);
  940. *ppdispParent = NULL;
  941. return m_pGrid->InternalQueryInterface(&IID_IAccessible, (void**)ppdispParent);
  942. }
  943. HRESULT CXTPPropertyGridItem::GetAccessibleName(VARIANT varChild, BSTR* pszName)
  944. {
  945. if (GetChildIndex(&varChild) != CHILDID_SELF)
  946. return E_INVALIDARG;
  947. CString strCaption = GetCaption();
  948. *pszName = strCaption.AllocSysString();
  949. return S_OK;
  950. }
  951. HRESULT CXTPPropertyGridItem::GetAccessibleDescription(VARIANT varChild, BSTR* pszDescription)
  952. {
  953. if (GetChildIndex(&varChild) != CHILDID_SELF)
  954. return E_INVALIDARG;
  955. *pszDescription = GetDescription().AllocSysString();
  956. return S_OK;
  957. }
  958. HRESULT CXTPPropertyGridItem::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole)
  959. {
  960. if (!pvarRole)
  961. return E_INVALIDARG;
  962. pvarRole->vt = VT_EMPTY;
  963. if (GetChildIndex(&varChild) == CHILDID_SELF)
  964. {
  965. pvarRole->vt = VT_I4;
  966. pvarRole->lVal = ROLE_SYSTEM_ROW;
  967. return S_OK;
  968. }
  969. return E_INVALIDARG;
  970. }
  971. HRESULT CXTPPropertyGridItem::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
  972. {
  973. if (!pvarState)
  974. return E_INVALIDARG;
  975. if (GetChildIndex(&varChild) != CHILDID_SELF)
  976. return E_INVALIDARG;
  977. pvarState->vt = VT_I4;
  978. pvarState->lVal = STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_SELECTABLE |
  979. (IsSelected() ? STATE_SYSTEM_FOCUSED : 0);
  980. if (!IsVisible())
  981. pvarState->lVal |= STATE_SYSTEM_INVISIBLE;
  982. if (GetReadOnly())
  983. pvarState->lVal |= STATE_SYSTEM_READONLY;
  984. return S_OK;
  985. }
  986. HRESULT CXTPPropertyGridItem::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
  987. {
  988. *pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
  989. if (GetChildIndex(&varChild) != CHILDID_SELF)
  990. return E_INVALIDARG;
  991. if (!m_pGrid->GetSafeHwnd())
  992. return S_OK;
  993. CRect rcItem;
  994. m_pGrid->GetItemRect(GetIndex(), &rcItem);
  995. m_pGrid->ClientToScreen(&rcItem);
  996. *pxLeft = rcItem.left;
  997. *pyTop = rcItem.top;
  998. *pcxWidth = rcItem.Width();
  999. *pcyHeight = rcItem.Height();
  1000. return S_OK;
  1001. }
  1002. HRESULT CXTPPropertyGridItem::AccessibleHitTest(long xLeft, long yTop, VARIANT* pvarID)
  1003. {
  1004. if (pvarID == NULL)
  1005. return E_INVALIDARG;
  1006. pvarID->vt = VT_EMPTY;
  1007. if (!m_pGrid->GetSafeHwnd())
  1008. return S_FALSE;
  1009. if (!CXTPWindowRect(m_pGrid).PtInRect(CPoint(xLeft, yTop)))
  1010. return S_FALSE;
  1011. pvarID->vt = VT_I4;
  1012. pvarID->lVal = 0;
  1013. CRect rcItem;
  1014. m_pGrid->GetItemRect(GetIndex(), &rcItem);
  1015. m_pGrid->ClientToScreen(&rcItem);
  1016. if (!rcItem.PtInRect(CPoint(xLeft, yTop)))
  1017. return S_FALSE;
  1018. return S_OK;
  1019. }
  1020. HRESULT CXTPPropertyGridItem::AccessibleSelect(long /*flagsSelect*/, VARIANT varChild)
  1021. {
  1022. if (GetChildIndex(&varChild) != CHILDID_SELF)
  1023. return E_INVALIDARG;
  1024. Select();
  1025. return S_OK;
  1026. }
  1027. HRESULT CXTPPropertyGridItem::GetAccessibleValue(VARIANT varChild, BSTR* pszValue)
  1028. {
  1029. if (GetChildIndex(&varChild) != CHILDID_SELF)
  1030. return E_INVALIDARG;
  1031. *pszValue = GetValue().AllocSysString();
  1032. return S_OK;
  1033. }
  1034. /////////////////////////////////////////////////////////////////////////////
  1035. // CXTPPropertyGridItems
  1036. CXTPPropertyGridItems::CXTPPropertyGridItems()
  1037. {
  1038. }
  1039. void CXTPPropertyGridItems::Clear()
  1040. {
  1041. CXTPPropertyGridView* pGrid = GetCount() > 0 ? m_arrItems[0]->m_pGrid : 0;
  1042. if (pGrid)
  1043. {
  1044. if (pGrid->m_nLockUpdate == 0)
  1045. pGrid->ResetContent();
  1046. pGrid->m_nLockUpdate++;
  1047. }
  1048. for (int i = 0; i < GetCount(); i++)
  1049. {
  1050. m_arrItems[i]->Clear();
  1051. m_arrItems[i]->InternalRelease();
  1052. }
  1053. m_arrItems.RemoveAll();
  1054. if (pGrid)
  1055. {
  1056. pGrid->m_nLockUpdate--;
  1057. if (pGrid->m_nLockUpdate == 0)
  1058. pGrid->Refresh();
  1059. }
  1060. }
  1061. CXTPPropertyGridItem* CXTPPropertyGridItems::GetAt(int nIndex) const
  1062. {
  1063. if (nIndex >= 0 && nIndex < GetCount())
  1064. {
  1065. return m_arrItems.GetAt(nIndex);
  1066. }
  1067. return 0;
  1068. }
  1069. void CXTPPropertyGridItems::RemoveAt (int nIndex)
  1070. {
  1071. CXTPPropertyGridItem* pItem = GetAt(nIndex);
  1072. if (pItem)
  1073. {
  1074. m_arrItems.RemoveAt(nIndex);
  1075. if (pItem->GetGrid())
  1076. {
  1077. pItem->GetGrid()->Refresh();
  1078. }
  1079. pItem->InternalRelease();
  1080. }
  1081. }
  1082. int CXTPPropertyGridItems::Find(CXTPPropertyGridItem* pItem) const
  1083. {
  1084. for (int i = 0; i < GetCount(); i++)
  1085. {
  1086. if (m_arrItems[i] == pItem)
  1087. return i;
  1088. }
  1089. return -1;
  1090. }
  1091. void CXTPPropertyGridItems::AddTail(CXTPPropertyGridItems* pItems)
  1092. {
  1093. ASSERT(this != pItems);
  1094. for (int i = 0; i < pItems->GetCount(); i++)
  1095. {
  1096. AddTail(pItems->GetAt(i));
  1097. }
  1098. }
  1099. int CXTPPropertyGridItems::CompareFunc(const CXTPPropertyGridItem** ppItem1, const CXTPPropertyGridItem** ppItem2)
  1100. {
  1101. return (*ppItem1)->GetCaption().Compare((*ppItem2)->GetCaption());
  1102. }
  1103. void CXTPPropertyGridItems::Sort()
  1104. {
  1105. typedef int (_cdecl *GENERICCOMPAREFUNC)(const void *, const void*);
  1106. qsort(m_arrItems.GetData(), m_arrItems.GetSize(), sizeof(CXTPPropertyGridItem*), (GENERICCOMPAREFUNC)CompareFunc);
  1107. }
  1108. CXTPPropertyGridItem* CXTPPropertyGridItems::FindItem(LPCTSTR strCaption) const
  1109. {
  1110. for (int i = 0; i < GetCount(); i++)
  1111. {
  1112. CXTPPropertyGridItem* pItem = GetAt(i);
  1113. if (pItem->GetCaption().Compare(strCaption) == 0)
  1114. return pItem;
  1115. CXTPPropertyGridItem* pChild = pItem->m_pChilds->FindItem(strCaption);
  1116. if (pChild) return pChild;
  1117. }
  1118. return NULL;
  1119. }
  1120. CXTPPropertyGridItem* CXTPPropertyGridItems::FindItem(UINT nID) const
  1121. {
  1122. for (int i = 0; i < GetCount(); i++)
  1123. {
  1124. CXTPPropertyGridItem* pItem = GetAt(i);
  1125. if (pItem->GetID() == nID)
  1126. return pItem;
  1127. CXTPPropertyGridItem* pChild = pItem->m_pChilds->FindItem(nID);
  1128. if (pChild) return pChild;
  1129. }
  1130. return NULL;
  1131. }
  1132. //////////////////////////////////////////////////////////////////////////
  1133. // CXTPPropertyGridItemConstraint
  1134. CXTPPropertyGridItemConstraint::CXTPPropertyGridItemConstraint()
  1135. {
  1136. m_nIndex = 0;
  1137. m_dwData = 0;
  1138. m_nImage = -1;
  1139. m_pItem = 0;
  1140. }
  1141. CXTPImageManagerIcon* CXTPPropertyGridItemConstraint::GetImage() const
  1142. {
  1143. ASSERT(m_pItem);
  1144. if (!m_pItem)
  1145. return NULL;
  1146. if (m_nImage == -1)
  1147. return NULL;
  1148. return m_pItem->GetGrid()->GetImageManager()->GetImage(m_nImage, 0);
  1149. }
  1150. /////////////////////////////////////////////////////////////////////////////
  1151. // CXTPPropertyGridItemConstraints
  1152. // Summary: Constructs a CXTPPropertyGridItemConstraints object
  1153. CXTPPropertyGridItemConstraints::CXTPPropertyGridItemConstraints(CXTPPropertyGridItem* pItem)
  1154. {
  1155. m_pItem = pItem;
  1156. m_nCurrent = -1;
  1157. }
  1158. CXTPPropertyGridItemConstraints::~CXTPPropertyGridItemConstraints()
  1159. {
  1160. RemoveAll();
  1161. }
  1162. CXTPPropertyGridItemConstraint* CXTPPropertyGridItemConstraints::AddConstraint(LPCTSTR str, DWORD_PTR dwData, int nImage)
  1163. {
  1164. CXTPPropertyGridItemConstraint* pConstaint = new CXTPPropertyGridItemConstraint();
  1165. pConstaint->m_strConstraint = str;
  1166. pConstaint->m_dwData = dwData;
  1167. pConstaint->m_nIndex = (int)m_arrConstraints.Add(pConstaint);
  1168. pConstaint->m_pItem = m_pItem;
  1169. pConstaint->m_nImage = nImage;
  1170. SAFE_CALLPTR(m_pItem, OnConstraintsChanged());
  1171. return pConstaint;
  1172. }
  1173. CString CXTPPropertyGridItemConstraints::GetAt(int nIndex) const
  1174. {
  1175. return nIndex >= 0 && nIndex < GetCount() ? m_arrConstraints.GetAt(nIndex)->m_strConstraint : _T("");
  1176. }
  1177. void CXTPPropertyGridItemConstraints::RemoveAll()
  1178. {
  1179. for (int i = 0; i < GetCount(); i++)
  1180. m_arrConstraints[i]->InternalRelease();
  1181. m_arrConstraints.RemoveAll();
  1182. SAFE_CALLPTR(m_pItem, OnConstraintsChanged());
  1183. }
  1184. void CXTPPropertyGridItemConstraints::RemoveAt(int nIndex)
  1185. {
  1186. m_arrConstraints[nIndex]->InternalRelease();
  1187. m_arrConstraints.RemoveAt(nIndex);
  1188. for (int i = nIndex; i < GetCount(); i++)
  1189. m_arrConstraints[i]->m_nIndex = i;
  1190. SAFE_CALLPTR(m_pItem, OnConstraintsChanged());
  1191. }
  1192. int CXTPPropertyGridItemConstraints::FindConstraint(LPCTSTR str) const
  1193. {
  1194. for (int i = 0; i < GetCount(); i++)
  1195. {
  1196. if (GetAt(i).CompareNoCase(str) == 0)
  1197. return i;
  1198. }
  1199. return -1;
  1200. }
  1201. int CXTPPropertyGridItemConstraints::FindConstraint(DWORD_PTR dwData) const
  1202. {
  1203. for (int i = 0; i < GetCount(); i++)
  1204. {
  1205. if (dwData == GetConstraintAt(i)->m_dwData)
  1206. return i;
  1207. }
  1208. return -1;
  1209. }
  1210. CXTPPropertyGridItemConstraint* CXTPPropertyGridItemConstraints::GetConstraintAt(int nIndex) const
  1211. {
  1212. return m_arrConstraints[nIndex];
  1213. }
  1214. int CXTPPropertyGridItemConstraints::CompareFunc(const CXTPPropertyGridItemConstraint** ppConstraint1, const CXTPPropertyGridItemConstraint** ppConstraint2)
  1215. {
  1216. return (*ppConstraint1)->m_strConstraint.Compare((*ppConstraint2)->m_strConstraint);
  1217. }
  1218. void CXTPPropertyGridItemConstraints::Sort()
  1219. {
  1220. typedef int (_cdecl *GENERICCOMPAREFUNC)(const void *, const void*);
  1221. qsort(m_arrConstraints.GetData(), (size_t)m_arrConstraints.GetSize(), sizeof(CXTPPropertyGridItemConstraint*), (GENERICCOMPAREFUNC)CompareFunc);
  1222. }
  1223. //////////////////////////////////////////////////////////////////////////
  1224. // CXTPPropertyGridItemCategory
  1225. CXTPPropertyGridItemCategory::CXTPPropertyGridItemCategory(LPCTSTR strCaption)
  1226. :CXTPPropertyGridItem(strCaption)
  1227. {
  1228. m_bCategory = TRUE;
  1229. m_nFlags = 0;
  1230. }
  1231. CXTPPropertyGridItemCategory::CXTPPropertyGridItemCategory(UINT nID)
  1232. :CXTPPropertyGridItem(nID)
  1233. {
  1234. m_bCategory = TRUE;
  1235. m_nFlags = 0;
  1236. }
  1237. ///////////////////////////////////////////////////////////////////////////////////
  1238. //  Acteve X Methods
  1239. //
  1240. BEGIN_INTERFACE_MAP(CXTPPropertyGridItem, CCmdTarget)
  1241. INTERFACE_PART(CXTPPropertyGridItem, IID_IAccessible, ExternalAccessible)
  1242. END_INTERFACE_MAP()