UIElement* UIElement::FindCommonAncestor(UIElement* element1) { UIElement* element0 = this; // mark phase for (UIElement* p = element0; p != nullptr; p = p->get_Parent()) { EnterCriticalSection(p->m_markedSection); p->m_marked = true; } UIElement* commonAncestor = nullptr; for (UIElement* p = element1; p != nullptr; p = p->get_Parent()) { if (p->m_marked) { commonAncestor = p; break; } } // unmark for (UIElement* p = element0; p != nullptr; p = p->get_Parent()) { p->m_marked = false; LeaveCriticalSection(p->m_markedSection); } return commonAncestor; }
void UIElement::RaiseEvent(RoutedEventArgs* args) { args->m_originalSource = this; RoutedEvent* routedEvent = args->get_RoutedEvent(); if (routedEvent == NULL) { raise(SystemException("routedEvent = NULL")); } // preview phase if (routedEvent->get_RoutingStrategy() == RoutingStrategy_Tunnel) { #if 0 EventRoute route; UIElement* p = this;//dynamic_cast<UIElement*>(GetRParent()); while (p) { route.ancestors.push_front(p); p = dynamic_cast<UIElement*>(p->GetRParent()); } list<UIElement*>::iterator it = route.ancestors.begin(); while (it != route.ancestors.end()) { UIElement* el = *it; // Class handlers if (!args->get_Handled()) // TODO { EventManager::InvokeClassHandlers(el/*args->get_Source()*/->GetType(), el, args); } // Instance handlers signal_base* sig = el->m_handlers[routedEvent->m_index]; if (sig) { int nslots = sig->GetSlotCount(); // signal2<Object*,RoutedEventArgs*>::connection_type it2 = el->m_handlers[routedEvent->m_index]->m_slots.begin(); // while (it2 != el->m_handlers[routedEvent->m_index]->m_slots.end()) for (int i = 0; i < nslots; i++) { stub_interface_base* slot = sig->GetSlot(i); if (!args->get_Handled()) // TODO { args->InvokeEventHandler(this, slot); } // ++it2; } } ++it; } #endif } else if (routedEvent->get_RoutingStrategy() == RoutingStrategy_Bubble) { EventRoute route; UIElement* p = this; do { route.ancestors.push_back(p); p = p->get_Parent(); } while (p); if (args->get_Source() == nullptr) { args->set_Source(this); } for (auto it = route.ancestors.begin(); it != route.ancestors.end(); ++it) { UIElement* el = *it; // Class handlers if (!args->get_Handled()) // TODO { EventManager::InvokeClassHandlers(el->GetType(), el, args); } // Instance handlers Event* pEvent = el->m_events[routedEvent->GetIndex()]; if (pEvent) { try { switch (pEvent->get_NumArgs()) { case 2: { pEvent->Handle(el, args); } break; default: ASSERT(0); } } catch (Exception* e) { MessageBox(nullptr, e->get_Reason().c_strw(), L"GUI", MB_OK | MB_ICONERROR); } } args->set_Source(el); #if 0 list<IDispatch*>::iterator it = pEvent->m_handlers.begin(); while (it != pEvent->m_handlers.end()) { IDispatch* handler = *it; ++it; if (!args->get_Handled()) // TODO { args->InvokeEventHandler(this, handler); } } /* int nslots = el->m_handlers[routedEvent->m_index]->GetSlotCount(); signal2<Object*,RoutedEventArgs*>::connection_type it2 = el->m_handlers[routedEvent->m_index].m_slots.begin(); while (it2 != el->m_handlers[routedEvent->m_index].m_slots.end()) { args->InvokeEventHandler(this, *it2); ++it2; } */ } #endif } }
void PlatformWindowSite::OnMouseMove(gm::PointF clientMousePos) { POINT screenMousePos; ::GetCursorPos(&screenMousePos); UIElement* hitElement = nullptr; if (m_MouseCaptureElement) { hitElement = m_MouseCaptureElement; } else { //Visual* child = get_Child(); UIElement* child = GetRootElement(); if (child) { hitElement = child->HitTest_(clientMousePos); } } if (m_MouseOverElement != hitElement) { // Find common ancestor UIElement* commonAncestor = m_MouseOverElement->FindCommonAncestor(hitElement); // ASSERT(commonAncestor); for (UIElement* p = m_MouseOverElement; p != commonAncestor; p = p->get_Parent()) { p->set_IsMouseOver(false); } for (UIElement* p = hitElement; p != commonAncestor; p = p->get_Parent()) { p->set_IsMouseOver(true); } if (m_MouseOverElement) { m_MouseOverElement->set_IsMouseDirectlyOver(false); } m_MouseOverElement = hitElement; if (m_MouseOverElement) { m_MouseOverElement->set_IsMouseDirectlyOver(true); } } if (hitElement) { MouseEventArgs* args = new MouseEventArgs(nullptr, 0); args->set_RoutedEvent(UIElement::get_MouseMoveEvent()); args->m_screenpos = Point(float(screenMousePos.x), float(screenMousePos.y)); args->m_clientpos = clientMousePos; hitElement->RaiseEvent(args); } }