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

对话框与窗口

开发平台:

Visual C++

  1. // XTPPropertyGridInplaceList.cpp : implementation of the CXTPPropertyGridInplaceList 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/XTPDrawHelpers.h"
  22. #include "Common/XTPVC80Helpers.h"
  23. #include "XTPPropertyGridInplaceEdit.h"
  24. #include "XTPPropertyGridInplaceButton.h"
  25. #include "XTPPropertyGridInplaceList.h"
  26. #include "XTPPropertyGridItem.h"
  27. #include "XTPPropertyGridInplaceList.h"
  28. #include "XTPPropertyGrid.h"
  29. #include "XTPPropertyGridView.h"
  30. #ifdef _DEBUG
  31. #define new DEBUG_NEW
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CXTPPropertyGridInplaceList
  37. CXTPPropertyGridInplaceList::CXTPPropertyGridInplaceList()
  38. : m_pItem(0)
  39. {
  40. }
  41. CXTPPropertyGridInplaceList::~CXTPPropertyGridInplaceList()
  42. {
  43. }
  44. IMPLEMENT_DYNAMIC(CXTPPropertyGridInplaceList, CListBox)
  45. BEGIN_MESSAGE_MAP(CXTPPropertyGridInplaceList, CListBox)
  46. //{{AFX_MSG_MAP(CXTPPropertyGridInplaceList)
  47. ON_WM_KILLFOCUS()
  48. ON_WM_LBUTTONUP()
  49. ON_WM_KEYDOWN()
  50. ON_WM_SYSKEYDOWN()
  51. ON_WM_MOUSEACTIVATE()
  52. //}}AFX_MSG_MAP
  53. END_MESSAGE_MAP()
  54. void CXTPPropertyGridInplaceList::MeasureItem(LPMEASUREITEMSTRUCT)
  55. {
  56. }
  57. void CXTPPropertyGridInplaceList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  58. {
  59. CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  60. CRect rc(lpDrawItemStruct->rcItem);
  61. CXTPPropertyGridItemConstraint* pConstraint = (CXTPPropertyGridItemConstraint*)GetItemDataPtr(lpDrawItemStruct->itemID);
  62. BOOL bSelected = (lpDrawItemStruct->itemState & ODS_SELECTED);
  63. if (m_pItem)
  64. {
  65. m_pItem->OnDrawItemConstraint(pDC, pConstraint, rc, bSelected);
  66. }
  67. }
  68. void CXTPPropertyGridInplaceList::Create(CXTPPropertyGridItem* pItem, CRect rect)
  69. {
  70. ASSERT(pItem && pItem->GetGrid());
  71. if (!pItem)
  72. return;
  73. CRect rcValue(rect);
  74. rcValue.left = pItem->GetGrid()->GetDividerPos() + 1;
  75. CWnd* pParent = (CWnd*)pItem->GetGrid();
  76. m_pItem = pItem;
  77. DestroyWindow();
  78. if (!m_hWnd)
  79. {
  80. CListBox::CreateEx(WS_EX_TOOLWINDOW | (pParent->GetExStyle() & WS_EX_LAYOUTRTL), _T("LISTBOX"), _T(""), LBS_NOTIFY | WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS, CRect(0, 0, 0, 0), pParent, 0);
  81. SetOwner(pParent);
  82. }
  83. SetFont(pParent->GetFont());
  84. ResetContent();
  85. CXTPPropertyGridItemConstraints* pList = pItem->GetConstraints();
  86. int dx = rect.right - rcValue.left;
  87. CWindowDC dc(pParent);
  88. CXTPFontDC font(&dc, pParent->GetFont());
  89. int nHeight = dc.GetTextExtent(_T(" "), 1).cy + 3;
  90. for (int i = 0; i < pList->GetCount(); i++)
  91. {
  92. CXTPPropertyGridItemConstraint* pConstraint = pList->GetConstraintAt(i);
  93. CString str = pConstraint->m_strConstraint;
  94. int nIndex = AddString(str);
  95. SetItemDataPtr(nIndex, pConstraint);
  96. CSize sz = pItem->OnMergeItemConstraint(&dc, pConstraint);
  97. dx = max(dx, sz.cx);
  98. nHeight = max(nHeight, sz.cy);
  99. if (pItem->GetValue() == str)
  100. SetCurSel(nIndex);
  101. }
  102. SetItemHeight(0, nHeight);
  103. rect.top = rect.bottom;
  104. rect.bottom += nHeight * __min(pItem->GetDropDownItemCount(), GetCount()) + 2;
  105. rect.left = rect.right - __min(dx, rect.Width() - XTP_PGI_EXPAND_BORDER);
  106. pParent->ClientToScreen(&rect);
  107. CRect rcWork = XTPMultiMonitor()->GetWorkArea(rect);
  108. if (rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y)
  109. {
  110. rect.OffsetRect(0, - rect.Height() - rcValue.Height() - 1);
  111. }
  112. if (rect.left < rcWork.left) rect.OffsetRect(rcWork.left - rect.left, 0);
  113. if (rect.right > rcWork.right) rect.OffsetRect(rcWork.right - rect.right, 0);
  114. SetFocus();
  115. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0);
  116. ModifyStyle(WS_CHILD, WS_POPUP);
  117. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)pParent->m_hWnd);
  118. SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  119. CXTPMouseMonitor::SetupHook(this);
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. // CXTPPropertyGridInplaceList message handlers
  123. void CXTPPropertyGridInplaceList::OnKillFocus(CWnd* pNewWnd)
  124. {
  125. CListBox::OnKillFocus(pNewWnd);
  126. CXTPMouseMonitor::SetupHook(NULL);
  127. Cancel();
  128. DestroyWindow();
  129. }
  130. int CXTPPropertyGridInplaceList::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
  131. {
  132. return MA_NOACTIVATE;
  133. }
  134. void CXTPPropertyGridInplaceList::PostNcDestroy()
  135. {
  136. CXTPMouseMonitor::SetupHook(NULL);
  137. CListBox::PostNcDestroy();
  138. }
  139. void CXTPPropertyGridInplaceList::OnLButtonUp(UINT, CPoint point)
  140. {
  141. CXTPClientRect rc(this);
  142. if (rc.PtInRect(point))
  143. Apply();
  144. else
  145. Cancel();
  146. }
  147. void CXTPPropertyGridInplaceList::Cancel()
  148. {
  149. if (m_pItem)
  150. {
  151. m_pItem->OnCancelEdit();
  152. m_pItem = NULL;
  153. }
  154. if (m_hWnd && ::GetFocus() == m_hWnd)
  155. {
  156. GetOwner()->SetFocus();
  157. }
  158. }
  159. void CXTPPropertyGridInplaceList::Apply()
  160. {
  161. int nIndex = GetCurSel();
  162. if (nIndex != LB_ERR && m_pItem)
  163. {
  164. CXTPPropertyGridItem* pItem = m_pItem;
  165. m_pItem = NULL;
  166. CXTPPropertyGridItemConstraints* pList = pItem->GetConstraints();
  167. pList->SetCurrent(nIndex);
  168. CString str;
  169. GetText(nIndex, str);
  170. if (pItem->OnAfterEdit(str) && str != pItem->GetValue())
  171. pItem->OnValueChanged(str);
  172. }
  173. if (m_hWnd && ::GetFocus() == m_hWnd)
  174. {
  175. GetOwner()->SetFocus();
  176. }
  177. }
  178. void CXTPPropertyGridInplaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  179. {
  180. if (nChar == VK_ESCAPE) Cancel();
  181. else if (nChar == VK_RETURN || nChar == VK_F4) Apply();
  182. else CListBox::OnKeyDown(nChar, nRepCnt, nFlags);
  183. }
  184. void CXTPPropertyGridInplaceList::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  185. {
  186. if (nChar == VK_DOWN || nChar == VK_UP)
  187. {
  188. Apply();
  189. return;
  190. }
  191. CListBox::OnSysKeyDown(nChar, nRepCnt, nFlags);
  192. }
  193. void CXTPPropertyGridInplaceList::DestroyItem()
  194. {
  195. // reset variables to defaults.
  196. m_pItem = NULL;
  197. CXTPMouseMonitor::SetupHook(NULL);
  198. // destroy the window.
  199. DestroyWindow();
  200. }
  201. /////////////////////////////////////////////////////////////////////////////
  202. // CXTPPropertyGridInplaceMultilineEdit
  203. CXTPPropertyGridInplaceMultilineEdit::CXTPPropertyGridInplaceMultilineEdit()
  204. : m_pItem(0)
  205. {
  206. }
  207. CXTPPropertyGridInplaceMultilineEdit::~CXTPPropertyGridInplaceMultilineEdit()
  208. {
  209. }
  210. IMPLEMENT_DYNAMIC(CXTPPropertyGridInplaceMultilineEdit, CEdit)
  211. BEGIN_MESSAGE_MAP(CXTPPropertyGridInplaceMultilineEdit, CEdit)
  212. //{{AFX_MSG_MAP(CXTPPropertyGridInplaceMultilineEdit)
  213. ON_WM_KILLFOCUS()
  214. ON_WM_KEYDOWN()
  215. ON_WM_SYSKEYDOWN()
  216. ON_WM_MOUSEACTIVATE()
  217. //}}AFX_MSG_MAP
  218. END_MESSAGE_MAP()
  219. void CXTPPropertyGridInplaceMultilineEdit::Create(CXTPPropertyGridItem* pItem, CRect rect)
  220. {
  221. ASSERT(pItem && pItem->GetGrid());
  222. if (!pItem)
  223. return;
  224. CRect rcValue(rect);
  225. rcValue.left = pItem->GetGrid()->GetDividerPos() + 1;
  226. CWnd* pParent = (CWnd*)pItem->GetGrid();
  227. m_pItem = pItem;
  228. if (!m_hWnd)
  229. {
  230. CEdit::CreateEx(WS_EX_TOOLWINDOW, _T("EDIT"), m_pItem->GetValue(), ES_MULTILINE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_AUTOVSCROLL, CRect(0, 0, 0, 0), pParent, 0);
  231. SetOwner(pParent);
  232. }
  233. SetFont(pParent->GetFont());
  234. int dx = rect.right - rcValue.left;
  235. CWindowDC dc(pParent);
  236. CXTPFontDC font(&dc, pParent->GetFont());
  237. int nHeight = dc.GetTextExtent(_T(" "), 1).cy;
  238. rect.top = rect.bottom;
  239. rect.bottom += nHeight * pItem->GetDropDownItemCount() + 4;
  240. rect.left = rect.right - __min(dx, rect.Width() - XTP_PGI_EXPAND_BORDER);
  241. pParent->ClientToScreen(&rect);
  242. CRect rcWork = XTPMultiMonitor()->GetWorkArea(rect);
  243. if (rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y)
  244. {
  245. rect.OffsetRect(0, - rect.Height() - rcValue.Height() - 1);
  246. }
  247. if (rect.left < rcWork.left) rect.OffsetRect(rcWork.left - rect.left, 0);
  248. if (rect.right > rcWork.right) rect.OffsetRect(rcWork.right - rect.right, 0);
  249. SetFocus();
  250. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0);
  251. ModifyStyle(WS_CHILD, WS_POPUP);
  252. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)pParent->m_hWnd);
  253. SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  254. CXTPMouseMonitor::SetupHook(this);
  255. }
  256. /////////////////////////////////////////////////////////////////////////////
  257. // CXTPPropertyGridInplaceMultilineEdit message handlers
  258. void CXTPPropertyGridInplaceMultilineEdit::OnKillFocus(CWnd* pNewWnd)
  259. {
  260. CEdit::OnKillFocus(pNewWnd);
  261. CXTPMouseMonitor::SetupHook(NULL);
  262. Cancel();
  263. DestroyWindow();
  264. }
  265. int CXTPPropertyGridInplaceMultilineEdit::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
  266. {
  267. return MA_NOACTIVATE;
  268. }
  269. void CXTPPropertyGridInplaceMultilineEdit::PostNcDestroy()
  270. {
  271. CXTPMouseMonitor::SetupHook(NULL);
  272. delete this;
  273. }
  274. void CXTPPropertyGridInplaceMultilineEdit::Cancel()
  275. {
  276. if (m_pItem)
  277. {
  278. m_pItem->OnCancelEdit();
  279. m_pItem = NULL;
  280. }
  281. if (m_hWnd && ::GetFocus() == m_hWnd)
  282. {
  283. GetOwner()->SetFocus();
  284. }
  285. }
  286. void CXTPPropertyGridInplaceMultilineEdit::Apply()
  287. {
  288. if (m_pItem)
  289. {
  290. CXTPPropertyGridItem* pItem = m_pItem;
  291. m_pItem = NULL;
  292. CString str;
  293. GetWindowText(str);
  294. if (pItem->OnAfterEdit(str) && str != pItem->GetValue())
  295. pItem->OnValueChanged(str);
  296. }
  297. if (m_hWnd && ::GetFocus() == m_hWnd)
  298. {
  299. GetOwner()->SetFocus();
  300. }
  301. }
  302. void CXTPPropertyGridInplaceMultilineEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  303. {
  304. if (nChar == VK_ESCAPE)
  305. Cancel();
  306. else if (nChar == VK_F4)
  307. Apply();
  308. else if (nChar == VK_RETURN && GetKeyState(VK_CONTROL) < 0)
  309. Apply();
  310. else CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  311. }
  312. void CXTPPropertyGridInplaceMultilineEdit::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  313. {
  314. if (nChar == VK_DOWN || nChar == VK_UP)
  315. {
  316. Apply();
  317. return;
  318. }
  319. CEdit::OnSysKeyDown(nChar, nRepCnt, nFlags);
  320. }