[CONNECT C++] DgnElementSetTool::_DoLocate

MicroStationAPI tool class DgnElementSetTool provides method _DoLocate...

HitPathCP  _DoLocate (DgnButtonEventCR ev, bool newSearch, ComponentMode complexComponent) 

The last argument complexComponent is unclear. It's documented like this...

enum ComponentMode

Innermost Set cursor index to head of path (0)
NormalChild Set cursor index to last entry in path (-1)
SharedChild Set cursor index to innermost public component of a complex element (same as None if no normal cells in path)

Those parenthesised values puzzle me.  Note that there's no documentation for value None.

Here's the definition of that enum in \DgnPlatform\Locate.h...

enum class ComponentMode
    {
    None            = 0, //! Set cursor index to head of path (0).
    Innermost       = 1, //! Set cursor index to last entry in path (-1).
    NormalChild     = 3, //! Set cursor index to innermost public component of a complex element (same as None if no normal cells in path)...
    SharedChild     = 4, //! Set cursor index to innermost public shared component (same as NormalChild if no shared cells in path)...
    };
  1. Value None is commented Set cursor index to head of path.  But the documentation tells us that's the purpose of Innermost.
  2. What is Innermost trying to tell us?  It's value is 1 but documented as 0 and commented as -1!
  3. What is NormalChild trying to tell us?  It's value is 3 but documented as -1!
  • Here's the code that ends up being called to set the path index...

    void ElementLocateManager::SetPathIndex (HitPathP hit, ComponentMode complexComponent)
    {
    if (NULL == hit)
    return;

    int index = 0;

    switch (complexComponent)
    {
    case ComponentMode::None: // outermost complex header
    {
    index = 0;
    break;
    }

    case ComponentMode::Innermost: // last element in path
    {
    index = -1;
    break;
    }

    case ComponentMode::InnermostHeader: // innermost complex header
    {
    ElementRefP elem;

    for (int i=0; elem = hit->GetPathElem (i); i++)
    {
    if (NULL == elem)
    break;

    if (elem->IsComplexHeader ())
    index = i;
    }
    break;
    }

    case ComponentMode::NormalChild: // innermost public component
    {
    index = hit->GetPathIndex (hit->GetChildElem ());
    break;
    }

    case ComponentMode::SharedChild: // innermost public component (allow components of shared cell definitions)
    {
    index = hit->GetPathIndex (hit->GetSharedChildElem ());
    break;
    }
    }

    hit->SetCursorIndex (index);
    hit->SetComponentMode (ComponentMode::Innermost == complexComponent); // Set component mode for flashing of extended elements...
    }

    ElementRefP DisplayPath::GetChildElem (ExposeChildrenReason reason) const
    {
    if (m_path.empty ())
    return NULL;

    ElementRefP innerRef = NULL;

    for (DgnElemRefArray::const_iterator curr = m_path.begin (); curr != m_path.end (); ++curr)
    {
    ElementHandle eh (innerRef = (ElementRefP) *curr);

    // Quit at the first element that doesn't expose components...
    if (!eh.IsValid () || !eh.GetHandler ().ExposeChildren (eh, reason))
    break;
    }

    return innerRef;
    }

    ElementRefP DisplayPath::GetSharedChildElem (ExposeChildrenReason reason) const
    {
    if (m_path.empty ())
    return NULL;

    ElementRefP innerRef = NULL;

    for (DgnElemRefArray::const_iterator curr = m_path.begin (); curr != m_path.end (); ++curr)
    {
    ElementHandle eh (innerRef = (ElementRefP) *curr);

    if (!eh.IsValid ())
    break;

    if (eh.GetHandler ().ExposeChildren (eh, reason))
    continue;

    ISharedCellQuery* scQuery;

    // Quit at the first element that doesn't expose components that isn't a shared cell instance...
    if (NULL == (scQuery = dynamic_cast <ISharedCellQuery*> (&eh.GetHandler ())) || !scQuery->IsSharedCell (eh))
    break;
    }

    return innerRef;
    }



    Answer Verified By: Jon Summers