// XTPMarkupInputElement.cpp: implementation of the CXTPMarkupInputElement class. // // This file is a part of the XTREME TOOLKIT PRO MFC class library. // (c)1998-2012 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "XTPMarkupObject.h" #include "XTPMarkupInputElement.h" #include "XTPMarkupContext.h" #include "XTPMarkupBuilder.h" #include "XTPMarkupUIElement.h" #include "XTPMarkupResourceDictionary.h" #include "XTPMarkupKeyboardNavigation.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////////// // CXTPMarkupRoutedEvent CXTPMarkupRoutedEvent::CXTPMarkupRoutedEvent() { } CXTPMarkupRoutedEvent* CXTPMarkupRoutedEvent::RegisterRoutedEvent(LPCWSTR lpszName, RoutingStrategy routingStrategy, CXTPMarkupType* pOwnerType) { CXTPMarkupRoutedEvent* pEvent = (CXTPMarkupRoutedEvent*)RegisterCommon(new CXTPMarkupRoutedEvent(), lpszName, MARKUP_TYPE(CXTPMarkupString), pOwnerType, FALSE); if (routingStrategy != routingDirect) { pEvent->m_pMetadata = new CXTPMarkupPropertyMetadata(NULL, routingStrategy); } return pEvent; } ////////////////////////////////////////////////////////////////////////// // CXTPMarkupRoutedEventArgs CXTPMarkupRoutedEventArgs::CXTPMarkupRoutedEventArgs(CXTPMarkupRoutedEvent* pEvent, CXTPMarkupObject* pSource) { m_pSource = pSource; m_pEvent = pEvent; m_bHandled = FALSE; } CXTPMarkupRoutedEventArgs::CXTPMarkupRoutedEventArgs() { m_pSource = NULL; m_pEvent = NULL; m_bHandled = FALSE; } CXTPMarkupMouseEventArgs::CXTPMarkupMouseEventArgs(CXTPMarkupRoutedEvent* pEvent) : CXTPMarkupRoutedEventArgs(pEvent, NULL) { m_hWnd = 0; m_point = 0; } CPoint CXTPMarkupMouseEventArgs::GetPosition(CXTPMarkupInputElement* relativeTo) { CPoint pt = m_point; CXTPMarkupObject* pVisual = relativeTo; while (pVisual != 0) { if (pVisual->IsKindOf(MARKUP_TYPE(CXTPMarkupVisual))) { pt -= ((CXTPMarkupVisual*)pVisual)->GetVisualOffset(); } pVisual = pVisual->GetLogicalParent(); } return pt; } CXTPMarkupMouseButtonEventArgs::CXTPMarkupMouseButtonEventArgs(CXTPMarkupRoutedEvent* pEvent) : CXTPMarkupMouseEventArgs(pEvent) { } CXTPMarkupQueryCursorEventArgs::CXTPMarkupQueryCursorEventArgs() : CXTPMarkupMouseEventArgs(NULL) { } CXTPMarkupMouseWheelEventArgs::CXTPMarkupMouseWheelEventArgs() : CXTPMarkupMouseEventArgs(NULL) { } ////////////////////////////////////////////////////////////////////////// // CXTPMarkupEventHandlerMap CXTPMarkupEventHandlerMap::CXTPMarkupEventHandlerMap() { } CXTPMarkupEventHandlerMap::~CXTPMarkupEventHandlerMap() { RemoveAll(); } void CXTPMarkupEventHandlerMap::RemoveAll() { POSITION pos = m_mapHandlers.GetStartPosition(); while (pos) { CPtrList* pHandlers; CXTPMarkupRoutedEvent* pEvent; m_mapHandlers.GetNextAssoc(pos, pEvent, pHandlers); while (!pHandlers->IsEmpty()) { CXTPMarkupDelegate* pDelegate = (CXTPMarkupDelegate*)pHandlers->RemoveTail(); MARKUP_RELEASE(pDelegate); } delete pHandlers; } m_mapHandlers.RemoveAll(); } void CXTPMarkupEventHandlerMap::Add(CXTPMarkupRoutedEvent* pEvent, CXTPMarkupDelegate* pDelegate) { CPtrList* pHandlers; if (!m_mapHandlers.Lookup(pEvent, pHandlers)) { pHandlers = new CPtrList(); m_mapHandlers.SetAt(pEvent, pHandlers); } pHandlers->AddTail(pDelegate); } void CXTPMarkupEventHandlerMap::Raise(CXTPMarkupObject* pSender, CXTPMarkupRoutedEventArgs* pEventArgs) { CPtrList* pHandlers; if (!m_mapHandlers.Lookup(pEventArgs->GetEvent(), pHandlers)) return; POSITION pos = pHandlers->GetHeadPosition(); while (pos) { CXTPMarkupDelegate* pDelegate = (CXTPMarkupDelegate*)pHandlers->GetNext(pos); pDelegate->Execute(pSender, pEventArgs); } } ////////////////////////////////////////////////////////////////////////// // CXTPMarkupInputElement CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pCursorProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pIsMouseOverProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pIsKeyboardFocusedProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pResourcesProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pStyleProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pIsFocusableProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupInputElement::m_pToolTipProperty = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseLeaveEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseEnterEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseLeftButtonUpEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseLeftButtonDownEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseRightButtonUpEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseRightButtonDownEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pMouseMoveEvent = NULL; CXTPMarkupRoutedEvent* CXTPMarkupInputElement::m_pLostMouseCaptureEvent = NULL; IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupInputElement, CXTPMarkupObject); void CXTPMarkupInputElement::RegisterMarkupClass() { CXTPMarkupStyle::RegisterType(); m_pCursorProperty = CXTPMarkupDependencyProperty::Register(L"Cursor", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupInputElement), new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertCursor, &CXTPMarkupInputElement::OnCursorPropertyChanged)); m_pIsMouseOverProperty = CXTPMarkupDependencyProperty::Register(L"IsMouseOver", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupInputElement), new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateFalseValue())); m_pResourcesProperty = CXTPMarkupStyle::m_pResourcesProperty->AddOwner(MARKUP_TYPE(CXTPMarkupInputElement)); m_pStyleProperty = CXTPMarkupDependencyProperty::Register(L"Style", MARKUP_TYPE(CXTPMarkupStyle), MARKUP_TYPE(CXTPMarkupInputElement), new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupInputElement::OnStylePropertyChanged)); m_pIsKeyboardFocusedProperty = CXTPMarkupDependencyProperty::Register(L"IsKeyboardFocused", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupInputElement), new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateFalseValue(), CXTPMarkupPropertyMetadata::flagAffectsRender)); m_pIsFocusableProperty = CXTPMarkupDependencyProperty::Register(L"IsFocusable", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupInputElement), new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateFalseValue())); m_pToolTipProperty = CXTPMarkupDependencyProperty::Register(L"ToolTip", MARKUP_TYPE(CXTPMarkupObject), MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseLeaveEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseLeave", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseEnterEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseEnter", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseLeftButtonUpEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseLeftButtonUp", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseLeftButtonDownEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseLeftButtonDown", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseRightButtonUpEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseRightButtonUp", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseRightButtonDownEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseRightButtonDown", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pMouseMoveEvent = CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"MouseMove", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); m_pLostMouseCaptureEvent= CXTPMarkupRoutedEvent::RegisterRoutedEvent(L"LostMouseCapture", CXTPMarkupRoutedEvent::routingDirect, MARKUP_TYPE(CXTPMarkupInputElement)); } CXTPMarkupInputElement::CXTPMarkupInputElement() { m_pMarkupContext = NULL; m_pHandlers = NULL; m_pActiveTriggers = NULL; m_pTriggerProperties = NULL; m_pStyleCache = NULL; } CXTPMarkupInputElement::~CXTPMarkupInputElement() { SAFE_DELETE(m_pHandlers); MARKUP_RELEASE(m_pActiveTriggers); MARKUP_RELEASE(m_pTriggerProperties); } void CXTPMarkupInputElement::OnMouseLeave(CXTPMarkupMouseEventArgs* /*e*/) { SetValue(m_pIsMouseOverProperty, NULL); } void CXTPMarkupInputElement::OnMouseEnter(CXTPMarkupMouseEventArgs* /*e*/) { SetValue(m_pIsMouseOverProperty, CXTPMarkupBool::CreateTrueValue()); } void CXTPMarkupInputElement::OnMouseMove(CXTPMarkupMouseEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnQueryCursor(CXTPMarkupQueryCursorEventArgs* e) { CXTPMarkupInt* pCursor = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_pCursorProperty)); if (pCursor) { e->SetHandled(); e->m_hCursor = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE((int)*pCursor)); } } void CXTPMarkupInputElement::OnMouseWheel(CXTPMarkupMouseWheelEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnMouseLeftButtonUp(CXTPMarkupMouseButtonEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnMouseRightButtonUp(CXTPMarkupMouseButtonEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnMouseLeftButtonDown(CXTPMarkupMouseButtonEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnMouseRightButtonDown(CXTPMarkupMouseButtonEventArgs* /*e*/) { } void CXTPMarkupInputElement::OnLostMouseCapture(CXTPMarkupMouseEventArgs* /*e*/) { } void CXTPMarkupInputElement::SetToolTip(LPCTSTR lpszTooltip) { SetValue(m_pToolTipProperty, new CXTPMarkupString(lpszTooltip)); } void CXTPMarkupInputElement::RaiseEvent(CXTPMarkupRoutedEventArgs* pEventArgs) { if (pEventArgs->GetEvent() == NULL) { ASSERT(FALSE); return; } if (pEventArgs->GetEvent()->GetFlags() & CXTPMarkupRoutedEvent::routingBubble) { CXTPMarkupObject* pParent = this; while (pParent) { if (pParent->IsKindOf(MARKUP_TYPE(CXTPMarkupInputElement))) { CXTPMarkupEventHandlerMap* pHandlers = ((CXTPMarkupInputElement*)pParent)->m_pHandlers; if (pHandlers) pHandlers->Raise(pParent, pEventArgs); if (pEventArgs->IsHandled()) return; } pParent = pParent->GetLogicalParent(); } CXTPMarkupContext* pMarkupContext = GetMarkupContext(); if (pMarkupContext) { pMarkupContext->RaiseEvent(this, pEventArgs); } } else { if (m_pHandlers) m_pHandlers->Raise(this, pEventArgs); } } void CXTPMarkupInputElement::AddHandler(CXTPMarkupRoutedEvent* pEvent, CXTPMarkupDelegate* pDelegate) { if (m_pHandlers == NULL) m_pHandlers = new CXTPMarkupEventHandlerMap(); m_pHandlers->Add(pEvent, pDelegate); } CXTPMarkupInputElement* CXTPMarkupInputElement::InputHitTest(CPoint /*point*/) const { return NULL; } void CXTPMarkupInputElement::SetPropertyObject(CXTPMarkupBuilder* pBuilder, CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pValue) { if (pProperty->IsEvent()) { CXTPMarkupContext* pMarkupContext = GetMarkupContext(); if (!pMarkupContext) { pBuilder->ThrowBuilderException(_T("Markup Context is NULL")); } LPCWSTR lpszDelegate = (LPCWSTR)*((CXTPMarkupString*)pValue); CXTPMarkupDelegate* pDelegate = pMarkupContext->LookupDelegate(lpszDelegate); if (!pDelegate) { pBuilder->ThrowBuilderException(CXTPMarkupBuilder::FormatString(_T("'%ls' delegate not found"), (LPCTSTR)lpszDelegate)); } AddHandler((CXTPMarkupRoutedEvent*)pProperty, pDelegate); MARKUP_RELEASE(pValue); MARKUP_ADDREF(pDelegate); return; } CXTPMarkupObject::SetPropertyObject(pBuilder, pProperty, pValue); } void CXTPMarkupInputElement::OnFinalRelease() { if (NULL != m_pMarkupContext) { m_pMarkupContext->FinalizeMarkupObject(this); } CXTPMarkupObject::OnFinalRelease(); } void CXTPMarkupInputElement::CaptureMouse() { m_pMarkupContext->CaptureMouse(this); } void CXTPMarkupInputElement::ReleaseMouseCapture() { m_pMarkupContext->ReleaseMouseCapture(this); } void CXTPMarkupInputElement::ApplyTree(CXTPMarkupObject* pChild) { int nCount = pChild->GetLogicalChildrenCount(); for (int i = 0; i < nCount; i++) { CXTPMarkupObject* p = pChild->GetLogicalChild(i); ApplyTree(p); } if (pChild->IsKindOf(MARKUP_TYPE(CXTPMarkupInputElement))) { ((CXTPMarkupInputElement*)pChild)->OnApply(); } } void CXTPMarkupInputElement::Apply() { ApplyTree(this); } CXTPMarkupObject* CXTPMarkupInputElement::FindResource(const CXTPMarkupObject* pKey) const { return CXTPMarkupResourceDictionary::FindResource(this, pKey); } void CXTPMarkupInputElement::OnApply() { if (m_pStyleCache == NULL) { CXTPMarkupType* pType = GetType(); if (!pType) return; CXTPMarkupStyle* pStyle = MARKUP_DYNAMICCAST(CXTPMarkupStyle, FindResource(pType)); if (pStyle) { pStyle->Seal(); m_pStyleCache = pStyle; } } if (m_pStyleCache != NULL) { FireTriggers(NULL, NULL); } } class CXTPMarkupActiveTriggerCollection : public CXTPMarkupTriggerCollection { public: CXTPMarkupActiveTriggerCollection() { m_bLogicalParent = FALSE; } }; BOOL CXTPMarkupInputElement::AddStyleTriggers(CXTPMarkupStyle* pStyle, CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pNewValue) { BOOL bChanged = FALSE; CXTPMarkupStyle* pBasedStyle = pStyle->GetBasedStyle(); if (pBasedStyle) { bChanged = AddStyleTriggers(pBasedStyle, pProperty, pNewValue); } CXTPMarkupTriggerCollection* pTriggers = pStyle->GetTriggers(); if (!pTriggers) return bChanged; BOOL bAllProperties = (pProperty == NULL); for (int i = pTriggers->GetCount() - 1; i >= 0; i--) { CXTPMarkupTrigger* pTrigger = pTriggers->GetItem(i); if (bAllProperties) { pProperty = pTrigger->GetTriggerProperty(); pNewValue = GetValue(pProperty); } if (pTrigger->GetTriggerProperty() == pProperty && pTrigger->GetTriggerValue()->IsEqual(pNewValue)) { if (!m_pActiveTriggers) { m_pActiveTriggers = new CXTPMarkupActiveTriggerCollection(); } pTrigger->AddRef(); m_pActiveTriggers->Add(pTrigger); bChanged = TRUE; } } return bChanged; } void CXTPMarkupInputElement::FireTriggers(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pNewValue) { BOOL bChanged = FALSE; int i; CMap mapOldValues; if (m_pActiveTriggers) { for (i = m_pActiveTriggers->GetCount() - 1; i >= 0; i--) { CXTPMarkupTrigger* pTrigger = m_pActiveTriggers->GetItem(i); if (pTrigger->GetTriggerProperty() == pProperty) { if (!pTrigger->GetTriggerValue()->IsEqual(pNewValue)) { CXTPMarkupSetterColection* pSetters = pTrigger->GetSetters(); for (int j = 0; j < pSetters->GetCount(); j++) { CXTPMarkupSetter* pSetter = pSetters->GetItem(j); CXTPMarkupDependencyProperty* pSetterProperty = pSetter->GetSetterProperty(); CXTPMarkupObject* pOldValue = m_pTriggerProperties->Lookup(pSetterProperty); CXTPMarkupObject* pTempValue; if (!mapOldValues.Lookup(pSetterProperty, pTempValue)) { MARKUP_ADDREF(pOldValue); mapOldValues.SetAt(pSetterProperty, pOldValue); } m_pTriggerProperties->Set(pSetterProperty, NULL); } m_pActiveTriggers->Remove(i); bChanged = TRUE; } } } } if (m_pStyleCache) { bChanged = AddStyleTriggers(m_pStyleCache, pProperty, pNewValue) || bChanged; } else if (GetType()->GetTypeStyle()) { bChanged = AddStyleTriggers(GetType()->GetTypeStyle(), pProperty, pNewValue) || bChanged; } if (bChanged) { if (!m_pTriggerProperties) m_pTriggerProperties = new CXTPMarkupProperties(NULL); for (i = 0; i < m_pActiveTriggers->GetCount(); i++) { CXTPMarkupTrigger* pTrigger = m_pActiveTriggers->GetItem(i); CXTPMarkupSetterColection* pSetters = pTrigger->GetSetters(); for (int j = 0; j < pSetters->GetCount(); j++) { CXTPMarkupSetter* pSetter = pSetters->GetItem(j); CXTPMarkupObject* pValue = pSetter->GetSetterValue(); CXTPMarkupDependencyProperty* pSetterProperty = pSetter->GetSetterProperty(); CXTPMarkupObject* pOldValue = m_pTriggerProperties->Lookup(pSetterProperty); if (!pValue->IsEqual(pOldValue)) { CXTPMarkupObject* pTempValue; if (!mapOldValues.Lookup(pSetterProperty, pTempValue)) { MARKUP_ADDREF(pOldValue); mapOldValues.SetAt(pSetterProperty, pOldValue); } pValue->AddRef(); m_pTriggerProperties->Set(pSetterProperty, pValue); } } } } POSITION pos = mapOldValues.GetStartPosition(); while (pos) { CXTPMarkupDependencyProperty* pProperty; CXTPMarkupObject* pOldValue; mapOldValues.GetNextAssoc(pos, pProperty, pOldValue); CXTPMarkupObject* pNewValue = m_pTriggerProperties->Lookup(pProperty); if (!::IsEqual(pNewValue, pOldValue)) { OnPropertyChanged(pProperty, pOldValue, pNewValue); if (pProperty->GetFlags() & CXTPMarkupPropertyMetadata::flagInherited) { RecursePropertyChanged(pProperty, pOldValue, pNewValue); } } MARKUP_RELEASE(pOldValue); } } void CXTPMarkupInputElement::OnCursorPropertyChanged(CXTPMarkupObject* d, CXTPMarkupPropertyChangedEventArgs* /*e*/) { CXTPMarkupInputElement* pElement = MARKUP_DYNAMICCAST(CXTPMarkupInputElement, d); if (!pElement) { ASSERT(FALSE); return; } pElement->GetMarkupContext()->HandleSetCursor(); } void CXTPMarkupInputElement::OnStylePropertyChanged(CXTPMarkupObject* d, CXTPMarkupPropertyChangedEventArgs* e) { CXTPMarkupInputElement* pElement = MARKUP_DYNAMICCAST(CXTPMarkupInputElement, d); if (!pElement) { ASSERT(FALSE); return; } CXTPMarkupStyle* pStyle = MARKUP_STATICCAST(CXTPMarkupStyle, e->m_pNewValue); if (pStyle) { pStyle->Seal(); } pElement->m_pStyleCache = pStyle; } CXTPMarkupObject* CXTPMarkupInputElement::GetValueCore(CXTPMarkupDependencyProperty* pProperty) const { CXTPMarkupObject* pValue = CXTPMarkupObject::GetValueCore(pProperty); if (pValue) return pValue; if (m_pTriggerProperties) { pValue = m_pTriggerProperties->Lookup(pProperty); if (pValue) return pValue; } if (m_pStyleCache) { pValue = m_pStyleCache->GetStyleValue(pProperty); if (pValue) return pValue; } CXTPMarkupStyle* pTypeStyle = GetType()->GetTypeStyle(); if (pTypeStyle) return pTypeStyle->GetStyleValue(pProperty); return NULL; } void CXTPMarkupInputElement::Focus() { if (!m_pMarkupContext) return; m_pMarkupContext->GetKeyboardNavigation()->Focus(this); }