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

对话框与窗口

开发平台:

Visual C++

  1. // XTPMarkupKeyboardNavigation.cpp: implementation of the CXTPMarkupKeyboardNavigation class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO 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 "XTPMarkupFrameworkElement.h"
  22. #include "XTPMarkupInline.h"
  23. #include "XTPMarkupInputElement.h"
  24. #include "XTPMarkupKeyboardNavigation.h"
  25. #include "XTPMarkupContext.h"
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char THIS_FILE[]=__FILE__;
  29. #define new DEBUG_NEW
  30. #endif
  31. CXTPMarkupDependencyProperty* CXTPMarkupKeyboardNavigation::m_pIsTabStopProperty = NULL;
  32. CXTPMarkupDependencyProperty* CXTPMarkupKeyboardNavigation::m_pTabNavigationProperty = NULL;
  33. CXTPMarkupDependencyProperty* CXTPMarkupKeyboardNavigation::m_pTabIndexProperty = NULL;
  34. IMPLEMENT_MARKUPCLASS(L"KeyboardNavigation", CXTPMarkupKeyboardNavigation, CXTPMarkupObject)
  35. void CXTPMarkupKeyboardNavigation::RegisterMarkupClass()
  36. {
  37. m_pIsTabStopProperty = CXTPMarkupDependencyProperty::RegisterAttached(L"IsTabStop", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupKeyboardNavigation),
  38. new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateTrueValue()));
  39. m_pTabNavigationProperty = CXTPMarkupDependencyProperty::RegisterAttached(L"TabNavigation", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupKeyboardNavigation),
  40. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupKeyboardNavigation::ConvertKeyboardNavigationMode));
  41. m_pTabIndexProperty = CXTPMarkupDependencyProperty::RegisterAttached(L"TabIndex", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupKeyboardNavigation),
  42. new CXTPMarkupPropertyMetadata(new CXTPMarkupInt(INT_MAX)));
  43. }
  44. CXTPMarkupKeyboardNavigation::CXTPMarkupKeyboardNavigation(CXTPMarkupContext* pContext)
  45. {
  46. m_pFocused = NULL;
  47. m_pLastFocused = NULL;
  48. m_pMarkupContext = pContext;
  49. }
  50. CXTPMarkupKeyboardNavigation::~CXTPMarkupKeyboardNavigation()
  51. {
  52. MARKUP_RELEASE(m_pFocused);
  53. MARKUP_RELEASE(m_pLastFocused);
  54. }
  55. XTPMarkupKeyboardNavigationMode CXTPMarkupKeyboardNavigation::GetTabNavigation(CXTPMarkupObject* pElement)
  56. {
  57. CXTPMarkupEnum* pValue = MARKUP_STATICCAST(CXTPMarkupEnum, pElement->GetValue(m_pTabNavigationProperty));
  58. return pValue ? (XTPMarkupKeyboardNavigationMode)(int)*pValue : xtpMarkupKeyboardNavigationContinue;
  59. }
  60. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::ConvertKeyboardNavigationMode(CXTPMarkupContext* /*pContext*/, CXTPMarkupObject* pObject)
  61. {
  62. if (IsStringObject(pObject))
  63. {
  64. LPCWSTR lpszValue = *((CXTPMarkupString*)pObject);
  65. int nLength = ((CXTPMarkupString*)pObject)->GetLength();
  66. if (nLength == 8 && _wcsicmp(lpszValue, L"Continue") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationContinue);
  67. if (nLength == 4 && _wcsicmp(lpszValue, L"Once") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationOnce);
  68. if (nLength == 5 && _wcsicmp(lpszValue, L"Cycle") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationCycle);
  69. if (nLength == 4 && _wcsicmp(lpszValue, L"None") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationNone);
  70. if (nLength == 9 && _wcsicmp(lpszValue, L"Contained") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationContained);
  71. if (nLength == 5 && _wcsicmp(lpszValue, L"Local") == 0) return CXTPMarkupEnum::CreateValue(xtpMarkupKeyboardNavigationLocal);
  72. }
  73. return NULL;
  74. }
  75. BOOL CXTPMarkupKeyboardNavigation::OnWndMsg(UINT /*message*/, WPARAM /*wParam*/, LPARAM /*lParam*/, LRESULT* /*pResult*/)
  76. {
  77. // NotImplmeneted
  78. return FALSE;
  79. #if 0
  80. if (message == WM_SETFOCUS)
  81. {
  82. if (m_pLastFocused && !m_pFocused)
  83. {
  84. Focus(m_pLastFocused);
  85. MARKUP_RELEASE(m_pLastFocused);
  86. }
  87. }
  88. if (message == WM_KILLFOCUS)
  89. {
  90. if (m_pFocused)
  91. {
  92. m_pLastFocused = m_pFocused;
  93. MARKUP_ADDREF(m_pLastFocused);
  94. Focus(NULL);
  95. }
  96. }
  97. if (message == WM_KEYDOWN)
  98. {
  99. ProcessInput((UINT)wParam);
  100. }
  101. return FALSE;
  102. #endif
  103. }
  104. BOOL CXTPMarkupKeyboardNavigation::IsInNavigationTree(CXTPMarkupObject* pVisual)
  105. {
  106. CXTPMarkupUIElement* pElement = MARKUP_DYNAMICCAST(CXTPMarkupUIElement, pVisual);
  107. if ((pElement != NULL) && (pElement->IsVisible()))
  108. {
  109. return TRUE;
  110. }
  111. return FALSE;
  112. }
  113. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetParent(CXTPMarkupObject* e)
  114. {
  115. if (!e)
  116. return NULL;
  117. if (e->IsKindOf(MARKUP_TYPE(CXTPMarkupVisual)))
  118. {
  119. CXTPMarkupVisual* reference = ((CXTPMarkupVisual*)e)->GetVisualParent();
  120. while (reference != NULL)
  121. {
  122. if (IsInNavigationTree(reference))
  123. {
  124. return reference;
  125. }
  126. reference = reference->GetVisualParent();
  127. }
  128. }
  129. else if (e->IsKindOf(MARKUP_TYPE(CXTPMarkupFrameworkContentElement)))
  130. {
  131. return (CXTPMarkupObject*)(((CXTPMarkupFrameworkContentElement*)e)->GetParent());
  132. }
  133. return NULL;
  134. }
  135. XTPMarkupKeyboardNavigationMode CXTPMarkupKeyboardNavigation::GetKeyNavigationMode(CXTPMarkupObject* pElement)
  136. {
  137. CXTPMarkupEnum* pValue = MARKUP_STATICCAST(CXTPMarkupEnum, pElement->GetValue(m_pNavigationProperty));
  138. return pValue ? (XTPMarkupKeyboardNavigationMode)(int)*pValue : xtpMarkupKeyboardNavigationContinue;
  139. }
  140. BOOL CXTPMarkupKeyboardNavigation::IsGroup(CXTPMarkupObject* e)
  141. {
  142. return (GetKeyNavigationMode(e) != xtpMarkupKeyboardNavigationContinue);
  143. }
  144. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetGroupParent(CXTPMarkupObject* e, BOOL bIncludeCurrent)
  145. {
  146. CXTPMarkupObject* obj2 = e;
  147. if (!bIncludeCurrent)
  148. {
  149. obj2 = e;
  150. e = GetParent(e);
  151. if (e == NULL)
  152. {
  153. return obj2;
  154. }
  155. }
  156. while (e != NULL)
  157. {
  158. if (IsGroup(e))
  159. {
  160. return e;
  161. }
  162. obj2 = e;
  163. e = GetParent(e);
  164. }
  165. return obj2;
  166. }
  167. BOOL CXTPMarkupKeyboardNavigation::IsTabStopOrGroup(CXTPMarkupObject* e)
  168. {
  169. return IsTabStop(e) || IsGroup(e);
  170. }
  171. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::FocusedElement(CXTPMarkupObject* /*e*/)
  172. {
  173. return NULL;
  174. }
  175. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetTreeFirstChild(CXTPMarkupObject* e)
  176. {
  177. CXTPMarkupObject* obj2 = FocusedElement(e);
  178. if (obj2 != NULL)
  179. {
  180. return obj2;
  181. }
  182. CXTPMarkupUIElement* o = MARKUP_DYNAMICCAST(CXTPMarkupUIElement, e);
  183. if (o != NULL && o->IsVisible())
  184. {
  185. CXTPMarkupVisual* reference = o;
  186. if (reference != NULL)
  187. {
  188. int childrenCount = reference->GetVisualChildrenCount();
  189. for (int i = 0; i < childrenCount; i++)
  190. {
  191. CXTPMarkupVisual* child = reference->GetVisualChild(i);
  192. if (IsInNavigationTree(child))
  193. {
  194. return child;
  195. }
  196. CXTPMarkupObject* firstChild = GetTreeFirstChild(child);
  197. if (firstChild != NULL)
  198. {
  199. return firstChild;
  200. }
  201. }
  202. }
  203. }
  204. return NULL;
  205. }
  206. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetTreeNextSibling(CXTPMarkupObject* e)
  207. {
  208. CXTPMarkupObject* parent = GetParent(e);
  209. {
  210. CXTPMarkupVisual* reference = MARKUP_DYNAMICCAST(CXTPMarkupVisual, parent);
  211. CXTPMarkupObject* obj4 = MARKUP_DYNAMICCAST(CXTPMarkupVisual, e);
  212. if ((reference != NULL) && obj4)
  213. {
  214. int childrenCount = reference->GetVisualChildrenCount();
  215. int childIndex = 0;
  216. while (childIndex < childrenCount)
  217. {
  218. if (reference->GetVisualChild(childIndex) == obj4)
  219. {
  220. break;
  221. }
  222. childIndex++;
  223. }
  224. childIndex++;
  225. while (childIndex < childrenCount)
  226. {
  227. CXTPMarkupObject* child = reference->GetVisualChild(childIndex);
  228. if (IsInNavigationTree(child))
  229. {
  230. return child;
  231. }
  232. childIndex++;
  233. }
  234. }
  235. }
  236. return NULL;
  237. }
  238. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetNextInTree(CXTPMarkupObject* e, CXTPMarkupObject* container)
  239. {
  240. CXTPMarkupObject* firstChild = NULL;
  241. if ((e == container) || !IsGroup(e))
  242. {
  243. firstChild = GetTreeFirstChild(e);
  244. }
  245. if ((firstChild != NULL) || (e == container))
  246. {
  247. return firstChild;
  248. }
  249. CXTPMarkupObject* parent = e;
  250. do
  251. {
  252. CXTPMarkupObject* nextSibling = GetTreeNextSibling(parent);
  253. if (nextSibling != NULL)
  254. {
  255. return nextSibling;
  256. }
  257. parent = GetParent(parent);
  258. }
  259. while ((parent != NULL) && (parent != container));
  260. return NULL;
  261. }
  262. int CXTPMarkupKeyboardNavigation::GetTabIndexHelper(CXTPMarkupObject* d)
  263. {
  264. CXTPMarkupInt* pValue = MARKUP_STATICCAST(CXTPMarkupInt, d->GetValue(m_pTabIndexProperty));
  265. return pValue ? (int)*pValue : INT_MAX;
  266. }
  267. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetFirstTabInGroup(CXTPMarkupObject* container)
  268. {
  269. CXTPMarkupObject* obj2 = NULL;
  270. int num = INT_MIN;
  271. CXTPMarkupObject* e = container;
  272. while ((e = GetNextInTree(e, container)) != NULL)
  273. {
  274. if (IsTabStopOrGroup(e))
  275. {
  276. int tabIndexHelper = GetTabIndexHelper(e);
  277. if ((tabIndexHelper < num) || (obj2 == NULL))
  278. {
  279. num = tabIndexHelper;
  280. obj2 = e;
  281. }
  282. }
  283. }
  284. return obj2;
  285. }
  286. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetNextTabWithSameIndex(CXTPMarkupObject* e, CXTPMarkupObject* container)
  287. {
  288. int tabIndexHelper = GetTabIndexHelper(e);
  289. CXTPMarkupObject* obj2 = e;
  290. while ((obj2 = GetNextInTree(obj2, container)) != NULL)
  291. {
  292. if (IsTabStopOrGroup(obj2) && (GetTabIndexHelper(obj2) == tabIndexHelper))
  293. {
  294. return obj2;
  295. }
  296. }
  297. return NULL;
  298. }
  299. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetNextTabWithNextIndex(CXTPMarkupObject* e, CXTPMarkupObject* container, XTPMarkupKeyboardNavigationMode tabbingType)
  300. {
  301. CXTPMarkupObject* obj2 = NULL;
  302. CXTPMarkupObject* obj3 = NULL;
  303. int num = INT_MIN;
  304. int num2 = INT_MIN;
  305. int tabIndexHelper = GetTabIndexHelper(e);
  306. CXTPMarkupObject* obj4 = container;
  307. while ((obj4 = GetNextInTree(obj4, container)) != NULL)
  308. {
  309. if (IsTabStopOrGroup(obj4))
  310. {
  311. int num4 = GetTabIndexHelper(obj4);
  312. if ((num4 > tabIndexHelper) && ((num4 < num2) || (obj2 == NULL)))
  313. {
  314. num2 = num4;
  315. obj2 = obj4;
  316. }
  317. if ((num4 < num) || (obj3 == NULL))
  318. {
  319. num = num4;
  320. obj3 = obj4;
  321. }
  322. }
  323. }
  324. if ((tabbingType == xtpMarkupKeyboardNavigationCycle) && (obj2 == NULL))
  325. {
  326. obj2 = obj3;
  327. }
  328. return obj2;
  329. }
  330. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetNextTabInGroup(CXTPMarkupObject* e, CXTPMarkupObject* container, XTPMarkupKeyboardNavigationMode tabbingType)
  331. {
  332. if (tabbingType == xtpMarkupKeyboardNavigationNone)
  333. {
  334. return NULL;
  335. }
  336. if ((e == NULL) || (e == container))
  337. {
  338. return GetFirstTabInGroup(container);
  339. }
  340. if (tabbingType == xtpMarkupKeyboardNavigationOnce)
  341. {
  342. return NULL;
  343. }
  344. CXTPMarkupObject* nextTabWithSameIndex = GetNextTabWithSameIndex(e, container);
  345. if (nextTabWithSameIndex != NULL)
  346. {
  347. return nextTabWithSameIndex;
  348. }
  349. return GetNextTabWithNextIndex(e, container, tabbingType);
  350. }
  351. AFX_INLINE BOOL GetBoolValue(CXTPMarkupObject* e, CXTPMarkupDependencyProperty* p)
  352. {
  353. CXTPMarkupBool* pValue = MARKUP_STATICCAST(CXTPMarkupBool, e->GetValue(p));
  354. return pValue ? (BOOL)*pValue : FALSE;
  355. }
  356. BOOL CXTPMarkupKeyboardNavigation::IsTabStop(CXTPMarkupObject* e)
  357. {
  358. if (e->IsKindOf(MARKUP_TYPE(CXTPMarkupFrameworkElement)))
  359. {
  360. CXTPMarkupFrameworkElement* pElement = (CXTPMarkupFrameworkElement*)e;
  361. return pElement->IsFocusable() && GetBoolValue(pElement, m_pIsTabStopProperty) && pElement->IsEnabled() && pElement->IsVisible();
  362. }
  363. else if (e->IsKindOf(MARKUP_TYPE(CXTPMarkupFrameworkContentElement)))
  364. {
  365. return FALSE;
  366. }
  367. return FALSE;
  368. }
  369. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetTabOnceActiveElement(CXTPMarkupObject* /*d*/)
  370. {
  371. return NULL;
  372. }
  373. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetActiveElement(CXTPMarkupObject* d)
  374. {
  375. return GetTabOnceActiveElement(d);
  376. }
  377. CXTPMarkupObject* CXTPMarkupKeyboardNavigation::GetNextTab(CXTPMarkupObject* e, CXTPMarkupObject* pContainer, BOOL goDownOnly)
  378. {
  379. XTPMarkupKeyboardNavigationMode keyNavigationMode = GetKeyNavigationMode(pContainer);
  380. if (e == NULL)
  381. {
  382. if (IsTabStop(pContainer))
  383. {
  384. return pContainer;
  385. }
  386. CXTPMarkupObject* pActiveElement = GetActiveElement(pContainer);
  387. if (pActiveElement)
  388. {
  389. return GetNextTab(NULL, pActiveElement, TRUE);
  390. }
  391. }
  392. else if (((keyNavigationMode == xtpMarkupKeyboardNavigationOnce) || (keyNavigationMode == xtpMarkupKeyboardNavigationNone)) && (pContainer != e))
  393. {
  394. if (goDownOnly)
  395. {
  396. return NULL;
  397. }
  398. CXTPMarkupObject* groupParent = GetGroupParent(pContainer);
  399. return GetNextTab(pContainer, groupParent, goDownOnly);
  400. }
  401. CXTPMarkupObject* obj4 = NULL;
  402. CXTPMarkupObject* obj5 = e;
  403. XTPMarkupKeyboardNavigationMode tabbingType = keyNavigationMode;
  404. while ((obj5 = GetNextTabInGroup(obj5, pContainer, tabbingType)) != NULL)
  405. {
  406. if (obj4 == obj5)
  407. {
  408. break;
  409. }
  410. if (obj4 == NULL)
  411. {
  412. obj4 = obj5;
  413. }
  414. CXTPMarkupObject* obj6 = GetNextTab(NULL, obj5, TRUE);
  415. if (obj6 != NULL)
  416. {
  417. return obj6;
  418. }
  419. if (tabbingType == xtpMarkupKeyboardNavigationOnce)
  420. {
  421. tabbingType = xtpMarkupKeyboardNavigationContained;
  422. }
  423. }
  424. if ((!goDownOnly && (tabbingType != xtpMarkupKeyboardNavigationContained)) && (GetParent(pContainer) != NULL))
  425. {
  426. return GetNextTab(pContainer, GetGroupParent(pContainer), FALSE);
  427. }
  428. return NULL;
  429. }
  430. void CXTPMarkupKeyboardNavigation::Navigate(CXTPMarkupInputElement* pCurrentElement, XTPMarkupFocusNavigationDirection direction)
  431. {
  432. CXTPMarkupObject* pNextInDirection = NULL;
  433. switch (direction)
  434. {
  435. case xtpMarkupFocusNavigationDirectionNext:
  436. m_pNavigationProperty = m_pTabNavigationProperty;
  437. pNextInDirection = GetNextTab(pCurrentElement, GetGroupParent(pCurrentElement, TRUE), FALSE);
  438. break;
  439.    /*case xtpMarkupFocusNavigationDirectionPrevious:
  440. m_pNavigationProperty = m_pTabNavigationProperty;
  441. pNextInDirection = GetPrevTab(pCurrentElement, NULL, FALSE);
  442. break;*/
  443. }
  444. if (pNextInDirection != NULL)
  445. {
  446. if (pNextInDirection->IsKindOf(MARKUP_TYPE(CXTPMarkupInputElement)))
  447. {
  448. ((CXTPMarkupInputElement*)pNextInDirection)->Focus();
  449. }
  450. }
  451. }
  452. void CXTPMarkupKeyboardNavigation::Navigate(CXTPMarkupInputElement* pSourceElement, UINT nChar)
  453. {
  454. if (nChar == VK_TAB)
  455. {
  456. Navigate(pSourceElement, (::GetKeyState(VK_SHIFT) & 0x8000) == 0 ? xtpMarkupFocusNavigationDirectionNext : xtpMarkupFocusNavigationDirectionPrevious);
  457. }
  458. }
  459. void CXTPMarkupKeyboardNavigation::ProcessInput(UINT nChar)
  460. {
  461. if (!m_pFocused)
  462. return;
  463. if (nChar == VK_TAB)
  464. {
  465. Navigate(m_pFocused, nChar);
  466. }
  467. }
  468. void CXTPMarkupKeyboardNavigation::Focus(CXTPMarkupInputElement* /*pInputElement*/)
  469. {
  470. // NotImplmeneted
  471. return;
  472. #if 0
  473. if (!m_pMarkupContext->m_hContextWnd)
  474. return;
  475. if (m_pFocused == pInputElement)
  476. return;
  477. if (m_pFocused)
  478. {
  479. m_pFocused->SetValue(CXTPMarkupInputElement::m_pIsKeyboardFocusedProperty, NULL);
  480. MARKUP_RELEASE(m_pFocused);
  481. }
  482. m_pFocused = pInputElement;
  483. if (m_pFocused)
  484. {
  485. m_pFocused->SetValue(CXTPMarkupInputElement::m_pIsKeyboardFocusedProperty, CXTPMarkupBool::CreateTrueValue());
  486. MARKUP_ADDREF(m_pFocused);
  487. ::SetFocus(m_pMarkupContext->m_hContextWnd);
  488. }
  489. #endif
  490. }