//------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors // primary ctor used to create all providers for IAccessible objects. // hwnd is the window this object belongs to. // root is a provider for the OBJID_CLIENT of the window. may be null if it is not yet known. // don't call this constructor directly -- call a Create or Wrap function below. protected MsaaNativeProvider(Accessible acc, IntPtr hwnd, MsaaNativeProvider parent, MsaaNativeProvider knownRoot, RootStatus isRoot) { Debug.Assert(acc != null, "acc"); Debug.Assert(hwnd != IntPtr.Zero); _acc = acc; _hwnd = hwnd; _parent = parent; // can be null if not known. _knownRoot = knownRoot; // can be null if not known. _isRoot = isRoot; // can be RootStatus.Unknown // _controlType defaults to null. computed on demand. }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // the creation of any msaa-based provider funnels through this function. // it creates an object of the base or correct derived class for the specified IAccessible object. private static MsaaNativeProvider Wrap(Accessible acc, IntPtr hwnd, MsaaNativeProvider parent, MsaaNativeProvider knownRoot, RootStatus isRoot) { // if acc is null then return null. if (acc == null) return null; // check that parent is actually our parent - sometimes hit-test and navigation skip layers, so we // may need to reconstruct the parent chain to account for skipped-over ancestors: keep climbing // upwards till we reach the 'parent' that was passed in... MsaaNativeProvider parentChain = parent; if (parent != null) { ArrayList actualParentChain = null; Accessible scan = acc.Parent; while (scan != null) { if (Accessible.Compare(scan, parent._acc)) break; // found actual parent // found intermediate ancestor - add to list... if (actualParentChain == null) actualParentChain = new ArrayList(); actualParentChain.Add(scan); scan = scan.Parent; } if (actualParentChain != null) { // if we found intermediate ancestors, process them top-down, creating // MsaaNativeProviders for each in turn, using the bottom-most one as // our own actual parent... for (int i = actualParentChain.Count - 1; i >= 0; i--) { Accessible ancestor = (Accessible)actualParentChain[i]; parentChain = new MsaaNativeProvider(ancestor, hwnd, parentChain, knownRoot, isRoot); } } } return new MsaaNativeProvider(acc, hwnd, parentChain, knownRoot, isRoot); }