Selection support for the VirtualTreeControl. The motivation for implementing this here, rather than allowing the underlying listbox to handle it, is that we need to fire the correct WinEvents for selection/focus. If we let the listbox handle it, it will fire WinEvents with it's own child ids that assume a flat list structure. We need to be able to account for hierarhcy in the tree. Also, it gets us a step closer to removing the listbox dependency altogether.
 public SelectedIndexEnumerator(VirtualTreeControl owner)
 {
     myOwner        = owner;
     myCurrentRange = -2;
     // -2 to distinguish initial state from ending state (where these will equal VirtualTreeConstant.NullIndex)
     myCurrentSelection = -2;
 }
 /// <summary>
 ///     Create a new DoubleClickEventArgs in response to a double click event in the VirtualTreeControl
 /// </summary>
 /// <param name="parent">The control that was double clicked</param>
 /// <param name="button">The mouse button that was clicked</param>
 /// <param name="x">The x (horizontal) coordinate of the click</param>
 /// <param name="y">The y (vertical) coordinate of the click</param>
 public DoubleClickEventArgs(VirtualTreeControl parent, MouseButtons button, int x, int y)
 {
     myX      = x;
     myY      = y;
     myParent = parent;
     myButton = button;
 }
Example #3
0
            /// <summary>
            ///     Signals the system that an accessibility event occurred.
            ///     The notification will be sent for the specified view only.
            /// </summary>
            /// <param name="accessibilityEvent">One of the predefined EVENT_OBJECT_* or EVENT_SYSTEM_* constants.</param>
            /// <param name="row">row index for item.</param>
            /// <param name="column">column index for item.</param>
            /// <param name="treeControl">The VirtualTreeControl that contains the object that generated the event.</param>
            public static void Notify(int accessibilityEvent, int row, int column, VirtualTreeControl treeControl)
            {
                Debug.Assert(ShouldNotify(accessibilityEvent, treeControl));
                if ((treeControl == null) ||
                    (row < 0) ||
                    (column < 0))
                {
                    return;
                }

                // Add the accessibleObject to the circular array and generate an ID for it.
                var accessibleObjectId = Instance.InternalAddObject(treeControl, row, column);

                // Create a HandleRef object for the hwnd.
                // (A HandleRef structure wraps a managed object holding a
                // handle to a resource that is passed to unmanaged code.
                // Wrapping a handle with HandleRef guarantees that the managed
                // object is not garbage collected until the platform invoke call completes.)
                var viewHandleRef = new HandleRef(treeControl, treeControl.Handle);

                // Notify the system of the event.
                NativeMethods.NotifyWinEvent(
                    accessibilityEvent,          // Specifies the event that occurred
                    viewHandleRef,               // Handle to the window that contains the object that generated the event.
                    accessibleObjectId,          // Generated object ID that uniquely identifies the accessibleObject (for use by WM_GETOBJECT).
                    NativeMethods.CHILDID_SELF); // CHILDID_SELF means the event was generated by the object itself, not a child object.
            }
Example #4
0
 /// <summary>
 ///     Call to test if the Notify method needs to be called. ShouldNotify should
 ///     always be called before Notify.
 /// </summary>
 /// <param name="accessibilityEvent">One of the predefined EVENT_OBJECT_* or EVENT_SYSTEM_* constants.</param>
 /// <param name="treeControl">The tree control that generated the event</param>
 /// <returns>true if Notify should be called</returns>
 public static bool ShouldNotify(int accessibilityEvent, VirtualTreeControl treeControl)
 {
     if (treeControl.GetStateFlag(VTCStateFlags.ReturnedAccessibilityObject))
     {
         // IsWinEventHookInstalled not available on W2k
         return(NativeMethods.WinXPOrHigher ? (0 != NativeMethods.IsWinEventHookInstalled(accessibilityEvent)) : true);
     }
     return(false);
 }
Example #5
0
 public AccessibleObjectEntry(int index)
 {
     // empty entry
     _index             = index;
     _entryReuseCounter = 0;
     _treeControl       = null;
     _row    = 0;
     _column = 0;
 }
Example #6
0
                public void SetObjectData(VirtualTreeControl treeControl, int row, int column)
                {
                    _treeControl = treeControl;
                    _row         = row;
                    _column      = column;

                    if (_entryReuseCounter >= Int16.MaxValue)
                    {
                        _entryReuseCounter = 0;
                    }
                    else
                    {
                        _entryReuseCounter++;
                    }
                }
Example #7
0
            private int InternalAddObject(VirtualTreeControl treeControl, int row, int column)
            {
                array[nextIndex].SetObjectData(treeControl, row, column);

                var id = array[nextIndex].Id;

                if (nextIndex >= array.GetUpperBound(0))
                {
                    nextIndex = array.GetLowerBound(0);
                }
                else
                {
                    nextIndex++;
                }
                return(id);
            }
 /// <summary>
 ///     Create a new VirtualTreeHeaderControl to associate with a specific VirtualTreeControl. Should
 ///     only be called directly by VirtualTreeControl.CreateHeaderControl, or indirectly by an override
 ///     of that function and a constructor from a derived class.
 /// </summary>
 /// <param name="associatedControl"></param>
 public VirtualTreeHeaderControl(VirtualTreeControl associatedControl)
     : this()
 {
     myAssociatedControl = associatedControl;
 }
                public void SetObjectData(VirtualTreeControl treeControl, int row, int column)
                {
                    _treeControl = treeControl;
                    _row = row;
                    _column = column;

                    if (_entryReuseCounter >= Int16.MaxValue)
                    {
                        _entryReuseCounter = 0;
                    }
                    else
                    {
                        _entryReuseCounter++;
                    }
                }
            private int InternalAddObject(VirtualTreeControl treeControl, int row, int column)
            {
                array[nextIndex].SetObjectData(treeControl, row, column);

                var id = array[nextIndex].Id;
                if (nextIndex >= array.GetUpperBound(0))
                {
                    nextIndex = array.GetLowerBound(0);
                }
                else
                {
                    nextIndex++;
                }
                return id;
            }
 public AccTreeRoot(VirtualTreeControl ctl)
     : base(ctl)
 {
     myCtl = ctl;
 }
            // row and column here are the row and column of the parent item.
            // The local column (relative to the parent branch) can be retrieved from the VirtualTreeItemInfo.
            public AccColumn(
                VirtualTreeControl ctl, int row, int displayColumn, int nativeColumn, AccItemSettings settings, ref VirtualTreeItemInfo info)
            {
                // Blank row is calculated explicitly, ignore it if it is passed in
                settings = (AccItemSettings)((int)settings & ~(int)(AccItemSettings.BlankRow));
                myCtl = ctl;
                var tree = ctl.Tree;
                var lastRowAdjust = 0;
                if (info.Column == 0)
                {
                    // Looking at a complex column
                    myChildCount = info.Branch.VisibleItemCount;
                    lastRowAdjust = -1;
                }
                else
                {
                    // This is a wrapper around a single-celled column. It can
                    // only have one item in it. Flag with a -1 to distinguish it
                    // from a complex column
                    myChildCount = -1;
                }

                // Expand column to include blanks to the bottom and right
                var expansion =
                    tree.GetBlankExpansion(
                        row + lastRowAdjust + tree.GetDescendantItemCount(row, nativeColumn, true, myChildCount != -1), displayColumn,
                        myCtl.myColumnPermutation);
                myRow = row;
                myRowHeight = expansion.BottomRow - row + 1;
                displayColumn = expansion.AnchorColumn;
                var colPerm = ctl.myColumnPermutation;
                if (displayColumn == VirtualTreeConstant.NullIndex)
                {
                    settings |= AccItemSettings.BlankRow;
                    displayColumn = 0;
                    myColumnWidth = expansion.Width;
                }
                else
                {
                    nativeColumn = (colPerm != null) ? colPerm.GetNativeColumn(displayColumn) : displayColumn;
                    myColumnWidth = expansion.RightColumn - displayColumn + 1;
                }
                myDisplayColumn = displayColumn;
                myNativeColumn = nativeColumn;
                mySettings = settings;
            }
 public AccSimpleCell(
     VirtualTreeControl ctl, int row, int displayColumn, int nativeColumn, AccItemSettings settings, ref VirtualTreeItemInfo info)
     :
         base(ctl, row, displayColumn, nativeColumn, settings, ref info)
 {
     value = info.Branch.GetAccessibleValue(info.Row, info.Column);
 }
            public AccPrimaryItem(
                VirtualTreeControl ctl, int row, int displayColumn, int nativeColumn, AccItemSettings settings, ref VirtualTreeItemInfo info)
                :
                    base(ctl, row, displayColumn, nativeColumn, settings, ref info)
            {
                if (ctl.MultiColumnTree != null)
                {
                    var mcBranch = info.Branch as IMultiColumnBranch;
                    if (mcBranch != null)
                    {
                        // If Column is not 0, then we're looking at an expandable cell. Expandable
                        // cells cannot have multiple columns.
                        if (info.Column == 0)
                        {
                            var childColumnCount = (0 == (info.Branch.Features & BranchFeatures.JaggedColumns))
                                                       ? mcBranch.ColumnCount
                                                       : mcBranch.GetJaggedColumnCount(info.Row);

                            myNativeChildColumns = myDisplayedChildColumns = childColumnCount - 1;

                            var colPerm = ctl.myColumnPermutation;
                            if (colPerm != null)
                            {
                                // We have to ask on a per-column basis if the given column is
                                // currently displayed.
                                var columnBound = nativeColumn + childColumnCount;
                                childColumnCount = 0;
                                for (var i = nativeColumn + 1; i < columnBound; ++i)
                                {
                                    if (colPerm.GetPermutedColumn(i) != -1)
                                    {
                                        ++childColumnCount;
                                    }
                                }
                                myDisplayedChildColumns = childColumnCount;
                            }
                        }
                    }
                }
                if (ctl.Tree.IsExpanded(myRow, myNativeColumn))
                {
                    myChildItems = ctl.Tree.GetExpandedBranch(myRow, myNativeColumn).Branch.VisibleItemCount;
                }
            }
            /// <summary>
            ///     Construct the base class of an accessibility item for this object
            /// </summary>
            /// <param name="ctl">The parent control</param>
            /// <param name="row">The current row</param>
            /// <param name="displayColumn">The display column.</param>
            /// <param name="nativeColumn">The native column.</param>
            /// <param name="settings">Miscellaneous settings for the object</param>
            /// <param name="info">The info for this cell. Gives the info for column 0 for a blank row.</param>
            public AccItem(
                VirtualTreeControl ctl,
                int row,
                int displayColumn,
                int nativeColumn,
                AccItemSettings settings,
                ref VirtualTreeItemInfo info)
            {
                // Blank row is calculated explicitly, ignore it if it is passed in
                settings = (AccItemSettings)((int)settings & ~(int)(AccItemSettings.BlankRow));

                var tree = ctl.Tree;

                // Get information about the branch and tree state at this
                // position in the tree.
                Debug.Assert(!info.Blank); // Adjust row and column before creating here to take care of blanks
                if (displayColumn < 0)
                {
                    displayColumn = 0;
                }
                if (nativeColumn < 0)
                {
                    nativeColumn = 0;
                }

                if (ctl.MultiColumnTree != null)
                {
                    // Adjust the passed in row and column so that it is on a non-blank item,
                    // and find out how far the blank range extends from that anchor point.
                    // Note that even a single-column branch can have blank columns to the
                    // right (or left, with permutations), so we always need to do GetBlankExpansion.
                    var expansion = tree.GetBlankExpansion(row, displayColumn, ctl.myColumnPermutation);
                    row = expansion.TopRow;
                    myRowHeight = expansion.Height;
                    if (expansion.AnchorColumn != -1)
                    {
                        displayColumn = expansion.AnchorColumn;
                        myColumnWidth = expansion.RightColumn - displayColumn + 1; // Ignore blanks to the left, don't use Width
                    }
                    else
                    {
                        settings |= AccItemSettings.BlankRow;
                        myColumnWidth = expansion.Width;
                    }
                }
                else
                {
                    myRowHeight = myColumnWidth = 1;
                }

                // Cache the information we need
                myCtl = ctl;
                ctl.GetAccessibilityTextFields(
                    row, displayColumn, ref info, out myName, out myValue, out myDescription, out myHelpFile, out myHelpId, out myState,
                    out myCheckBoxContent);
                myRow = row;
                myDisplayColumn = displayColumn;
                myNativeColumn = nativeColumn;
                mySettings = settings;
                myLevel = info.Level;
                if (info.Expandable)
                {
                    if (info.Expanded)
                    {
                        myState |= AccessibleStates.Expanded;
                    }
                    else
                    {
                        myState |= AccessibleStates.Collapsed;
                    }
                }
                if (0 != (settings & AccItemSettings.HiddenItem))
                {
                    myState |= AccessibleStates.Invisible;
                }
                else if (Rectangle.Empty == myCtl.GetAccessibilityLocation(myRow, myDisplayColumn, myRowHeight, myColumnWidth))
                {
                    myState |= (AccessibleStates.Invisible | AccessibleStates.Offscreen);
                }
                ctl.SetAccessibilityState(row, displayColumn, settings, ref myState);
            }
 /// <summary>
 ///     Helper routine to figure out if a given column object is a simple cell or a complex item.
 /// </summary>
 public static bool IsSimpleItem(VirtualTreeControl ctl, int baseRow, int nativeBaseColumn, int localColumn)
 {
     if (localColumn == 0)
     {
         return false; // items in the first column are never simple
     }
     var simpleCell = true;
     var tree = ctl.Tree;
     var info = tree.GetItemInfo(baseRow, nativeBaseColumn, false);
     var mcBranch = info.Branch as IMultiColumnBranch;
     if (mcBranch != null)
     {
         var nativeColumn = nativeBaseColumn + localColumn;
         var style = mcBranch.ColumnStyles(localColumn);
         var colInfo = new VirtualTreeItemInfo();
         switch (style)
         {
             case SubItemCellStyles.Expandable:
                 // Use a simple cell unless the item is expandable. An item
                 // in an expandable column cannot have subitems, so
                 // we will not need a column object for this purpose.
                 simpleCell = !info.Branch.IsExpandable(info.Row, localColumn);
                 break;
             case SubItemCellStyles.Mixed:
             case SubItemCellStyles.Complex:
                 colInfo = tree.GetItemInfo(baseRow, nativeColumn, true);
                 if (colInfo.Column == 0)
                 {
                     var columns = (0 == (info.Branch.Features & BranchFeatures.JaggedColumns))
                                       ? mcBranch.ColumnCount
                                       : mcBranch.GetJaggedColumnCount(info.Row);
                     // The data is provided by a different branch. The item is simple only
                     // if the branch has one unexpandable item and no sub items.
                     if (!(colInfo.Branch.VisibleItemCount == 1 &&
                           !colInfo.Branch.IsExpandable(0, 0) &&
                           (localColumn < columns ||
                            (null != (colInfo.Branch as IMultiColumnBranch) &&
                             0 == tree.GetSubItemCount(baseRow, nativeColumn)))))
                     {
                         simpleCell = false;
                     }
                 }
                 else if (style == SubItemCellStyles.Mixed)
                 {
                     goto case SubItemCellStyles.Expandable;
                 }
                 break;
         }
     }
     return simpleCell;
 }
 /// <summary>
 ///     Return either a Cell or Column object, depending on the branch settings
 /// </summary>
 /// <param name="ctl">The parent control</param>
 /// <param name="baseRow">The row coordinate</param>
 /// <param name="nativeBaseColumn">The column coordinate for the owning branch</param>
 /// <param name="localColumn">The native column offset</param>
 /// <param name="returnColumn">Return an AccColumn object if this is true, otherwise return the AccPrimaryItem directly</param>
 /// <returns>An AccSimpleCell or AccColumn</returns>
 public static AccessibleObject GetColumnObject(
     VirtualTreeControl ctl, int baseRow, int nativeBaseColumn, int localColumn, bool returnColumn)
 {
     // Note:  if this logic changes, corresponding change should be made to IsSimpleItem below.
     Debug.Assert(localColumn > 0);
     AccessibleObject retVal = null;
     var tree = ctl.Tree;
     var info = tree.GetItemInfo(baseRow, nativeBaseColumn, false);
     var mcBranch = info.Branch as IMultiColumnBranch;
     if (mcBranch != null)
     {
         var simpleCell = true;
         var useColInfo = false;
         var nativeColumn = nativeBaseColumn + localColumn;
         var displayColumn = nativeColumn;
         var colPerm = ctl.myColumnPermutation;
         var settings = AccItemSettings.None;
         if (colPerm != null)
         {
             displayColumn = colPerm.GetPermutedColumn(nativeColumn);
             if (displayColumn == -1)
             {
                 displayColumn = 0;
                 settings |= AccItemSettings.HiddenItem;
             }
         }
         var style = mcBranch.ColumnStyles(localColumn);
         var colInfo = new VirtualTreeItemInfo();
         style = mcBranch.ColumnStyles(localColumn);
         switch (style)
         {
             case SubItemCellStyles.Expandable:
                 // Use a simple cell unless the item is expandable. An item
                 // in an expandable column cannot have subitems, so
                 // we will not need a column object for this purpose.
                 simpleCell = !info.Branch.IsExpandable(info.Row, localColumn);
                 break;
             case SubItemCellStyles.Mixed:
             case SubItemCellStyles.Complex:
                 colInfo = tree.GetItemInfo(baseRow, nativeColumn, true);
                 if (colInfo.Column == 0)
                 {
                     var columns = (0 == (info.Branch.Features & BranchFeatures.JaggedColumns))
                                       ? mcBranch.ColumnCount
                                       : mcBranch.GetJaggedColumnCount(info.Row);
                     // The data is provided by a different branch. The item is simple only
                     // if the branch has one unexpandable item and no sub items.
                     if (!(colInfo.Branch.VisibleItemCount == 1 &&
                           !colInfo.Branch.IsExpandable(0, 0) &&
                           (localColumn < columns ||
                            (null != (colInfo.Branch as IMultiColumnBranch) &&
                             0 == tree.GetSubItemCount(baseRow, nativeColumn)))))
                     {
                         simpleCell = false;
                     }
                     useColInfo = true;
                 }
                 else if (style == SubItemCellStyles.Mixed)
                 {
                     goto case SubItemCellStyles.Expandable;
                 }
                 break;
         }
         if (simpleCell)
         {
             if (useColInfo)
             {
                 retVal = new AccSimpleCell(ctl, baseRow, displayColumn, nativeColumn, settings, ref colInfo);
             }
             else
             {
                 var cellInfo = tree.GetItemInfo(baseRow, nativeColumn, true);
                 if (!cellInfo.Blank)
                 {
                     retVal = new AccSimpleCell(ctl, baseRow, displayColumn, nativeColumn, settings, ref cellInfo);
                 }
             }
         }
         else if (returnColumn)
         {
             if (useColInfo)
             {
                 retVal = new AccColumn(ctl, baseRow, displayColumn, nativeColumn, settings, ref colInfo);
             }
             else
             {
                 var cellInfo = tree.GetItemInfo(baseRow, nativeBaseColumn + localColumn, true);
                 retVal = new AccColumn(ctl, baseRow, displayColumn, nativeColumn, settings, ref cellInfo);
             }
         }
         else
         {
             if (useColInfo)
             {
                 retVal = new AccPrimaryItem(ctl, baseRow, displayColumn, nativeColumn, settings, ref colInfo);
             }
             else
             {
                 var cellInfo = tree.GetItemInfo(baseRow, nativeBaseColumn + localColumn, true);
                 retVal = new AccPrimaryItem(ctl, baseRow, displayColumn, nativeColumn, settings, ref cellInfo);
             }
         }
     }
     return retVal;
 }
 /// <summary>
 ///     Create a new DoubleClickEventArgs in response to a double click event in the VirtualTreeControl
 /// </summary>
 /// <param name="parent">The control that was double clicked</param>
 /// <param name="button">The mouse button that was clicked</param>
 /// <param name="x">The x (horizontal) coordinate of the click</param>
 /// <param name="y">The y (vertical) coordinate of the click</param>
 public DoubleClickEventArgs(VirtualTreeControl parent, MouseButtons button, int x, int y)
 {
     myX = x;
     myY = y;
     myParent = parent;
     myButton = button;
 }
 /// <summary>
 ///     Call to test if the Notify method needs to be called. ShouldNotify should
 ///     always be called before Notify.
 /// </summary>
 /// <param name="accessibilityEvent">One of the predefined EVENT_OBJECT_* or EVENT_SYSTEM_* constants.</param>
 /// <param name="treeControl">The tree control that generated the event</param>
 /// <returns>true if Notify should be called</returns>
 public static bool ShouldNotify(int accessibilityEvent, VirtualTreeControl treeControl)
 {
     if (treeControl.GetStateFlag(VTCStateFlags.ReturnedAccessibilityObject))
     {
         // IsWinEventHookInstalled not available on W2k
         return NativeMethods.WinXPOrHigher ? (0 != NativeMethods.IsWinEventHookInstalled(accessibilityEvent)) : true;
     }
     return false;
 }
 public ListBoxStateTrackerClass(VirtualTreeControl ctl)
 {
     Inner = new ListBoxStateTracker(ctl);
 }
 internal static string GetAccessibleObjectName(VirtualTreeControl parent)
 {
     var treeControl = parent;
     if (treeControl != null)
     {
         var headers = treeControl.GetColumnHeaders();
         // Fix for 332947 - Exception thrown when trying to in-place edit a resource name with JAWS running 
         // v-matbir 7/28/04
         if (headers != null)
         {
             var currentColumn = treeControl.CurrentColumn;
             Debug.Assert(currentColumn >= 0 && currentColumn < headers.Length, "column index out of range");
             if (currentColumn >= 0
                 && currentColumn < headers.Length)
             {
                 return headers[currentColumn].Text;
             }
         }
     }
     return string.Empty;
 }
Example #22
0
 /// <summary>
 ///     Create a new inplace edit control
 /// </summary>
 public VirtualTreeInPlaceEditControl()
 {
     myInPlaceHelper = VirtualTreeControl.CreateInPlaceControlHelper(this);
     BorderStyle     = BorderStyle.FixedSingle;
     TextAlign       = HorizontalAlignment.Left;
 }
 internal ListBoxStateTracker(VirtualTreeControl ctl)
 {
     startTop = ctl.TopIndex;
     restoreSelection = null;
     restoreAnchorIndex = -1;
     restoreColumn = startColumn = ctl.CurrentColumn;
     var hWnd = ctl.Handle;
     if (ctl.GetStyleFlag(VTCStyleFlags.MultiSelect)
         && ctl.SelectedItemCount > 0)
     {
         restoreSelection = ctl.SelectedIndicesArray;
         restoreAnchorIndex = ctl.AnchorIndex;
     }
     restoreTop = startTop;
     // Don't use CurrentIndex here, it doesn't notice the caret/anchor subtle distinction,
     // so we end up making a selection where there didn't used to be one.
     restoreCaret = ctl.CurrentIndexCheckAnchor;
     caretMoved = false;
     restoreXPos = ctl.myXPos;
     startingListCount = NativeMethods.SendMessage(hWnd, NativeMethods.LB_GETCOUNT, 0, 0).ToInt32();
     restoreHExtent = 0;
     if (restoreXPos != 0)
     {
         restoreHExtent = NativeMethods.SendMessage(hWnd, NativeMethods.LB_GETHORIZONTALEXTENT, 0, 0).ToInt32();
         NativeMethods.SendMessage(
             hWnd, NativeMethods.WM_HSCROLL, NativeMethods.MAKELONG((int)NativeMethods.ScrollAction.ThumbPosition, 0), 0);
         NativeMethods.SendMessage(hWnd, NativeMethods.WM_HSCROLL, (int)NativeMethods.ScrollAction.EndScroll, 0);
         NativeMethods.SendMessage(hWnd, NativeMethods.LB_SETHORIZONTALEXTENT, 0, 0);
     }
 }
            /// <summary>
            ///     Signals the system that an accessibility event occurred.
            ///     The notification will be sent for the specified view only.
            /// </summary>
            /// <param name="accessibilityEvent">One of the predefined EVENT_OBJECT_* or EVENT_SYSTEM_* constants.</param>
            /// <param name="row">row index for item.</param>
            /// <param name="column">column index for item.</param>
            /// <param name="treeControl">The VirtualTreeControl that contains the object that generated the event.</param>
            public static void Notify(int accessibilityEvent, int row, int column, VirtualTreeControl treeControl)
            {
                Debug.Assert(ShouldNotify(accessibilityEvent, treeControl));
                if ((treeControl == null)
                    || (row < 0)
                    || (column < 0))
                {
                    return;
                }

                // Add the accessibleObject to the circular array and generate an ID for it.
                var accessibleObjectId = Instance.InternalAddObject(treeControl, row, column);

                // Create a HandleRef object for the hwnd.
                // (A HandleRef structure wraps a managed object holding a 
                // handle to a resource that is passed to unmanaged code.
                // Wrapping a handle with HandleRef guarantees that the managed 
                // object is not garbage collected until the platform invoke call completes.)
                var viewHandleRef = new HandleRef(treeControl, treeControl.Handle);

                // Notify the system of the event.
                NativeMethods.NotifyWinEvent(
                    accessibilityEvent, // Specifies the event that occurred
                    viewHandleRef, // Handle to the window that contains the object that generated the event.
                    accessibleObjectId, // Generated object ID that uniquely identifies the accessibleObject (for use by WM_GETOBJECT).
                    NativeMethods.CHILDID_SELF); // CHILDID_SELF means the event was generated by the object itself, not a child object.
            }
 internal void Restore(VirtualTreeControl ctl)
 {
     var itemCount = ctl.ItemCount;
     if (itemCount == 0)
     {
         if (restoreSelection != null
             || restoreCaret >= 0)
         {
             // fire selection change, as we cannot restore the selection or caret.
             ctl.DoSelectionChanged();
         }
         return;
     }
     var hWnd = ctl.Handle;
     if (restoreSelection != null)
     {
         // The old selection is still there, make sure we clear it before restoring
         ctl.ClearSelection(false);
         var upper = restoreSelection.GetUpperBound(0) + 1;
         for (var i = 0; i < upper; ++i)
         {
             // UNDONE: Be smarter about this and do ranges in addition to
             // individual items.
             if (restoreSelection[i] != -1
                 && restoreSelection[i] < itemCount)
             {
                 ctl.SetSelected(restoreSelection[i], true);
             }
         }
     }
     if (startingListCount > 0)
     {
         if (restoreCaret >= 0
             && restoreCaret < itemCount)
         {
             try
             {
                 if (!caretMoved)
                 {
                     ctl.SetStateFlag(VTCStateFlags.RestoringSelection, true);
                 }
                 if (restoreColumn != startColumn)
                 {
                     ctl.SetSelectionColumn(restoreColumn, false);
                 }
                 if (ctl.GetStyleFlag(VTCStyleFlags.ExtendedMultiSelect))
                 {
                     // Last parameter is a little strange. If there is no anchor, then the caret
                     // should not be selected, which is the normal behavior of the routine.
                     ctl.SetCurrentExtendedMultiSelectIndex(
                         restoreCaret, false, true,
                         (restoreAnchorIndex == -1) ? ModifySelectionAction.Clear : ModifySelectionAction.None);
                 }
                 else
                 {
                     ctl.CurrentIndex = restoreCaret;
                 }
             }
             finally
             {
                 if (!caretMoved)
                 {
                     ctl.SetStateFlag(VTCStateFlags.RestoringSelection, false);
                 }
             }
         }
         ctl.TopIndex = restoreTop;
         if (restoreXPos != 0)
         {
             NativeMethods.SendMessage(hWnd, NativeMethods.LB_SETHORIZONTALEXTENT, restoreHExtent, 0);
             NativeMethods.SetScrollPos(hWnd, NativeMethods.ScrollBarType.Horizontal, restoreXPos, true);
             NativeMethods.SendMessage(
                 hWnd, NativeMethods.WM_HSCROLL,
                 NativeMethods.MAKELONG((int)NativeMethods.ScrollAction.ThumbPosition, restoreXPos), 0);
             NativeMethods.SendMessage(hWnd, NativeMethods.WM_HSCROLL, (int)NativeMethods.ScrollAction.EndScroll, 0);
         }
         if (restoreAnchorIndex >= 0
             && restoreAnchorIndex < itemCount)
         {
             ctl.AnchorIndex = restoreAnchorIndex;
         }
     }
 }
 public AccessibleObjectEntry(int index)
 {
     // empty entry
     _index = index;
     _entryReuseCounter = 0;
     _treeControl = null;
     _row = 0;
     _column = 0;
 }
 public ToolTipControl(VirtualTreeControl parent)
 {
     myParent = parent;
     myLastString = String.Empty;
     SetStyle(ControlStyles.UserPaint, true);
     BackColor = SystemColors.Info;
     ForeColor = SystemColors.InfoText;
 }
            public void PositionTipWindow(VirtualTreeControl ctl)
            {
                // measure the string, set up the window
                var tipString = Marshal.PtrToStringAuto(myStringBuffer);
                int stringWidth, stringHeight;
                using (var g = CreateGraphics())
                {
                    stringWidth = ctl.ListItemStringWidth(g, Font, tipString);
                    stringHeight = Math.Max(
                        StringRenderer.MeasureString(UseCompatibleTextRendering, g, tipString, Font, myFormat).Height, ctl.myTextHeight);
                }
                var textDimsInt = new Size();
                textDimsInt.Width = stringWidth;
                textDimsInt.Height = stringHeight;
                var windowRect = new Rectangle(ctl.PointToScreen(myFullLabelRectangle.Location), textDimsInt);

                // add padding for the client rectangle
                windowRect.Inflate(1, 1);

                // move window into screen space, clip, and set the position
                // To determine the screen to show the tip on, we could use Screen.FromRectangle(tipRect),
                // Screen.FromPoint(tipRect.Location), Screen.FromPoint(current mouse position), or
                // Screen.FromPoint(activating mouse position). I chose the last option.
                var offScreenEdge = false;
                var screenBounds = Screen.FromPoint(myActivatingMousePos).WorkingArea;
                if (windowRect.Left < screenBounds.Left)
                {
                    offScreenEdge = true;
                    windowRect.X = screenBounds.X;
                }
                else if (windowRect.Right > screenBounds.Right)
                {
                    offScreenEdge = true;
                    windowRect.X = screenBounds.X + screenBounds.Width - windowRect.Width;
                }

                if (windowRect.Bottom > screenBounds.Bottom)
                {
                    offScreenEdge = true;
                    windowRect.Y = screenBounds.Y + screenBounds.Height - windowRect.Height;
                }
                NativeMethods.SetWindowPos(
                    Handle,
                    IntPtr.Zero,
                    windowRect.Left,
                    windowRect.Top,
                    windowRect.Width,
                    windowRect.Height,
                    NativeMethods.SetWindowPosFlags.SWP_NOACTIVATE | NativeMethods.SetWindowPosFlags.SWP_NOZORDER);

                // find the point in the client rect to draw the text rect
                if (!offScreenEdge)
                {
                    myTextRect = new RectangleF(
                        PointToClient(ctl.PointToScreen(myFullLabelRectangle.Location)), new SizeF(textDimsInt.Width, textDimsInt.Height));
                }
                else
                {
                    var rect = NativeMethods.RECT.FromXYWH(windowRect.X, windowRect.Y, windowRect.Width, windowRect.Height);
                    NativeMethods.SendMessage(Handle, NativeMethods.TTM_ADJUSTRECT, 0, out rect);
                    myTextRect = new RectangleF(
                        PointToClient(new Point(rect.left, rect.top)), new SizeF(textDimsInt.Width, textDimsInt.Height));
                }
            }
Example #29
0
 public HeaderContainer(VirtualTreeControl associatedControl)
 {
     SetStyle(ControlStyles.ContainerControl, true);
     SetStyle(ControlStyles.Selectable, false);
     Size = new Size(0, 0);
     TabStop = false;
     Font = associatedControl.Font;
     myHeader = associatedControl.CreateHeaderControl();
     Controls.Add(myHeader);
 }