// Static create method called by the event tracker system. // WinEvents are raised only when a notification has been set for a // specific item. Create the item first and check for details afterward. internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { WindowsScrollBar wtv = new WindowsScrollBar(hwnd, null, -1, NativeMethods.SB_CTL); if (idChild == 0 && eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { // UIA works differently than MSAA. Events are set for elements rather than hwnd // Scroll bar are processed the same way whatever they are part of the non client area // or stand alone hwnd. OBJID_HSCROLL and OBJID_VSCROLL are mapped to OBJID_WINDOW // so they behave the same for NC and hwnd SB. // Parameters are setup so that the dispatch will send the proper notification and // recursively will send notifications to all of the children if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } } if (idChild == 0) { wtv.DispatchEvents(eventId, idProp, idObject, idChild); } else { // raise events for the children ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, wtv, idChild, NativeMethods.SB_CTL); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } }
// Same effect as a click on the arrows or the large increment. void IInvokeProvider.Invoke() { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } if ((WindowsScrollBar.ScrollBarItem)_item == WindowsScrollBar.ScrollBarItem.Thumb) { return; } ScrollAmount amount = ScrollAmount.SmallDecrement; switch ((WindowsScrollBar.ScrollBarItem)_item) { case WindowsScrollBar.ScrollBarItem.UpArrow: amount = ScrollAmount.SmallDecrement; break; case WindowsScrollBar.ScrollBarItem.LargeDecrement: amount = ScrollAmount.LargeDecrement; break; case WindowsScrollBar.ScrollBarItem.LargeIncrement: amount = ScrollAmount.LargeIncrement; break; case WindowsScrollBar.ScrollBarItem.DownArrow: amount = ScrollAmount.SmallIncrement; break; } if (WindowsScrollBar.IsScrollBarVertical(_hwnd, _sbFlag)) { Scroll(amount, NativeMethods.SBS_VERT); } else { Scroll(amount, NativeMethods.SBS_HORZ); } }
// Static create method called by the event tracker system. // WinEvents are raised only when a notification has been set for a // specific item. Create the item first and check for details afterward. internal static void RaiseEvents (IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { WindowsScrollBar wtv = new WindowsScrollBar (hwnd, null, -1, NativeMethods.SB_CTL); if (idChild == 0 && eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { // UIA works differently than MSAA. Events are set for elements rather than hwnd // Scroll bar are processed the same way whatever they are part of the non client area // or stand alone hwnd. OBJID_HSCROLL and OBJID_VSCROLL are mapped to OBJID_WINDOW // so they behave the same for NC and hwnd SB. // Parameters are setup so that the dispatch will send the proper notification and // recursively will send notifications to all of the children if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } } if (idChild == 0) { wtv.DispatchEvents (eventId, idProp, idObject, idChild); } else { // raise events for the children ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, wtv, idChild, NativeMethods.SB_CTL); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods // Static implementation for the bounding rectangle. This is used by // ElementProviderFromPoint to avoid to have to create for a simple // boundary check // param "item", ID for the scrollbar bit // param "sbFlag", SBS_ WindowLong equivallent flag static internal Rect GetBoundingRectangle(IntPtr hwnd, ProxyFragment parent, WindowsScrollBar.ScrollBarItem item, int sbFlag) { NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo(); si.cbSize = Marshal.SizeOf(si.GetType()); si.fMask = NativeMethods.SIF_RANGE; // If the scroll bar is disabled, we cannot have a thumb and large Increment/Decrement) bool fDisableScrollBar = !WindowsScrollBar.IsScrollBarWithThumb(hwnd, sbFlag); if (fDisableScrollBar && (item == WindowsScrollBar.ScrollBarItem.LargeDecrement || item == WindowsScrollBar.ScrollBarItem.Thumb || item == WindowsScrollBar.ScrollBarItem.LargeDecrement)) { return(Rect.Empty); } // If fails assume that the hwnd is invalid if (!Misc.GetScrollInfo(hwnd, sbFlag, ref si)) { return(Rect.Empty); } int idObject = sbFlag == NativeMethods.SB_VERT ? NativeMethods.OBJID_VSCROLL : sbFlag == NativeMethods.SB_HORZ ? NativeMethods.OBJID_HSCROLL : NativeMethods.OBJID_CLIENT; NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo(); sbi.cbSize = Marshal.SizeOf(sbi.GetType()); if (!Misc.GetScrollBarInfo(hwnd, idObject, ref sbi)) { return(Rect.Empty); } if (parent != null && parent._parent != null) { // // Builds prior to Vista 5359 failed to correctly account for RTL scrollbar layouts. // if ((Environment.OSVersion.Version.Major < 6) && (Misc.IsLayoutRTL(parent._parent._hwnd))) { // Right to left mirroring style Rect rcParent = parent._parent.BoundingRectangle; int width = sbi.rcScrollBar.right - sbi.rcScrollBar.left; if (sbFlag == NativeMethods.SB_VERT) { int offset = (int)rcParent.Right - sbi.rcScrollBar.right; sbi.rcScrollBar.left = (int)rcParent.Left + offset; sbi.rcScrollBar.right = sbi.rcScrollBar.left + width; } else { int offset = sbi.rcScrollBar.left - (int)rcParent.Left; sbi.rcScrollBar.right = (int)rcParent.Right - offset; sbi.rcScrollBar.left = sbi.rcScrollBar.right - width; } } } // When the scroll bar is for a listbox within a combo and it is hidden, then // GetScrollBarInfo returns true but the rectangle is boggus! // 32 bits * 32 bits > 64 values // // Note that this test must come after the rectangle has been normalized for RTL or it will fail // long area = (sbi.rcScrollBar.right - sbi.rcScrollBar.left) * (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top); if (area <= 0 || area > 1000 * 1000) { // Ridiculous value assume error return(Rect.Empty); } if (WindowsScrollBar.IsScrollBarVertical(hwnd, sbFlag)) { return(GetVerticalScrollbarBitBoundingRectangle(hwnd, item, sbi)); } else { return(GetHorizontalScrollbarBitBoundingRectangle(hwnd, item, sbi)); } }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods // Static implementation for the bounding rectangle. This is used by // ElementProviderFromPoint to avoid to have to create for a simple // boundary check // param "item", ID for the scrollbar bit // param "sbFlag", SBS_ WindowLong equivallent flag static internal Rect GetHorizontalScrollbarBitBoundingRectangle(IntPtr hwnd, WindowsScrollBar.ScrollBarItem item, NativeMethods.ScrollBarInfo sbi) { // Horizontal Scrollbar NativeMethods.Win32Rect rc = new NativeMethods.Win32Rect(sbi.xyThumbTop, sbi.rcScrollBar.top, sbi.xyThumbBottom, sbi.rcScrollBar.bottom); if (!Misc.MapWindowPoints(hwnd, IntPtr.Zero, ref rc, 2)) { return Rect.Empty; } // Since the scrollbar position is already mapped, restore them back rc.top = sbi.rcScrollBar.top; rc.bottom = sbi.rcScrollBar.bottom; NativeMethods.SIZE sizeArrow; using (ThemePart themePart = new ThemePart(hwnd, "SCROLLBAR")) { sizeArrow = themePart.Size((int)ThemePart.SCROLLBARPARTS.SBP_ARROWBTN, 0); } // check that the 2 buttons can hold in the scroll bar bool fThumbVisible = sbi.rcScrollBar.right - sbi.rcScrollBar.left >= 5 * sizeArrow.cx / 2; if (sbi.rcScrollBar.right - sbi.rcScrollBar.left < 2 * sizeArrow.cx) { // the scroll bar is tiny, need to shrink the button sizeArrow.cx = (sbi.rcScrollBar.right - sbi.rcScrollBar.left) / 2; } // // Builds prior to Vista 5359 failed to correctly account for RTL scrollbar layouts. // if ((Environment.OSVersion.Version.Major < 6) && (Misc.IsLayoutRTL(hwnd))) { if (item == WindowsScrollBar.ScrollBarItem.UpArrow) { item = WindowsScrollBar.ScrollBarItem.DownArrow; } else if (item == WindowsScrollBar.ScrollBarItem.DownArrow) { item = WindowsScrollBar.ScrollBarItem.UpArrow; } else if (item == WindowsScrollBar.ScrollBarItem.LargeIncrement) { item = WindowsScrollBar.ScrollBarItem.LargeDecrement; } else if (item == WindowsScrollBar.ScrollBarItem.LargeDecrement) { item = WindowsScrollBar.ScrollBarItem.LargeIncrement; } } switch (item) { case WindowsScrollBar.ScrollBarItem.UpArrow : rc.left = sbi.rcScrollBar.left; rc.right = sbi.rcScrollBar.left + sizeArrow.cx; break; case WindowsScrollBar.ScrollBarItem.LargeIncrement : if (fThumbVisible) { rc.left = rc.right; rc.right = sbi.rcScrollBar.right - sizeArrow.cx; } else { rc.left = rc.right = sbi.rcScrollBar.left + sizeArrow.cx; } break; case WindowsScrollBar.ScrollBarItem.Thumb : if (!fThumbVisible) { rc.left = rc.right = sbi.rcScrollBar.left + sizeArrow.cx; } break; case WindowsScrollBar.ScrollBarItem.LargeDecrement : if (fThumbVisible) { rc.right = rc.left; rc.left = sbi.rcScrollBar.left + sizeArrow.cx; } else { rc.left = rc.right = sbi.rcScrollBar.left + sizeArrow.cx; } break; case WindowsScrollBar.ScrollBarItem.DownArrow : rc.left = sbi.rcScrollBar.right - sizeArrow.cx; rc.right = sbi.rcScrollBar.right; break; } // Don't need to normalize, OSVer conditional block converts to absolute coordinates. return rc.ToRect(false); }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods // Static implementation for the bounding rectangle. This is used by // ElementProviderFromPoint to avoid to have to create for a simple // boundary check // param "item", ID for the scrollbar bit // param "sbFlag", SBS_ WindowLong equivallent flag static internal Rect GetVerticalScrollbarBitBoundingRectangle(IntPtr hwnd, WindowsScrollBar.ScrollBarItem item, NativeMethods.ScrollBarInfo sbi) { NativeMethods.Win32Rect rc = new NativeMethods.Win32Rect(sbi.rcScrollBar.left, sbi.xyThumbTop, sbi.rcScrollBar.right, sbi.xyThumbBottom); if (!Misc.MapWindowPoints(hwnd, IntPtr.Zero, ref rc, 2)) { return Rect.Empty; } // Vertical Scrollbar // Since the scrollbar position is already mapped, restore them back rc.left = sbi.rcScrollBar.left; rc.right = sbi.rcScrollBar.right; NativeMethods.SIZE sizeArrow; using (ThemePart themePart = new ThemePart(hwnd, "SCROLLBAR")) { sizeArrow = themePart.Size((int)ThemePart.SCROLLBARPARTS.SBP_ARROWBTN, 0); } // check that the 2 buttons can hold in the scroll bar bool fThumbVisible = sbi.rcScrollBar.bottom - sbi.rcScrollBar.top >= 5 * sizeArrow.cy / 2; if (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top < 2 * sizeArrow.cy) { // the scroll bar is tiny, need to shrink the button sizeArrow.cy = (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top) / 2; } switch (item) { case WindowsScrollBar.ScrollBarItem.UpArrow : rc.top = sbi.rcScrollBar.top; rc.bottom = sbi.rcScrollBar.top + sizeArrow.cy; break; case WindowsScrollBar.ScrollBarItem.LargeIncrement : if (fThumbVisible) { rc.top = rc.bottom; rc.bottom = sbi.rcScrollBar.bottom - sizeArrow.cy; } else { rc.top = rc.bottom = sbi.rcScrollBar.top + sizeArrow.cy; } break; case WindowsScrollBar.ScrollBarItem.Thumb : if (!fThumbVisible) { rc.top = rc.bottom = sbi.rcScrollBar.top + sizeArrow.cy; } break; case WindowsScrollBar.ScrollBarItem.LargeDecrement : if (fThumbVisible) { rc.bottom = rc.top; rc.top = sbi.rcScrollBar.top + sizeArrow.cy; } else { rc.top = rc.bottom = sbi.rcScrollBar.top + sizeArrow.cy; } break; case WindowsScrollBar.ScrollBarItem.DownArrow : rc.top = sbi.rcScrollBar.bottom - sizeArrow.cy; rc.bottom = sbi.rcScrollBar.bottom; break; } // Don't need to normalize, OSVer conditional block converts to absolute coordinates. return rc.ToRect(false); }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods // Static implementation for the bounding rectangle. This is used by // ElementProviderFromPoint to avoid to have to create for a simple // boundary check // param "item", ID for the scrollbar bit // param "sbFlag", SBS_ WindowLong equivallent flag static internal Rect GetBoundingRectangle(IntPtr hwnd, ProxyFragment parent, WindowsScrollBar.ScrollBarItem item, int sbFlag) { NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo (); si.cbSize = Marshal.SizeOf (si.GetType ()); si.fMask = NativeMethods.SIF_RANGE; // If the scroll bar is disabled, we cannot have a thumb and large Increment/Decrement) bool fDisableScrollBar = !WindowsScrollBar.IsScrollBarWithThumb (hwnd, sbFlag); if (fDisableScrollBar && (item == WindowsScrollBar.ScrollBarItem.LargeDecrement || item == WindowsScrollBar.ScrollBarItem.Thumb || item == WindowsScrollBar.ScrollBarItem.LargeDecrement)) { return Rect.Empty; } // If fails assume that the hwnd is invalid if (!Misc.GetScrollInfo(hwnd, sbFlag, ref si)) { return Rect.Empty; } int idObject = sbFlag == NativeMethods.SB_VERT ? NativeMethods.OBJID_VSCROLL : sbFlag == NativeMethods.SB_HORZ ? NativeMethods.OBJID_HSCROLL : NativeMethods.OBJID_CLIENT; NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo (); sbi.cbSize = Marshal.SizeOf (sbi.GetType ()); if (!Misc.GetScrollBarInfo(hwnd, idObject, ref sbi)) { return Rect.Empty; } if (parent != null && parent._parent != null) { // // Builds prior to Vista 5359 failed to correctly account for RTL scrollbar layouts. // if ((Environment.OSVersion.Version.Major < 6) && (Misc.IsLayoutRTL(parent._parent._hwnd))) { // Right to left mirroring style Rect rcParent = parent._parent.BoundingRectangle; int width = sbi.rcScrollBar.right - sbi.rcScrollBar.left; if (sbFlag == NativeMethods.SB_VERT) { int offset = (int)rcParent.Right - sbi.rcScrollBar.right; sbi.rcScrollBar.left = (int)rcParent.Left + offset; sbi.rcScrollBar.right = sbi.rcScrollBar.left + width; } else { int offset = sbi.rcScrollBar.left - (int)rcParent.Left; sbi.rcScrollBar.right = (int)rcParent.Right - offset; sbi.rcScrollBar.left = sbi.rcScrollBar.right - width; } } } // When the scroll bar is for a listbox within a combo and it is hidden, then // GetScrollBarInfo returns true but the rectangle is boggus! // 32 bits * 32 bits > 64 values // // Note that this test must come after the rectangle has been normalized for RTL or it will fail // long area = (sbi.rcScrollBar.right - sbi.rcScrollBar.left) * (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top); if (area <= 0 || area > 1000 * 1000) { // Ridiculous value assume error return Rect.Empty; } if(WindowsScrollBar.IsScrollBarVertical(hwnd, sbFlag)) { return GetVerticalScrollbarBitBoundingRectangle(hwnd, item, sbi); } else { return GetHorizontalScrollbarBitBoundingRectangle(hwnd, item, sbi); } }
private static void RaiseEventsOnScroll(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if ((idProp == ScrollPattern.VerticalScrollPercentProperty && idObject != NativeMethods.OBJID_VSCROLL) || (idProp == ScrollPattern.HorizontalScrollPercentProperty && idObject != NativeMethods.OBJID_HSCROLL)) { return; } ProxyFragment el = new NonClientArea(hwnd); if (el == null) return; if (idProp == InvokePattern.InvokedEvent) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; int sbFlag = idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; ProxyFragment scrollBar = new WindowsScrollBar(hwnd, el, (int)item, sbFlag); if (scrollBar != null) { ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, scrollBar, idChild, sbFlag); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } return; } if (eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { if (idChild == 0) { // if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } el.DispatchEvents(eventId, idProp, idObject, idChild); } return; } if (idProp == ValuePattern.ValueProperty && eventId == NativeMethods.EVENT_OBJECT_VALUECHANGE) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; WindowsScrollBar scrollBar = new WindowsScrollBar(hwnd, el, (int)item, idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT); scrollBar.DispatchEvents(0, ValuePattern.ValueProperty, NativeMethods.OBJID_CLIENT, 0); return; } if (Misc.GetClassName(hwnd) == "ComboLBox") { el = (ProxyFragment)WindowsListBox.Create(hwnd, 0); } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
private static void RaiseEventsOnScroll(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if ((idProp == ScrollPattern.VerticalScrollPercentProperty && idObject != NativeMethods.OBJID_VSCROLL) || (idProp == ScrollPattern.HorizontalScrollPercentProperty && idObject != NativeMethods.OBJID_HSCROLL)) { return; } ProxyFragment el = new NonClientArea(hwnd); if (el == null) { return; } if (idProp == InvokePattern.InvokedEvent) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; int sbFlag = idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; ProxyFragment scrollBar = new WindowsScrollBar(hwnd, el, (int)item, sbFlag); if (scrollBar != null) { ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, scrollBar, idChild, sbFlag); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } return; } if (eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { if (idChild == 0) { // if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } el.DispatchEvents(eventId, idProp, idObject, idChild); } return; } if (idProp == ValuePattern.ValueProperty && eventId == NativeMethods.EVENT_OBJECT_VALUECHANGE) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; WindowsScrollBar scrollBar = new WindowsScrollBar(hwnd, el, (int)item, idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT); scrollBar.DispatchEvents(0, ValuePattern.ValueProperty, NativeMethods.OBJID_CLIENT, 0); return; } if (Misc.GetClassName(hwnd) == "ComboLBox") { el = (ProxyFragment)WindowsListBox.Create(hwnd, 0); } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
// Create the approiate child this can return null if that child does not exist internal ProxyFragment CreateNonClientChild(NonClientItem item) { switch (item) { case NonClientItem.HScrollBar: if (WindowsScrollBar.HasHorizontalScrollBar(_hwnd)) { // the listview needs special handling WindowsListViewScrollBar inherits from WindowsScrollBar // and overrides some of its behavoir if (Misc.ProxyGetClassName(_hwnd) == "SysListView32") { return(new WindowsListViewScrollBar(_hwnd, this, (int)item, NativeMethods.SB_HORZ)); } else { return(new WindowsScrollBar(_hwnd, this, (int)item, NativeMethods.SB_HORZ)); } } break; case NonClientItem.VScrollBar: if (WindowsScrollBar.HasVerticalScrollBar(_hwnd)) { // the listview needs special handling WindowsListViewScrollBar inherits from WindowsScrollBar // and overrides some of its behavoir if (Misc.ProxyGetClassName(_hwnd) == "SysListView32") { return(new WindowsListViewScrollBar(_hwnd, this, (int)item, NativeMethods.SB_VERT)); } else { return(new WindowsScrollBar(_hwnd, this, (int)item, NativeMethods.SB_VERT)); } } break; case NonClientItem.TitleBar: { // Note 2 checks above will succeed for the win32popup menu, hence adding this last one if (WindowsTitleBar.HasTitleBar(_hwnd)) { return(new WindowsTitleBar(_hwnd, this, (int)item)); } break; } case NonClientItem.Menu: { return(CreateNonClientMenu()); } case NonClientItem.Grip: { int style = WindowStyle; if (Misc.IsBitSet(style, NativeMethods.WS_VSCROLL) && Misc.IsBitSet(style, NativeMethods.WS_HSCROLL)) { if (WindowsGrip.IsGripPresent(_hwnd, false)) { return(new WindowsGrip(_hwnd, this, (int)item)); } } break; } default: return(null); } return(null); }
private static void RaiseEventsOnScroll(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if ((idProp == ScrollPattern.VerticalScrollPercentProperty && idObject != NativeMethods.OBJID_VSCROLL) || (idProp == ScrollPattern.HorizontalScrollPercentProperty && idObject != NativeMethods.OBJID_HSCROLL)) { return; } ProxyFragment el = new NonClientArea(hwnd); if (el == null) { return; } if (idProp == InvokePattern.InvokedEvent) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; int sbFlag = idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; ProxyFragment scrollBar = new WindowsScrollBar(hwnd, el, (int)item, sbFlag); if (scrollBar != null) { ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, scrollBar, idChild, sbFlag); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } return; } if (eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { if (idChild == 0) { // This code is never exercised. The code in User needs to change to send // EventObjectStateChange with a client ID of zero // // UIA works differently than MSAA. Events are set for elements rather than hwnd // Scroll bar are processed the same way whatever they are part of the non client area // or stand alone hwnd. OBJID_HSCROLL and OBJID_VSCROLL are mapped to OBJID_WINDOW // so they behave the same for NC and hwnd SB. // Parameters are setup so that the dispatch will send the proper notification and // recursively will send notifications to all of the children if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } el.DispatchEvents(eventId, idProp, idObject, idChild); } return; } if (idProp == ValuePattern.ValueProperty && eventId == NativeMethods.EVENT_OBJECT_VALUECHANGE) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; WindowsScrollBar scrollBar = new WindowsScrollBar(hwnd, el, (int)item, idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT); scrollBar.DispatchEvents(0, ValuePattern.ValueProperty, NativeMethods.OBJID_CLIENT, 0); return; } if (Misc.GetClassName(hwnd) == "ComboLBox") { el = (ProxyFragment)WindowsListBox.Create(hwnd, 0); } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }