private bool IsEnabled() { NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo(); sbi.cbSize = Marshal.SizeOf(sbi.GetType()); int idObject = NativeMethods.OBJID_CLIENT; if (_sbFlag == NativeMethods.SB_VERT) { idObject = NativeMethods.OBJID_VSCROLL; } else if (_sbFlag == NativeMethods.SB_HORZ) { idObject = NativeMethods.OBJID_HSCROLL; } if (!Misc.GetScrollBarInfo(_hwnd, idObject, ref sbi)) { return false; } return !Misc.IsBitSet(sbi.scrollBarInfo, NativeMethods.STATE_SYSTEM_UNAVAILABLE); }
// ------------------------------------------------------ // // Private Methods // // ------------------------------------------------------ #region Private Methods // Create a new proxy for one of the scroll bit items private ProxySimple CreateScrollBitsItem (ScrollBarItem index) { // For Scrollbars as standalone controls, make sure that the buttons are not invisible. (office scroll bars) // Checking is done from the return value of SetScrolBarInfo. NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo (); sbi.cbSize = Marshal.SizeOf (sbi.GetType ()); if (_sbFlag != NativeMethods.SB_CTL || Misc.GetScrollBarInfo(_hwnd, NativeMethods.OBJID_CLIENT, ref sbi)) { return new WindowsScrollBarBits (_hwnd, this, (int) index, _sbFlag); } return null; }
// Check if a scroll bar implements the Value Pattern private static bool HasValuePattern (IntPtr hwnd, int sbFlag) { // The scroll bar is enabled, check if we have a thumb 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 ()); // Scroll bars implements the Value pattern if // 1) they are owner drawn (in which case GetScrollBarInfo fails) // 2) they have a thumb (not completely squished) if (Misc.GetScrollBarInfo(hwnd, idObject, ref sbi)) { return IsScrollBarWithThumb (hwnd, sbFlag); } return true; }
// Check if a scroll bar is in a disabled state internal static bool IsScrollBarWithThumb (IntPtr hwnd, int sbFlag) { NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo (); si.cbSize = Marshal.SizeOf (si.GetType ()); si.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE; if (!Misc.GetScrollInfo(hwnd, sbFlag, ref si)) { return false; } // Check for the min / max value if (si.nMax != si.nMin && si.nPage != si.nMax - si.nMin + 1) { // The scroll bar is enabled, check if we have a thumb 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 ()); // check that the 2 buttons can hold in the scroll bar if (Misc.GetScrollBarInfo(hwnd, idObject, ref sbi)) { // 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 long area = (sbi.rcScrollBar.right - sbi.rcScrollBar.left) * (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top); if (area > 0 && area < 1000 * 1000) { NativeMethods.SIZE sizeArrow; using (ThemePart themePart = new ThemePart(hwnd, "SCROLLBAR")) { sizeArrow = themePart.Size((int)ThemePart.SCROLLBARPARTS.SBP_ARROWBTN, 0); } bool fThumbVisible = false; if (IsScrollBarVertical(hwnd, sbFlag)) { fThumbVisible = (sbi.rcScrollBar.bottom - sbi.rcScrollBar.top >= 5 * sizeArrow.cy / 2); } else { fThumbVisible = (sbi.rcScrollBar.right - sbi.rcScrollBar.left >= 5 * sizeArrow.cx / 2); } return fThumbVisible; } } } return 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 bool SetScrollPercent(double fScrollPos, int sbFlag, int cPelsAll, out int delta) { // in case of early exit no move delta = 0; // Check param if ((int)fScrollPos == (int)ScrollPattern.NoScroll) { return true; } if (fScrollPos < 0 || fScrollPos > 100) { throw new ArgumentOutOfRangeException(sbFlag == NativeMethods.SB_HORZ ? "horizontalPercent" : "verticalPercent", SR.Get(SRID.ScrollBarOutOfRange)); } int scrollBar = sbFlag == NativeMethods.SB_HORZ ? NativeMethods.OBJID_HSCROLL : NativeMethods.OBJID_VSCROLL; NativeMethods.ScrollBarInfo scrollBarInfo = new NativeMethods.ScrollBarInfo(); scrollBarInfo.cbSize = Marshal.SizeOf(scrollBarInfo.GetType()); if (!Misc.GetScrollBarInfo(_hwnd, scrollBar, ref scrollBarInfo) || (scrollBarInfo.scrollBarInfo & NativeMethods.STATE_SYSTEM_INVISIBLE) != 0 || (scrollBarInfo.scrollBarInfo & NativeMethods.STATE_SYSTEM_UNAVAILABLE) != 0) { return false; } // Get scroll range NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo (); // this is used all over si.cbSize = Marshal.SizeOf (si.GetType ()); si.fMask = NativeMethods.SIF_ALL; // if no scroll bar return false // on Win 6.0 success is false // on other system check through the scroll info is a scroll bar is there if (!Misc.GetScrollInfo(_hwnd, sbFlag, ref si) || !((si.nMax != si.nMin && si.nPage != si.nMax - si.nMin + 1))) { return false; } // calculate user-requested thumb position int deltaPage = (si.nPage > 0) ? si.nPage - 1 : 0; int future = (int) Math.Round (((si.nMax - deltaPage) - si.nMin) * fScrollPos / 100.0 + si.nMin); // delta between current and user-requested position in pixels // since the cPelsAll contains the dimension in pels for all items + the 2 pels of the border // the operation below does a trunc on purpose delta = (future - si.nPos) * (cPelsAll / (si.nMax + 1 - si.nMin)); return true; }
// get rect of the v-scrollbar private NativeMethods.Win32Rect GetScrollbarRect() { NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo (); sbi.cbSize = Marshal.SizeOf(sbi.GetType()); if (Misc.GetScrollBarInfo(_hwnd, NativeMethods.OBJID_VSCROLL, ref sbi)) { return new NativeMethods.Win32Rect(sbi.rcScrollBar.left, sbi.rcScrollBar.top, sbi.rcScrollBar.right, sbi.rcScrollBar.bottom); } return NativeMethods.Win32Rect.Empty; }
// Finds if a control can be scrolled static internal bool Scrollable (IntPtr hwnd, int sbFlag) { int style = Misc.GetWindowStyle(hwnd); if ((sbFlag == NativeMethods.SB_HORZ && !Misc.IsBitSet(style, NativeMethods.WS_HSCROLL)) || (sbFlag == NativeMethods.SB_VERT && !Misc.IsBitSet(style, NativeMethods.WS_VSCROLL))) { return false; } if (!Misc.IsEnabled(hwnd)) { return false; } // Check if the scroll info shows the scroll bar as enabled. bool scrollBarEnabled = false; NativeMethods.ScrollBarInfo sbi = new NativeMethods.ScrollBarInfo(); sbi.cbSize = Marshal.SizeOf(sbi.GetType()); int scrollBarObjectId = (sbFlag == NativeMethods.SB_VERT) ? NativeMethods.OBJID_VSCROLL : NativeMethods.OBJID_HSCROLL; if (Misc.GetScrollBarInfo(hwnd, scrollBarObjectId, ref sbi)) { scrollBarEnabled = !Misc.IsBitSet(sbi.scrollBarInfo, NativeMethods.STATE_SYSTEM_UNAVAILABLE); } if (!scrollBarEnabled) { return false; } // Get scroll range NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo (); si.cbSize = Marshal.SizeOf (si.GetType ()); si.fMask = NativeMethods.SIF_ALL; if (!Misc.GetScrollInfo(hwnd, sbFlag, ref si)) { return false; } return (si.nMax != si.nMin && si.nPage != si.nMax - si.nMin + 1); }