Search code examples
.netwinformswindows-vistascrollbar

Stopping Scroll Bar Fade in Vista (.NET or WinAPI)


Does anyone know of any way to suppress the Vista fade animations on scroll bars?

I only want to do this temporarily and I don't think subclassing is an option because the scroll bars are the "automatic" ones generated by the auto-scroll functionality (it's a .NET app but I assume interop is required).

The reason I want to do this is because the content of the control can (and will) change and cause the vertical scroll bar to be automatically hidden. However - and this is the part that's been driving me crazy - if the user has hovered over the scroll bar within the last 1-2 seconds and the animation is still in progress, then the scroll bar hides but the animation continues anyway and leaves a ghost image, so the SB appears to still be there even though it really isn't (can't click on it, and minimizing/restoring the form makes it disappear completely).

I'm figuring that Vista uses some sort of timer for this animation and hoping that maybe there's some new API to stop the timer (Google is unfortunately no help on this). Or if anybody else has encountered this problem and knows a different way to solve it, that would be great too.

Thanks in advance,
Aaron


Solution

  • this is an effect I'm also wondering about.

    I wrote a control derived from ContainerControl where the child controls may grow or shrink by user interaction. So I spent some time to set up my own LayoutEngine to get the needed layout for the child controls. But even this animated non-stopping SB is dirty. I have a workaround - please don't take it as a solution - in the Layout method I set the focus on the container control before making the layout. That works for me...

    rp

    Another workaround...

    is to inherit from the ScrollableControl (Panel, ...) and to
    

    override the WndProc method and use the PreventScrollAnimation method. This will eat all WM_NCMOUSEMOVE messages having a hit test in the scroll bar. So this will prevent the internals to start the fading of the scroll bar. BTW the fading is implemented in the VISTA-UI using a timer callback, so there is no possibility to stop it.

    const int WM_NCMOUSEMOVE = 160;
    const int HTHSCROLL = 6;
    const int HTVSCROLL = 7;
    
    bool PreventScrollAnimation(ref Message m)
    {
        if (m.Msg == WM_NCMOUSEMOVE)
        {
            if ((m.WParam.ToInt32() == HTHSCROLL) ||
                (m.WParam.ToInt32() == HTVSCROLL))
            {
                m.Result = IntPtr.Zero;
                return true;
            }
        }
        return false;
    }
    
    protected override void WndProc(ref Message m)
    {
        if (PreventScrollAnimation(ref m))
            return;
    
        base.WndProc(ref m);
    }