Example #1
0
 internal static NativeMethods.SIZE GetGripSize(IntPtr hwnd, bool onStatusBar)
 {
     using (ThemePart themePart = new ThemePart(hwnd, onStatusBar ? "STATUS" : "SCROLLBAR"))
     {
         return(themePart.Size(onStatusBar ? (int)ThemePart.STATUSPARTS.SP_GRIPPER : (int)ThemePart.SCROLLBARPARTS.SBP_SIZEBOX, 0));
     }
 }
Example #2
0
        // 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);
        }
Example #3
0
        // 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 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 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 static NativeMethods.SIZE GetGripSize(IntPtr hwnd, bool onStatusBar)
 {
     using (ThemePart themePart = new ThemePart(hwnd, onStatusBar ? "STATUS" : "SCROLLBAR"))
     {
         return themePart.Size(onStatusBar ? (int)ThemePart.STATUSPARTS.SP_GRIPPER : (int)ThemePart.SCROLLBARPARTS.SBP_SIZEBOX, 0);
     }
 }