代码之家  ›  专栏  ›  技术社区  ›  Aaronaught

停止滚动条淡入Vista(.net或winapi)

  •  0
  • Aaronaught  · 技术社区  · 16 年前

    有人知道在滚动条上抑制Vista淡入淡出动画的方法吗?

    我只想暂时这样做,我不认为子类化是一个选项,因为滚动条是自动滚动功能生成的“自动”滚动条(它是一个.NET应用程序,但我认为需要interop)。

    我之所以要这样做,是因为控件的内容可以(并且将)更改并导致垂直滚动条自动隐藏。然而-这是让我发疯的部分-如果用户在过去的1-2秒内一直在滚动条上徘徊,而动画仍在进行中,那么滚动条会隐藏,但动画仍会继续,并留下一个鬼影图像,因此即使它确实不在,sb似乎仍然在那里(不能点击它,并且最小化/还原窗体会使其完全消失)。

    我认为Vista在这个动画中使用了某种计时器,并希望有一些新的API来停止计时器(不幸的是,谷歌对此没有帮助)。或者如果其他人遇到了这个问题,并且知道另一种解决方法,那也太好了。

    事先谢谢,
    亚伦

    4 回复  |  直到 13 年前
        1
  •  0
  •   RP    15 年前

    这也是我想知道的效果。

    我编写了一个从ContainerControl派生的控件,在该控件中,子控件可能会随着用户交互而增长或收缩。所以我花了一些时间设置自己的布局引擎,以获得子控件所需的布局。但即使是这个活生生的不停的人也是肮脏的。我有一个解决方法——请不要把它当作解决方案——在布局方法中,我在进行布局之前将焦点放在容器控件上。那对我有用…

    RP

    另一个解决方法…

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

    重写wndproc方法并使用preventScrollAnimation方法。 这将吃掉所有在滚动条中进行命中测试的wm_ncmousemove消息。 因此,这将防止内部启动滚动条的褪色。 顺便说一下,淡入淡出是在vista-ui中使用计时器回调实现的,因此 不可能阻止它。

    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);
    }
    
        2
  •  1
  •   sger6218    13 年前

    这篇文章的解决方法对我很有用:

    http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/88abdb31-651b-4b47-ae24-8b923344c349

    POST中的示例使用C++,但这里有一些C代码说明如何通过pJoNKE在.NET中使用它(在控制子类中工作)。

    protected override void OnSizeChanged(EventArgs e)
    {
        if (_vScrollVisible != VerticalScroll.Visible)
        {
            _vScrollVisible = VerticalScroll.Visible;
    
            if (!_vScrollVisible)
            {
    
                if (NativeMethods.IsThemeActive())
                {
                    // Fix scrollbar fade issue                
                    NativeMethods.SetWindowTheme(Handle, null, null);
                }
            }
        }
    }
    
    internal static class NativeMethods
    {      
        [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
        public static extern bool IsThemeActive();
    
        [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
        public static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList);
    }
    
        3
  •  0
  •   Beep beep    16 年前

    有什么理由要有滚动条吗?您可以在不使用任何win32 api技巧的情况下关闭它们,同时还可以设置窗口大小以适当地处理动画(或缩放动画)。

    我认为你唯一的选择是滚动你自己的窗口对象,这将是一个皇家痛苦。

        4
  •  0
  •   Eric Cosky    16 年前

    如果您在应用程序或系统范围内引用滚动条,问题并不能完全清楚。如果你指的是全系统的,那么我不确定你能做什么,除了为你的整个计算机设计一个全新的主题。但是,如果您所指的只是更改自己的应用程序,则可以使用WPF控制模板修改滚动条行为,以执行您所描述的操作。

    如果您有ExpressionBlend,那么很容易做到,因为它可以创建一个默认滚动条的副本,您可以根据自己的喜好对其进行修改(例如,在本例中,将淡入淡出的时间更改为零)。 This link 不完全是你想要的,但它应该给你一种可能涉及的感觉。

    如果没有表达式混合,仍然可以手工编写相同的代码,因为它都是XAML文本(即使混合生成它),但是学习如何这样做需要更多的努力。

    第15章 Windows演示基金会发布 (一本很好的书,有很多原因)解释了如何在win32和windows窗体应用程序中使用wpf,如果您无法将整个应用程序移植到wpf,但仍然希望有选择地使用一些wpf功能,那么这本书很方便。