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

对话框与窗口

开发平台:

Visual C++

  1. // XTPPropertyGrid.cpp : implementation of the CXTPPropertyGrid 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 "Resource.h"
  22. #include "Common/Resource.h"
  23. #include "Common/XTPResourceManager.h"
  24. #include "Common/XTPVC80Helpers.h"
  25. #include "Common/XTPDrawHelpers.h"
  26. #include "Common/XTPImageManager.h"
  27. #include "Common/XTPToolTipContext.h"
  28. #include "Common/XTPMarkupRender.h"
  29. #include "XTPPropertyGridInplaceEdit.h"
  30. #include "XTPPropertyGridInplaceButton.h"
  31. #include "XTPPropertyGridInplaceList.h"
  32. #include "XTPPropertyGridItem.h"
  33. #include "XTPPropertyGrid.h"
  34. #include "XTPPropertyGridDefines.h"
  35. #ifdef _DEBUG
  36. #define new DEBUG_NEW
  37. #undef THIS_FILE
  38. static char THIS_FILE[] = __FILE__;
  39. #endif
  40. const int SPLITTER_HEIGHT = 3;
  41. const int TOOLBAR_HEIGHT = 25;
  42. //////////////////////////////////////////////////////////////////////////
  43. // CXTPPropertyGridUpdateContext
  44. CXTPPropertyGridUpdateContext::CXTPPropertyGridUpdateContext()
  45. {
  46. m_nSelected = 0;
  47. m_nTopIndex = 0;
  48. m_propertySort = xtpGridSortAlphabetical;
  49. }
  50. //////////////////////////////////////////////////////////////////////////
  51. // CXTPPropertyGridVerb
  52. CXTPPropertyGridVerb::CXTPPropertyGridVerb()
  53. {
  54. m_nID = 0;
  55. m_nIndex = -1;
  56. m_pVerbs = 0;
  57. }
  58. //////////////////////////////////////////////////////////////////////////
  59. // CXTPPropertyGridVerbs
  60. CXTPPropertyGridVerbs::CXTPPropertyGridVerbs()
  61. {
  62. m_pGrid = 0;
  63. }
  64. CXTPPropertyGridVerbs::~CXTPPropertyGridVerbs()
  65. {
  66. for (int i = 0; i < m_arrVerbs.GetSize(); i++)
  67. m_arrVerbs[i]->InternalRelease();
  68. }
  69. void CXTPPropertyGridVerbs::RemoveAll()
  70. {
  71. if (IsEmpty())
  72. return;
  73. for (int i = 0; i < m_arrVerbs.GetSize(); i++)
  74. m_arrVerbs[i]->InternalRelease();
  75. m_arrVerbs.RemoveAll();
  76. m_pGrid->OnVerbsChanged();
  77. }
  78. int CXTPPropertyGridVerbs::GetCount() const
  79. {
  80. return (int)m_arrVerbs.GetSize();
  81. }
  82. void CXTPPropertyGridVerbs::Add(LPCTSTR strCaption, UINT nID)
  83. {
  84. CXTPPropertyGridVerb* pVerb = new CXTPPropertyGridVerb();
  85. pVerb->m_nID = nID;
  86. pVerb->m_strCaption = strCaption;
  87. pVerb->m_pVerbs = this;
  88. pVerb->m_rcPart.SetRectEmpty();
  89. pVerb->m_ptClick = CPoint(0);
  90. pVerb->m_nIndex = (UINT)m_arrVerbs.Add(pVerb);
  91. m_pGrid->OnVerbsChanged();
  92. }
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CXTPPropertyGridToolBar
  95. CXTPPropertyGridToolBar::CXTPPropertyGridToolBar()
  96. {
  97. m_cxLeftBorder = m_cxRightBorder = m_cyBottomBorder = m_cyTopBorder = 0;
  98. }
  99. CXTPPropertyGridToolBar::~CXTPPropertyGridToolBar()
  100. {
  101. }
  102. BEGIN_MESSAGE_MAP(CXTPPropertyGridToolBar, CToolBar)
  103. //{{AFX_MSG_MAP(CToolBar)
  104. ON_WM_PAINT()
  105. ON_WM_ERASEBKGND()
  106. ON_WM_NCCALCSIZE()
  107. ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
  108. //}}AFX_MSG_MAP
  109. END_MESSAGE_MAP()
  110. void CXTPPropertyGridToolBar::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
  111. {
  112. NMLVCUSTOMDRAW* lpLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
  113. *pResult = CDRF_DODEFAULT;
  114. switch (lpLVCD->nmcd.dwDrawStage)
  115. {
  116. case CDDS_PREPAINT:
  117. CWnd* pGrid = GetParent();
  118. HBRUSH hBrush = (HBRUSH)pGrid->GetParent()->SendMessage(WM_CTLCOLORSTATIC,
  119. (WPARAM)lpLVCD->nmcd.hdc, (LPARAM)pGrid->m_hWnd);
  120. ::FillRect(lpLVCD->nmcd.hdc, &lpLVCD->nmcd.rc, hBrush ? hBrush : GetSysColorBrush(COLOR_3DFACE));
  121. break;
  122. }
  123. }
  124. BOOL CXTPPropertyGridToolBar::OnEraseBkgnd(CDC*)
  125. {
  126. return TRUE;
  127. }
  128. void CXTPPropertyGridToolBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* /*lpncsp*/)
  129. {
  130. }
  131. void CXTPPropertyGridToolBar::OnPaint()
  132. {
  133. CPaintDC dc(this);
  134. CXTPClientRect rc(this);
  135. CXTPBufferDC memDC(dc, rc);
  136. memDC.FillSolidRect(rc, GetXtremeColor(COLOR_3DFACE));
  137. CToolBar::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0);
  138. }
  139. void CXTPPropertyGridToolBar::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/)
  140. {
  141. }
  142. BOOL CXTPPropertyGridToolBar::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  143. {
  144. CXTPPropertyGrid* pGrid = (CXTPPropertyGrid*)GetParent();
  145. if (pGrid->GetToolTipContext())
  146. {
  147. pGrid->GetToolTipContext()->FilterToolTipMessage(this, message, wParam, lParam);
  148. }
  149. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  150. }
  151. /////////////////////////////////////////////////////////////////////////////
  152. // CXTPPropertyGrid
  153. CXTPPropertyGrid::CXTPPropertyGrid()
  154. : m_bHelpVisible(TRUE)
  155. , m_bToolBarVisible(FALSE)
  156. , m_nHelpHeight(58)
  157. , m_bPreSubclassWindow(TRUE)
  158. {
  159. RegisterWindowClass();
  160. m_pView = 0;
  161. m_hCursorSplit = XTPResourceManager()->LoadCursor(XTP_IDC_VSPLITBAR);
  162. m_hCursorHand = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649));
  163. if (m_hCursorHand == 0)
  164. m_hCursorHand = XTPResourceManager()->LoadCursor(XTP_IDC_HAND);
  165. m_pPaintManager = new CXTPPropertyGridPaintManager(this);
  166. m_pPaintManager->RefreshMetrics();
  167. m_themeCurrent = xtpGridThemeDefault;
  168. m_pVerbs = new CXTPPropertyGridVerbs;
  169. m_pVerbs->m_pGrid = this;
  170. m_nVerbsHeight = 25;
  171. m_nFocusedVerb = -1;
  172. m_bVerbActivate = FALSE;
  173. m_bVerbsVisible = FALSE;
  174. m_bEnableTooltips = TRUE;
  175. m_bTabItems = FALSE;
  176. m_bTabCaptions = TRUE;
  177. m_bVariableItemsHeight = FALSE;
  178. m_borderStyle = xtpGridBorderStaticEdge;
  179. m_bShowInplaceButtonsAlways = FALSE;
  180. LOGFONT lfIcon;
  181. VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0));
  182. lfIcon.lfWeight = FW_NORMAL;
  183. lfIcon.lfItalic = FALSE;
  184. VERIFY(m_pPaintManager->GetItemMetrics()->m_fontNormal.CreateFontIndirect(&lfIcon));
  185. lfIcon.lfWeight = FW_BOLD;
  186. VERIFY(m_pPaintManager->GetItemMetrics()->m_fontBold.CreateFontIndirect(&lfIcon));
  187. m_bHighlightChanged = FALSE;
  188. m_pImageManager = new CXTPImageManager;
  189. m_pInplaceEdit = new CXTPPropertyGridInplaceEdit;
  190. m_pInplaceListBox = new CXTPPropertyGridInplaceList;
  191. m_bVariableHelpHeight = TRUE;
  192. m_pToolTipContext = new CXTPToolTipContext;
  193. m_bHideSelection = FALSE;
  194. m_bMultiSelect = FALSE;
  195. m_pMarkupContext = NULL;
  196. }
  197. BOOL CXTPPropertyGrid::RegisterWindowClass(HINSTANCE hInstance /*= NULL*/)
  198. {
  199. return XTPDrawHelpers()->RegisterWndClass(hInstance, XTPPROPERTYGRID_CLASSNAME, 0);
  200. }
  201. CXTPPropertyGrid::~CXTPPropertyGrid()
  202. {
  203. if (m_pView)
  204. {
  205. delete m_pView;
  206. }
  207. CMDTARGET_RELEASE(m_pVerbs);
  208. CMDTARGET_RELEASE(m_pImageManager);
  209. SAFE_DELETE(m_pInplaceEdit);
  210. SAFE_DELETE(m_pInplaceListBox);
  211. CMDTARGET_RELEASE(m_pPaintManager);
  212. CMDTARGET_RELEASE(m_pToolTipContext);
  213. XTPMarkupReleaseContext(m_pMarkupContext);
  214. }
  215. void CXTPPropertyGrid::SetInplaceEdit(CXTPPropertyGridInplaceEdit*  pInplaceEdit)
  216. {
  217. ASSERT(pInplaceEdit);
  218. SAFE_DELETE(m_pInplaceEdit);
  219. m_pInplaceEdit = pInplaceEdit;
  220. }
  221. void CXTPPropertyGrid::SetInplaceList(CXTPPropertyGridInplaceList*  pInplaceList)
  222. {
  223. ASSERT(pInplaceList);
  224. SAFE_DELETE(m_pInplaceListBox);
  225. m_pInplaceListBox = pInplaceList;
  226. }
  227. CXTPPropertyGridView* CXTPPropertyGrid::CreateView() const
  228. {
  229. return new CXTPPropertyGridView();
  230. }
  231. CXTPPropertyGridView& CXTPPropertyGrid::GetGridView() const
  232. {
  233. if (m_pView == 0)
  234. {
  235. m_pView = CreateView();
  236. m_pView->m_pGrid = (CXTPPropertyGrid*)this;
  237. }
  238. return *m_pView;
  239. }
  240. IMPLEMENT_DYNAMIC(CXTPPropertyGrid, CWnd)
  241. BEGIN_MESSAGE_MAP(CXTPPropertyGrid, CWnd)
  242. //{{AFX_MSG_MAP(CXTPPropertyGrid)
  243. ON_WM_ERASEBKGND()
  244. ON_WM_PAINT()
  245. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  246. ON_WM_SETFOCUS()
  247. ON_WM_KILLFOCUS()
  248. ON_WM_SIZE()
  249. ON_WM_SETCURSOR()
  250. ON_WM_LBUTTONDOWN()
  251. ON_WM_LBUTTONUP()
  252. ON_COMMAND(XTP_IDC_PROPERTYGRID_ALPHABETIC, OnSortAlphabetic)
  253. ON_COMMAND(XTP_IDC_PROPERTYGRID_CATEGORIZED, OnSortCategorized)
  254. ON_WM_SYSCOLORCHANGE()
  255. ON_WM_KEYDOWN()
  256. ON_WM_GETDLGCODE()
  257. //}}AFX_MSG_MAP
  258. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
  259. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
  260. END_MESSAGE_MAP()
  261. UINT CXTPPropertyGrid::OnGetDlgCode()
  262. {
  263. return DLGC_WANTALLKEYS;
  264. }
  265. BOOL CXTPPropertyGrid::CreateGridView(DWORD dwListStyle)
  266. {
  267. CXTPEmptyRect rect;
  268. if (dwListStyle == NULL)
  269. {
  270. dwListStyle = m_bVariableItemsHeight ? LBS_OWNERDRAWVARIABLE | LBS_NOINTEGRALHEIGHT :
  271. LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT;
  272. }
  273. if (m_bMultiSelect)
  274. {
  275. dwListStyle |= LBS_MULTIPLESEL | LBS_EXTENDEDSEL;
  276. }
  277. // Must be owner draw.
  278. ASSERT((dwListStyle & (LBS_OWNERDRAWVARIABLE|LBS_OWNERDRAWFIXED)) != 0);
  279. m_bVariableItemsHeight = (dwListStyle & LBS_OWNERDRAWVARIABLE) != 0;
  280. if (!GetGridView().CreateEx(0, _T("LISTBOX"), NULL,
  281. WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE |
  282. LBS_NOTIFY | WS_VSCROLL | WS_TABSTOP | dwListStyle, rect, this, 0))
  283. {
  284. TRACE0("Error creating property grid view.n");
  285. return FALSE;
  286. }
  287. GetGridView().ResetContent();
  288. SetStandardColors();
  289. return TRUE;
  290. }
  291. BOOL CXTPPropertyGrid::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwListStyle /*= LBS_OWNERDRAWFIXED|LBS_NOINTEGRALHEIGHT*/)
  292. {
  293. if (!CreateEx(0, XTPPROPERTYGRID_CLASSNAME, _T(""),
  294. WS_TABSTOP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_GROUP, rect, pParentWnd, nID))
  295. {
  296. TRACE0("Error creating property grid.n");
  297. return FALSE;
  298. }
  299. if (!CreateGridView(dwListStyle))
  300. return FALSE;
  301. Reposition(rect.right - rect.left, rect.bottom - rect.top);
  302. SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
  303. SWP_SHOWWINDOW|SWP_NOZORDER);
  304. return TRUE;
  305. }
  306. BOOL CXTPPropertyGrid::PreCreateWindow(CREATESTRUCT& cs)
  307. {
  308. if (!CWnd::PreCreateWindow(cs))
  309. return FALSE;
  310. //
  311. // PreCreateWindow is called when a control is dynamically
  312. // created. We want to set m_bPreSubclassWindow to FALSE
  313. // here so the control is initialized from CWnd::Create and
  314. // not CWnd::PreSubclassWindow.
  315. //
  316. m_bPreSubclassWindow = FALSE;
  317. return TRUE;
  318. }
  319. void CXTPPropertyGrid::PreSubclassWindow()
  320. {
  321. CWnd::PreSubclassWindow();
  322. if (m_bPreSubclassWindow)
  323. {
  324. // Initialize the control.
  325. VERIFY(CreateGridView(NULL));
  326. Reposition();
  327. }
  328. }
  329. void CXTPPropertyGrid::SetVariableItemsHeight(BOOL bVariable /*= TRUE*/)
  330. {
  331. if (m_bVariableItemsHeight == bVariable)
  332. return;
  333. m_bVariableItemsHeight = bVariable;
  334. RecreateView();
  335. }
  336. void CXTPPropertyGrid::RecreateView()
  337. {
  338. CXTPPropertyGridView& wndView = GetGridView();
  339. if (!wndView.GetSafeHwnd())
  340. return;
  341. wndView.ResetContent();
  342. wndView.DestroyWindow();
  343. DWORD dwListStyle = m_bVariableItemsHeight ? LBS_OWNERDRAWVARIABLE | LBS_NOINTEGRALHEIGHT : LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT;
  344. if (m_bMultiSelect)
  345. {
  346. dwListStyle |= LBS_MULTIPLESEL | LBS_EXTENDEDSEL;
  347. }
  348. VERIFY(GetGridView().CreateEx(0, _T("LISTBOX"), NULL, WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_TABSTOP | dwListStyle, CXTPEmptyRect(), this, 0));
  349. wndView.Refresh();
  350. Reposition();
  351. }
  352. void CXTPPropertyGrid::EnableMultiSelect(BOOL bMultiSelect)
  353. {
  354. if (m_bMultiSelect == bMultiSelect)
  355. return;
  356. m_bMultiSelect = bMultiSelect;
  357. RecreateView();
  358. }
  359. /////////////////////////////////////////////////////////////////////////////
  360. // CXTPPropertyGrid message handlers
  361. BOOL CXTPPropertyGrid::OnEraseBkgnd(CDC*)
  362. {
  363. return TRUE;
  364. }
  365. void CXTPPropertyGrid::OnPaint()
  366. {
  367. CPaintDC dcPaint(this);
  368. CXTPBufferDC dc(dcPaint);
  369. m_pPaintManager->FillPropertyGrid(&dc);
  370. }
  371. LRESULT CXTPPropertyGrid::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  372. {
  373. CDC* pDC = CDC::FromHandle((HDC)wParam);
  374. if (pDC)
  375. {
  376. m_pPaintManager->FillPropertyGrid(pDC);
  377. }
  378. return TRUE;
  379. }
  380. CWnd* CXTPPropertyGrid::GetNextGridTabItem(BOOL bForward)
  381. {
  382. CWnd* pThis = this;
  383. CWnd* pParent = pThis->GetParent();
  384. if (!pThis || !pParent)
  385. {
  386. ASSERT(FALSE);
  387. return 0 ;
  388. }
  389. if ((pParent->GetExStyle() & WS_EX_CONTROLPARENT) && (pParent->GetStyle() & WS_CHILD))
  390. {
  391. pParent = pParent->GetParent();
  392. }
  393. CWnd* pNextItem = pParent->GetNextDlgTabItem(pThis, bForward);
  394. if (pNextItem == pThis)
  395. return NULL;
  396. return pNextItem;
  397. }
  398. void CXTPPropertyGrid::OnNavigate(XTPPropertyGridUI nUIElement, BOOL bForward, CXTPPropertyGridItem* pItem)
  399. {
  400. int nNextElement = bForward ? +1 : -1;
  401. int nUI = nUIElement + nNextElement;
  402. CXTPPropertyGridView& wndView = GetGridView();
  403. if (pItem == NULL)
  404. pItem = wndView.GetSelectedItem();
  405. if (m_bTabItems)
  406. nUIElement = (XTPPropertyGridUI)-3;
  407. while (nUI != nUIElement)
  408. {
  409. if (nUI == xtpGridUIViewPrev)
  410. {
  411. nUI += nNextElement;
  412. if (m_bTabItems)
  413. {
  414. int nIndex = !bForward && pItem ? pItem->m_nIndex - 1 : 0;
  415. if (nIndex >= 0)
  416. {
  417. wndView.SetFocus();
  418. wndView.SetCurSel(nIndex);
  419. wndView.OnSelectionChanged();
  420. if (bForward)
  421. return;
  422. nUI = xtpGridUIInplaceButton;
  423. pItem = wndView.GetSelectedItem();
  424. }
  425. }
  426. }
  427. if (nUI == xtpGridUIView)
  428. {
  429. if (m_bTabCaptions)
  430. {
  431. wndView.SetFocus();
  432. wndView.FocusInplaceButton(NULL);
  433. return;
  434. }
  435. nUI += nNextElement;
  436. }
  437. if (nUI == xtpGridUIInplaceEdit)
  438. {
  439. if (pItem && pItem->GetFlags() & xtpGridItemHasEdit)
  440. {
  441. pItem->OnSelect();
  442. pItem->SetFocusToInplaceControl();
  443. return;
  444. }
  445. nUI += nNextElement;
  446. }
  447. if (nUI == xtpGridUIInplaceControl)
  448. {
  449. if (pItem && pItem->GetInplaceControls()->GetCount() > 0)
  450. {
  451. CWnd* pWnd = pItem->GetInplaceControls()->GetAt(0);
  452. if (pWnd && pWnd->GetSafeHwnd() && pWnd->GetStyle() & WS_TABSTOP)
  453. {
  454. pWnd->SetFocus();
  455. return;
  456. }
  457. }
  458. nUI += nNextElement;
  459. }
  460. if (nUI == xtpGridUIInplaceButton)
  461. {
  462. if (pItem && pItem->IsInplaceButtonsVisible())
  463. {
  464. CXTPPropertyGridInplaceButtons* pButtons = pItem->GetInplaceButtons();
  465. if (wndView.m_pFocusedButton && wndView.m_pFocusedButton->GetItem() == pItem)
  466. {
  467. int nIndex = wndView.m_pFocusedButton->GetIndex();
  468. if (bForward && nIndex < pButtons->GetCount() -1)
  469. {
  470. wndView.FocusInplaceButton(pButtons->GetAt(nIndex + 1));
  471. return;
  472. }
  473. else if (!bForward && nIndex > 0)
  474. {
  475. wndView.FocusInplaceButton(pButtons->GetAt(nIndex - 1));
  476. return;
  477. }
  478. }
  479. else
  480. {
  481. wndView.FocusInplaceButton(pButtons->GetAt(bForward ? 0 : pButtons->GetCount() - 1));
  482. return;
  483. }
  484. }
  485. nUI += nNextElement;
  486. }
  487. if (nUI == xtpGridUIViewNext)
  488. {
  489. if (m_bTabItems)
  490. {
  491. int nIndex = bForward ? (pItem ? pItem->m_nIndex + 1 : 0) : wndView.GetCount() - 1;
  492. if (nIndex < wndView.GetCount())
  493. {
  494. wndView.SetFocus();
  495. wndView.SetCurSel(nIndex);
  496. wndView.OnSelectionChanged();
  497. if (bForward)
  498. {
  499. if (!m_bTabCaptions)
  500. {
  501. nUI = xtpGridUIView;
  502. }
  503. else
  504. return;
  505. }
  506. pItem = wndView.GetSelectedItem();
  507. }
  508. }
  509. nUI += nNextElement;
  510. }
  511. if (nUI == xtpGridUIVerb)
  512. {
  513. if (IsVerbsVisible())
  514. {
  515. m_nFocusedVerb = bForward ? 0 : m_pVerbs->GetCount() - 1;
  516. m_bVerbActivate = TRUE;
  517. SetFocus();
  518. m_bVerbActivate = FALSE;
  519. Invalidate(FALSE);
  520. return;
  521. }
  522. nUI += nNextElement;
  523. }
  524. if (nUI == xtpGridUIParentNext || nUI == xtpGridUIParentPrev)
  525. {
  526. CWnd* pWndNext = GetNextGridTabItem(!bForward);
  527. if (pWndNext != NULL)
  528. {
  529. pWndNext->SetFocus();
  530. return;
  531. }
  532. nUI = (nUI == xtpGridUIParentNext) ? xtpGridUIViewPrev : xtpGridUIVerb;
  533. }
  534. if (nUI < xtpGridUIParentPrev || nUI > xtpGridUIParentNext)
  535. {
  536. ASSERT(FALSE);
  537. return;
  538. }
  539. }
  540. }
  541. void CXTPPropertyGrid::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  542. {
  543. if (m_nFocusedVerb != -1 && IsVerbsVisible())
  544. {
  545. if (m_nFocusedVerb >= m_pVerbs->GetCount())
  546. m_nFocusedVerb = m_pVerbs->GetCount() -1;
  547. BOOL bForward = GetKeyState(VK_SHIFT) >= 0;
  548. CXTPDrawHelpers::KeyToLayout(this, nChar);
  549. if ((nChar == VK_TAB) && bForward && (m_nFocusedVerb == m_pVerbs->GetCount() -1))
  550. {
  551. OnNavigate(xtpGridUIVerb, TRUE, NULL);
  552. return;
  553. }
  554. else if ((nChar == VK_TAB) && !bForward && (m_nFocusedVerb == 0))
  555. {
  556. OnNavigate(xtpGridUIVerb, FALSE, NULL);
  557. return;
  558. }
  559. else if (nChar == VK_RIGHT || nChar == VK_DOWN || ((nChar == VK_TAB) && bForward))
  560. {
  561. m_nFocusedVerb++;
  562. if (m_nFocusedVerb >= m_pVerbs->GetCount())
  563. m_nFocusedVerb = 0;
  564. Invalidate(FALSE);
  565. }
  566. else if (nChar == VK_LEFT || nChar == VK_UP || nChar == VK_TAB)
  567. {
  568. m_nFocusedVerb--;
  569. if (m_nFocusedVerb < 0)
  570. m_nFocusedVerb = m_pVerbs->GetCount() -1;
  571. Invalidate(FALSE);
  572. }
  573. else if (nChar == VK_RETURN)
  574. {
  575. CRect rcPart = m_pVerbs->GetAt(m_nFocusedVerb)->GetPart();
  576. OnVerbClick(m_nFocusedVerb, CPoint(rcPart.left, rcPart.bottom));
  577. }
  578. }
  579. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  580. }
  581. void CXTPPropertyGrid::OnKillFocus(CWnd* pNewWnd)
  582. {
  583. if (m_nFocusedVerb != -1)
  584. {
  585. m_nFocusedVerb = -1;
  586. Invalidate(FALSE);
  587. }
  588. CWnd::OnKillFocus(pNewWnd);
  589. }
  590. void CXTPPropertyGrid::OnSetFocus(CWnd* pOldWnd)
  591. {
  592. if (!m_bVerbActivate)
  593. {
  594. if (pOldWnd && pOldWnd == GetNextGridTabItem(FALSE) && GetKeyState(VK_SHIFT) < 0)
  595. {
  596. OnNavigate(xtpGridUIParentNext, FALSE, NULL);
  597. }
  598. else if (pOldWnd && pOldWnd == GetNextGridTabItem(TRUE) && GetKeyState(VK_SHIFT) >= 0)
  599. {
  600. OnNavigate(xtpGridUIParentPrev, TRUE, NULL);
  601. }
  602. else
  603. {
  604. GetGridView().SetFocus();
  605. }
  606. }
  607. else
  608. {
  609. CWnd::OnSetFocus(pOldWnd);
  610. }
  611. }
  612. void CXTPPropertyGrid::OnSize(UINT nType, int cx, int cy)
  613. {
  614. CWnd::OnSize(nType, cx, cy);
  615. if (!GetGridView().GetSafeHwnd())
  616. return;
  617. Reposition(cx, cy);
  618. }
  619. int CXTPPropertyGrid::HitTest(CPoint pt)
  620. {
  621. CXTPClientRect rc(this);
  622. if (m_bHelpVisible)
  623. {
  624. CRect rcSplitter(CPoint(rc.left, rc.bottom - SPLITTER_HEIGHT - m_nHelpHeight), CSize(rc.Width(), SPLITTER_HEIGHT));
  625. if (m_bVariableHelpHeight && rcSplitter.PtInRect(pt))
  626. return xtpGridHitHelpSplitter;
  627. rc.bottom -= SPLITTER_HEIGHT + m_nHelpHeight;
  628. }
  629. if (IsVerbsVisible())
  630. {
  631. CRect rcSplitter(CPoint(rc.left, rc.bottom - SPLITTER_HEIGHT - m_nVerbsHeight), CSize(rc.Width(), SPLITTER_HEIGHT));
  632. if (rcSplitter.PtInRect(pt))
  633. return xtpGridHitVerbsSplitter;
  634. CRect rcVerbs(rc);
  635. rcVerbs.top = rc.bottom - m_nVerbsHeight;
  636. if (rcVerbs.PtInRect(pt))
  637. {
  638. CWindowDC dc(this);
  639. int nIndex = m_pPaintManager->HitTestVerbs(&dc, rcVerbs, pt);
  640. if (nIndex != -1)
  641. {
  642. return xtpGridHitFirstVerb + nIndex;
  643. }
  644. }
  645. }
  646. return xtpGridHitError;
  647. }
  648. BOOL CXTPPropertyGrid::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  649. {
  650. if (nHitTest == HTCLIENT)
  651. {
  652. CPoint point;
  653. GetCursorPos(&point);
  654. ScreenToClient(&point);
  655. int nHit = HitTest(point);
  656. if (nHit == xtpGridHitHelpSplitter || nHit == xtpGridHitVerbsSplitter)
  657. {
  658. SetCursor(m_hCursorSplit);
  659. return TRUE;
  660. }
  661. if ((nHit != -1) && (nHit >= xtpGridHitFirstVerb))
  662. {
  663. SetCursor(m_hCursorHand);
  664. return TRUE;
  665. }
  666. }
  667. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  668. }
  669. void CXTPPropertyGrid::OnInvertTracker(CRect rect)
  670. {
  671. ASSERT_VALID(this);
  672. ASSERT(!rect.IsRectEmpty());
  673. ASSERT((GetStyle() & WS_CLIPCHILDREN) == 0);
  674. // pat-blt without clip children on
  675. CDC* pDC = GetDC();
  676. CBrush brush(GetXtremeColor(COLOR_3DFACE));
  677. CBrush* pBrush = (CBrush*)pDC->SelectObject(&brush);
  678. pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  679. pDC->SelectObject(pBrush);
  680. ReleaseDC(pDC);
  681. }
  682. void CXTPPropertyGrid::OnSelectionChanged(CXTPPropertyGridItem* pItem)
  683. {
  684. if (!m_hWnd)
  685. return;
  686. CXTPClientRect rc(this);
  687. CRect rcHelp(rc);
  688. rcHelp.top = rc.bottom - m_nHelpHeight;
  689. if (pItem) SendNotifyMessage(XTP_PGN_SELECTION_CHANGED, (LPARAM)pItem);
  690. InvalidateRect(rcHelp, FALSE);
  691. }
  692. void CXTPPropertyGrid::OnVerbsChanged()
  693. {
  694. if (m_bVerbsVisible != IsVerbsVisible() && GetGridView().m_nLockUpdate == 0)
  695. {
  696. Reposition();
  697. }
  698. else if (GetSafeHwnd() && GetGridView().m_nLockUpdate == 0)
  699. {
  700. Invalidate(FALSE);
  701. }
  702. }
  703. void CXTPPropertyGrid::OnVerbClick(int nIndex, CPoint pt)
  704. {
  705. ClientToScreen(&pt);
  706. ASSERT(nIndex < m_pVerbs->GetCount());
  707. CXTPPropertyGridVerb* pVerb = m_pVerbs->GetAt(nIndex);
  708. pVerb->m_ptClick = pt;
  709. SendNotifyMessage(XTP_PGN_VERB_CLICK, (LPARAM)pVerb);
  710. }
  711. void CXTPPropertyGrid::OnLButtonUp(UINT nFlags, CPoint point)
  712. {
  713. if ((m_nFocusedVerb != -1) && (m_nFocusedVerb == HitTest(point) - xtpGridHitFirstVerb))
  714. {
  715. OnVerbClick(m_nFocusedVerb, point);
  716. }
  717. else
  718. {
  719. CWnd::OnLButtonUp(nFlags, point);
  720. }
  721. }
  722. void CXTPPropertyGrid::OnLButtonDown(UINT nFlags, CPoint point)
  723. {
  724. int nHitTest = HitTest(point);
  725. if ((nHitTest != -1) && (nHitTest >= xtpGridHitFirstVerb))
  726. {
  727. m_nFocusedVerb = nHitTest - xtpGridHitFirstVerb;
  728. m_bVerbActivate = TRUE;
  729. SetFocus();
  730. m_bVerbActivate = FALSE;
  731. Invalidate(FALSE);
  732. return;
  733. }
  734. SetFocus();
  735. if ((nHitTest == xtpGridHitHelpSplitter) || (nHitTest == xtpGridHitVerbsSplitter))
  736. {
  737. SetCapture();
  738. CXTPClientRect rc(this);
  739. BOOL bHelpHitTest = nHitTest == xtpGridHitHelpSplitter;
  740. CRect rcAvail = bHelpHitTest ? CRect(0, 20 + TOOLBAR_HEIGHT, rc.right, rc.bottom) :
  741. CRect(0, 20 + TOOLBAR_HEIGHT, rc.right, rc.bottom - (IsHelpVisible() ? m_nHelpHeight + SPLITTER_HEIGHT : 0));
  742. ModifyStyle(WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, FALSE);
  743. m_rectTracker.SetRect(0, point.y, rc.Width(), point.y + 3);
  744. OnInvertTracker(m_rectTracker);
  745. BOOL bAccept = FALSE;
  746. while (GetCapture() == this)
  747. {
  748. MSG msg;
  749. if (!GetMessage(&msg, NULL, 0, 0))
  750. break;
  751. if (msg.message == WM_MOUSEMOVE)
  752. {
  753. point = CPoint(msg.lParam);
  754. point.y = __min(point.y, rcAvail.bottom - 20);
  755. point.y = __max((int)point.y, int(rcAvail.top));
  756. if (m_rectTracker.top != point.y)
  757. {
  758. OnInvertTracker(m_rectTracker);
  759. m_rectTracker.OffsetRect(0, point.y - m_rectTracker.top);
  760. OnInvertTracker(m_rectTracker);
  761. }
  762. }
  763. else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
  764. else if (msg.message == WM_LBUTTONUP)
  765. {
  766. bAccept = TRUE;
  767. break;
  768. }
  769. else  ::DispatchMessage(&msg);
  770. }
  771. ReleaseCapture();
  772. if (bAccept)
  773. {
  774. if (bHelpHitTest) m_nHelpHeight = rcAvail.bottom - m_rectTracker.top -2; else
  775. m_nVerbsHeight = rcAvail.bottom - m_rectTracker.top -2;
  776. Reposition(rc.Width(), rc.Height());
  777. }
  778. Invalidate(FALSE);
  779. ModifyStyle(0, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, FALSE);
  780. return;
  781. }
  782. CWnd::OnLButtonDown(nFlags, point);
  783. }
  784. void CXTPPropertyGrid::Reposition()
  785. {
  786. if (GetSafeHwnd() == 0)
  787. return;
  788. CXTPClientRect rc(this);
  789. Reposition(rc.Width(), rc.Height());
  790. }
  791. void CXTPPropertyGrid::Reposition(int cx, int cy)
  792. {
  793. if (GetGridView().m_nLockUpdate > 0)
  794. return;
  795. if (GetSafeHwnd() == 0)
  796. return;
  797. CRect rcView(0, 0, cx, cy);
  798. int nMinViewHeight = 20 + (m_bToolBarVisible ? TOOLBAR_HEIGHT : 0);
  799. if (m_bHelpVisible)
  800. {
  801. if (cy > nMinViewHeight && cy - m_nHelpHeight - SPLITTER_HEIGHT < nMinViewHeight && m_bVariableHelpHeight)
  802. {
  803. m_nHelpHeight = max(0, cy - SPLITTER_HEIGHT - nMinViewHeight);
  804. }
  805. rcView.bottom -= m_nHelpHeight + SPLITTER_HEIGHT;
  806. }
  807. if (IsVerbsVisible())
  808. {
  809. rcView.bottom -= m_nVerbsHeight + SPLITTER_HEIGHT;
  810. }
  811. m_bVerbsVisible = IsVerbsVisible();
  812. if (m_bToolBarVisible)
  813. {
  814. ASSERT(m_wndToolbar.GetSafeHwnd());
  815. CRect rcToolBar(0, 0, cx, TOOLBAR_HEIGHT);
  816. m_wndToolbar.MoveWindow(rcToolBar);
  817. rcView.top += TOOLBAR_HEIGHT;
  818. }
  819. GetGridView().MoveWindow(rcView);
  820. GetGridView().Invalidate(FALSE);
  821. Invalidate(FALSE);
  822. }
  823. void CXTPPropertyGrid::CreateToolbar()
  824. {
  825. #if _MSC_VER < 1200
  826. m_wndToolbar.Create(this, TBSTYLE_TRANSPARENT | TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE | WS_BORDER, 0);
  827. #else
  828. m_wndToolbar.CreateEx(this, TBSTYLE_TRANSPARENT | TBSTYLE_FLAT, WS_BORDER | WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP);
  829. #endif
  830. VERIFY(XTPResourceManager()->LoadToolBar(&m_wndToolbar, XTP_IDR_PROPERTYGRID_TOOLBAR));
  831. }
  832. void CXTPPropertyGrid::ShowToolBar(BOOL bShow)
  833. {
  834. if (bShow && !m_wndToolbar.GetSafeHwnd())
  835. {
  836. CreateToolbar();
  837. }
  838. else
  839. {
  840. if (m_wndToolbar.GetSafeHwnd())
  841. m_wndToolbar.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  842. }
  843. m_bToolBarVisible = bShow;
  844. Reposition();
  845. RefreshToolBarButtons();
  846. }
  847. void CXTPPropertyGrid::RefreshToolBarButtons()
  848. {
  849. if (m_bToolBarVisible)
  850. {
  851. m_wndToolbar.GetToolBarCtrl().SetState(XTP_IDC_PROPERTYGRID_CATEGORIZED, TBSTATE_ENABLED | (GetGridView().m_properetySort == xtpGridSortCategorized ? TBSTATE_CHECKED : 0));
  852. m_wndToolbar.GetToolBarCtrl().SetState(XTP_IDC_PROPERTYGRID_ALPHABETIC, TBSTATE_ENABLED | (GetGridView().m_properetySort == xtpGridSortAlphabetical ? TBSTATE_CHECKED : 0));
  853. }
  854. }
  855. void CXTPPropertyGrid::ShowHelp(BOOL bShow)
  856. {
  857. m_bHelpVisible = bShow;
  858. Reposition();
  859. }
  860. void CXTPPropertyGrid::OnSortAlphabetic()
  861. {
  862. SetPropertySort(xtpGridSortAlphabetical);
  863. }
  864. void CXTPPropertyGrid::OnSortCategorized()
  865. {
  866. SetPropertySort(xtpGridSortCategorized);
  867. }
  868. void CXTPPropertyGrid::OnSortChanged()
  869. {
  870. RefreshToolBarButtons();
  871. OnSelectionChanged(NULL);
  872. SendNotifyMessage(XTP_PGN_SORTORDER_CHANGED, (LPARAM)GetDlgCtrlID());
  873. }
  874. LRESULT CXTPPropertyGrid::SendNotifyMessage(WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/)
  875. {
  876. return GetOwner()->SendMessage(XTPWM_PROPERTYGRID_NOTIFY, wParam, lParam);
  877. }
  878. void CXTPPropertyGrid::SetStandardColors()
  879. {
  880. m_pPaintManager->GetItemMetrics()->SetDefaultValues();
  881. m_pPaintManager->RefreshMetrics();
  882. RedrawControl();
  883. }
  884. void CXTPPropertyGrid::RedrawControl()
  885. {
  886. if (GetSafeHwnd())
  887. {
  888. RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE);
  889. }
  890. }
  891. void CXTPPropertyGrid::SetCustomColors(
  892. COLORREF clrHelpBack, COLORREF clrHelpFore, COLORREF clrViewLine,
  893. COLORREF clrViewBack, COLORREF clrViewFore, COLORREF clrCategoryFore)
  894. {
  895. CXTPPropertyGridItemMetrics* pMetrics = m_pPaintManager->GetItemMetrics();
  896. pMetrics->m_clrHelpBack.SetCustomValue(clrHelpBack);
  897. pMetrics->m_clrHelpFore.SetCustomValue(clrHelpFore);
  898. pMetrics->m_clrLine.SetCustomValue(clrViewLine);
  899. pMetrics->m_clrBack.SetCustomValue(clrViewBack);
  900. pMetrics->m_clrFore.SetCustomValue(clrViewFore);
  901. pMetrics->m_clrCategoryFore.SetCustomValue(clrCategoryFore);
  902. RedrawControl();
  903. }
  904. void CXTPPropertyGrid::ResetContent()
  905. {
  906. m_pVerbs->RemoveAll();
  907. GetGridView().ResetContent();
  908. GetGridView().m_nLockUpdate++;
  909. GetGridView().m_pCategories->Clear();
  910. GetGridView().m_nLockUpdate--;
  911. }
  912. CXTPPropertyGridItems* CXTPPropertyGrid::GetCategories() const
  913. {
  914. return GetGridView().m_pCategories;
  915. }
  916. CXTPPropertyGridItem* CXTPPropertyGrid::AddCategory(int nID, CXTPPropertyGridItem* pCategory)
  917. {
  918. CString strCaption;
  919. VERIFY(strCaption.LoadString(nID));
  920. CXTPPropertyGridItem* pItem = GetGridView().AddCategory(strCaption, pCategory);
  921. pItem->SetID(nID);
  922. return pItem;
  923. }
  924. CXTPPropertyGridItem* CXTPPropertyGrid::InsertCategory(int nIndex, int nID, CXTPPropertyGridItem* pCategory)
  925. {
  926. CString strCaption;
  927. VERIFY(strCaption.LoadString(nID));
  928. CXTPPropertyGridItem* pItem = GetGridView().InsertCategory(nIndex, strCaption, pCategory);
  929. pItem->SetID(nID);
  930. return pItem;
  931. }
  932. void CXTPPropertyGrid::SetFont(CFont* pFont)
  933. {
  934. LOGFONT lf;
  935. if (pFont->GetLogFont(&lf))
  936. {
  937. CXTPPropertyGridItemMetrics* pMetrics = m_pPaintManager->GetItemMetrics();
  938. pMetrics->m_fontNormal.DeleteObject();
  939. pMetrics->m_fontBold.DeleteObject();
  940. lf.lfWeight = FW_NORMAL;
  941. VERIFY(pMetrics->m_fontNormal.CreateFontIndirect(&lf));
  942. lf.lfWeight = FW_BOLD;
  943. VERIFY(pMetrics->m_fontBold.CreateFontIndirect(&lf));
  944. if (m_pInplaceEdit->GetSafeHwnd())
  945. {
  946. m_pInplaceEdit->SetFont(&pMetrics->m_fontNormal);
  947. }
  948. Refresh();
  949. }
  950. }
  951. void CXTPPropertyGrid::Refresh()
  952. {
  953. GetGridView().SetPropertySort(GetPropertySort(), TRUE);
  954. }
  955. void CXTPPropertyGrid::SaveExpandingState(CXTPPropertyGridItems* pItems, CXTPPropertyGridUpdateContext& context)
  956. {
  957. int nTopIndex = GetGridView().GetTopIndex();
  958. for (int nItem = 0; nItem < pItems->GetCount(); nItem++)
  959. {
  960. CXTPPropertyGridItem* pItem = pItems->GetAt(nItem);
  961. if (pItem->GetID() != 0)
  962. {
  963. if (pItem->HasChilds())
  964. {
  965. BOOL bExpanded = pItem->IsExpanded();
  966. context.m_mapState.SetAt(pItem->GetID(), bExpanded);
  967. }
  968. if (pItem->IsSelected()) context.m_nSelected = pItem->GetID();
  969. if (pItem->GetIndex() == nTopIndex) context.m_nTopIndex= pItem->GetID();
  970. }
  971. SaveExpandingState(pItem->GetChilds(), context);
  972. }
  973. }
  974. void CXTPPropertyGrid::RestoreExpandingState(CXTPPropertyGridItems* pItems, CXTPPropertyGridUpdateContext& context)
  975. {
  976. for (int nItem = 0; nItem < pItems->GetCount(); nItem++)
  977. {
  978. CXTPPropertyGridItem* pItem = pItems->GetAt(nItem);
  979. BOOL bExpanded;
  980. if (pItem->GetID() != 0 && context.m_mapState.Lookup(pItem->GetID(), bExpanded))
  981. {
  982. if (bExpanded)
  983. pItem->Expand();
  984. else
  985. pItem->Collapse();
  986. }
  987. RestoreExpandingState(pItem->GetChilds(), context);
  988. }
  989. }
  990. void CXTPPropertyGrid::BeginUpdate(CXTPPropertyGridUpdateContext& context, BOOL bResetContent)
  991. {
  992. GetGridView().m_nLockUpdate = 1;
  993. GetGridView().SetRedraw(FALSE);
  994. context.m_nSelected = 0;
  995. context.m_nTopIndex = 0;
  996. context.m_propertySort = GetPropertySort();
  997. if (bResetContent)
  998. {
  999. SaveExpandingState(GetCategories(), context);
  1000. ResetContent();
  1001. }
  1002. else
  1003. {
  1004. GetGridView().ResetContent();
  1005. }
  1006. }
  1007. void CXTPPropertyGrid::EndUpdate(CXTPPropertyGridUpdateContext& context)
  1008. {
  1009. RestoreExpandingState(GetCategories(), context);
  1010. GetGridView().m_nLockUpdate = 0;
  1011. GetGridView().SetPropertySort(context.m_propertySort, TRUE, FALSE);
  1012. if (context.m_nSelected > 0 || context.m_nTopIndex > 0)
  1013. {
  1014. for (int i = 0; i < GetGridView().GetCount(); i++)
  1015. {
  1016. CXTPPropertyGridItem* pItem = GetGridView().GetItem(i);
  1017. if (context.m_nTopIndex > 0 && pItem && pItem->GetID() == context.m_nTopIndex)
  1018. {
  1019. SetTopIndex(pItem->GetIndex());
  1020. context.m_nTopIndex = 0;
  1021. if (context.m_nSelected == 0)
  1022. break;
  1023. }
  1024. if (context.m_nSelected > 0 && pItem && pItem->GetID() == context.m_nSelected)
  1025. {
  1026. pItem->Select();
  1027. break;
  1028. }
  1029. }
  1030. }
  1031. GetGridView().SetRedraw(TRUE);
  1032. Reposition();
  1033. }
  1034. void CXTPPropertyGrid::SetVerbsHeight(int nHeight)
  1035. {
  1036. ASSERT(nHeight > 0);
  1037. m_nVerbsHeight = nHeight;
  1038. Reposition();
  1039. }
  1040. void CXTPPropertyGrid::SetHelpHeight(int nHeight)
  1041. {
  1042. ASSERT(nHeight > 0);
  1043. m_nHelpHeight = nHeight;
  1044. Reposition();
  1045. }
  1046. void CXTPPropertyGrid::SetViewDivider(double dDivider)
  1047. {
  1048. ASSERT(dDivider > 0 && dDivider < 1);
  1049. GetGridView().m_dDivider = dDivider;
  1050. Reposition();
  1051. }
  1052. double CXTPPropertyGrid::GetViewDivider() const
  1053. {
  1054. return GetGridView().m_dDivider;
  1055. }
  1056. void CXTPPropertyGrid::SetViewDividerPos(int nDivider, BOOL bLockDivider /*= FALSE*/)
  1057. {
  1058. if (bLockDivider)
  1059. {
  1060. GetGridView().LockDivider();
  1061. }
  1062. GetGridView().SetDividerPos(nDivider);
  1063. Reposition();
  1064. }
  1065. CXTPPropertyGridItem* CXTPPropertyGrid::GetSelectedItem() const
  1066. {
  1067. return GetGridView().GetSelectedItem();
  1068. }
  1069. CXTPPropertyGridItem* CXTPPropertyGrid::GetItem(int nIndex) const
  1070. {
  1071. return GetGridView().GetItem(nIndex);
  1072. }
  1073. int CXTPPropertyGrid::GetSelectedItems(CArray<int, int>* pItems) const
  1074. {
  1075. CXTPPropertyGridView* pView = &GetGridView();
  1076. if (pView->GetStyle() & LBS_MULTIPLESEL)
  1077. {
  1078. int nCount = pView->GetSelCount();
  1079. if (!pItems)
  1080. return nCount;
  1081. pItems->SetSize(nCount);
  1082. pView->GetSelItems(nCount, pItems->GetData());
  1083. }
  1084. else
  1085. {
  1086. CXTPPropertyGridItem* pItem = GetSelectedItem();
  1087. if (!pItems)
  1088. return pItem ? 1 : 0;
  1089. if (pItem)
  1090. {
  1091. pItems->RemoveAll();
  1092. pItems->Add(pItem->GetIndent());
  1093. }
  1094. }
  1095. return (int)pItems->GetSize();
  1096. }
  1097. int CXTPPropertyGrid::GetTopIndex() const
  1098. {
  1099. return GetGridView().GetTopIndex();
  1100. }
  1101. void CXTPPropertyGrid::SetTopIndex(int nIndex)
  1102. {
  1103. GetGridView().SetTopIndex(nIndex);
  1104. }
  1105. void CXTPPropertyGrid::SetTheme(XTPPropertyGridPaintTheme paintTheme)
  1106. {
  1107. if (paintTheme == xtpGridThemeDefault) SetCustomTheme(new CXTPPropertyGridPaintManager(this));
  1108. else if (paintTheme == xtpGridThemeCool) SetCustomTheme(new CXTPPropertyGridCoolTheme(this));
  1109. else if (paintTheme == xtpGridThemeDelphi) SetCustomTheme(new CXTPPropertyGridDelphiTheme(this));
  1110. else if (paintTheme == xtpGridThemeNativeWinXP) SetCustomTheme(new CXTPPropertyGridNativeXPTheme(this));
  1111. else if (paintTheme == xtpGridThemeOffice2003) SetCustomTheme(new CXTPPropertyGridOffice2003Theme(this));
  1112. else if (paintTheme == xtpGridThemeSimple) SetCustomTheme(new CXTPPropertyGridSimpleTheme(this));
  1113. else if (paintTheme == xtpGridThemeWhidbey) SetCustomTheme(new CXTPPropertyGridWhidbeyTheme(this));
  1114. else if (paintTheme == xtpGridThemeOfficeXP) SetCustomTheme(new CXTPPropertyGridOfficeXPTheme(this));
  1115. else if (paintTheme == xtpGridThemeOffice2007) SetCustomTheme(new CXTPPropertyGridOffice2007Theme(this));
  1116. else
  1117. {
  1118. ASSERT(FALSE);
  1119. }
  1120. m_themeCurrent = paintTheme;
  1121. }
  1122. void CXTPPropertyGrid::SetCustomTheme(CXTPPropertyGridPaintManager* pPaintManager)
  1123. {
  1124. CXTPPropertyGridItemMetrics* pMetrics = m_pPaintManager->m_pMetrics;
  1125. m_pPaintManager->m_pMetrics = 0;
  1126. ASSERT(m_pPaintManager);
  1127. CMDTARGET_RELEASE(m_pPaintManager);
  1128. m_pPaintManager = pPaintManager;
  1129. CMDTARGET_RELEASE(m_pPaintManager->m_pMetrics);
  1130. m_pPaintManager->m_pMetrics = pMetrics;
  1131. m_pPaintManager->RefreshMetrics();
  1132. RedrawControl();
  1133. }
  1134. CXTPImageManager* CXTPPropertyGrid::GetImageManager() const
  1135. {
  1136. return m_pImageManager ? m_pImageManager : XTPImageManager();
  1137. }
  1138. void CXTPPropertyGrid::SetImageManager(CXTPImageManager* pImageManager)
  1139. {
  1140. if (m_pImageManager)
  1141. m_pImageManager->InternalRelease();
  1142. m_pImageManager = pImageManager;
  1143. }
  1144. void CXTPPropertyGrid::OnSysColorChange()
  1145. {
  1146. CWnd::OnSysColorChange();
  1147. m_pPaintManager->RefreshMetrics();
  1148. RedrawControl();
  1149. }
  1150. BOOL CXTPPropertyGrid::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
  1151. {
  1152. ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
  1153. // need to handle both ANSI and UNICODE versions of the message
  1154. TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  1155. TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  1156. CString strTipText;
  1157. // don't handle the message if no string resource found
  1158. if (!XTPResourceManager()->LoadString(&strTipText, (UINT)pNMHDR->idFrom))
  1159. return FALSE;
  1160. #ifndef _UNICODE
  1161. if (pNMHDR->code == TTN_NEEDTEXTA)
  1162. lstrcpyn(pTTTA->szText, strTipText, _countof(pTTTA->szText));
  1163. else
  1164. _mbstowcsz(pTTTW->szText, strTipText, _countof(pTTTW->szText));
  1165. #else
  1166. if (pNMHDR->code == TTN_NEEDTEXTA)
  1167. _wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
  1168. else
  1169. lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
  1170. #endif
  1171. *pResult = 0;
  1172. // bring the tooltip window above other popup windows
  1173. ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
  1174. SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER);
  1175. return TRUE;    // message was handled
  1176. }
  1177. BOOL CXTPPropertyGrid::IsLayoutRTL() const
  1178. {
  1179. return GetExStyle() & WS_EX_LAYOUTRTL ? TRUE : FALSE;
  1180. }
  1181. void CXTPPropertyGrid::SetLayoutRTL(CWnd* pWnd, BOOL bRTLLayout)
  1182. {
  1183. pWnd->ModifyStyleEx(bRTLLayout ? 0 : WS_EX_LAYOUTRTL, !bRTLLayout ? 0 : WS_EX_LAYOUTRTL);
  1184. // walk through HWNDs to avoid creating temporary CWnd objects
  1185. // unless we need to call this function recursively
  1186. for (CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild != NULL;
  1187. pChild = pChild->GetWindow(GW_HWNDNEXT))
  1188. {
  1189. // send to child windows after parent
  1190. SetLayoutRTL(pChild, bRTLLayout);
  1191. }
  1192. }
  1193. void CXTPPropertyGrid::SetLayoutRTL(BOOL bRightToLeft)
  1194. {
  1195. if (!XTPSystemVersion()->IsLayoutRTLSupported())
  1196. return;
  1197. SetLayoutRTL(this, bRightToLeft);
  1198. if (m_pInplaceEdit && m_pInplaceEdit->GetSafeHwnd())
  1199. {
  1200. m_pInplaceEdit->HideWindow();
  1201. m_pInplaceEdit->m_bDelayCreate = TRUE;
  1202. }
  1203. if (GetSelectedItem()) GetSelectedItem()->OnSelect();
  1204. Reposition();
  1205. RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE);
  1206. }
  1207. void CXTPPropertyGrid::SetBorderStyle(XTPPropertyGridBorderStyle borderStyle)
  1208. {
  1209. m_borderStyle = borderStyle;
  1210. Reposition();
  1211. if (GetGridView().GetSafeHwnd())
  1212. {
  1213. GetGridView().SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  1214. }
  1215. }
  1216. XTPPropertyGridBorderStyle CXTPPropertyGrid::GetBorderStyle() const
  1217. {
  1218. return m_borderStyle;
  1219. }
  1220. void CXTPPropertyGrid::EnableMarkup(BOOL bEnable)
  1221. {
  1222. if (bEnable && m_pMarkupContext)
  1223. return;
  1224. XTPMarkupReleaseContext(m_pMarkupContext);
  1225. if (bEnable)
  1226. {
  1227. m_pMarkupContext = XTPMarkupCreateContext(m_hWnd);
  1228. }
  1229. }