现在已经实现了自绘的SCROLLBAR,它继承于MFC的 CScrollBar,但是如何将该自绘的SCROLLBAR替换掉系统控件(ListCtrl,TreeCtrl,Edit等)的默认SCROLLBAR呢?
本来Subclass是个好的选择,但是却不可以拿到普通控件的默认Scrollbar,而且该对象好似也不是一直存在的.
看了有的方法是靠隐藏本身的ScrollBar,然后把自己定义的SCROLLBAR放到默认SCROLLBAR的位置上,以替换它.但是没有办法以通用的方式捕获控件的SCROLLINFO变化信息.(其实在SCROLLINFO变化的时候,是需要调用SCROLLBAR类的SETSCROLLBARINFO来设置SCROLLBAR的信息,以使SCROLLBARINFO与控件的内容变化相一致的,比如CListCtrl在InsertItem的时候,这时候它的ScrollInfo应该是变化的.)

解决方案 »

  1.   

    给每个滚动视图附加一个自己的滚动条控件,不仅仅是遮挡住原始滚动条(因为窗口绘制上无父子关系,原始滚动条不会被挡住),因此把视图的滚动条属性隐藏,截获消息控制滚动条显示,和滚动滚动条控制视图滚动。(其实这里有个好法,不去处显示滚动条的窗口属性,而是把原来相关的NC区域给SetRGN抠去了,就是说原始的滚动视图已经是被挖去滚动区域的不规则窗口,也不会出现原始滚动条覆盖自绘滚动条的BUG,而且还可以横纵兼施下面是这篇文章.希望对你有帮助.
    http://blog.9zi.com/post/1/890
      

  2.   

    这个问题我也挺感兴趣的,一般的都是把他的子控件用自己写的控件子类化替代掉,但是SCROLLBAR似乎挺特殊的,当时在codeproject上也挖过,没有找到“完美”的解决办法,就像楼主说的,一般的做法都是把原来的隐藏掉,把自己写的放到特定的位置上去。关注这个问题
      

  3.   

    TO :ydfivy(我就是一送外卖的)
    问题不在于是遮盖还是用SETRGN抠去,问题在于一个控件,当它的内容变化的时候,会导致相应的SCROLLINFO信息变化(比如增加或者删除listctrl的节点,那么它的SCROLLINFO里的nMax可能会变化),而问题是我要取得这个事件,从来可以使自己的SCROLLBAR里的SCROLLINFO信息也跟着变化,这样才可以使自己的滚动条信息跟实际控件的滚动条信息是一致的,问题就是,如何知道系统在何时调用了SetScrollInfo,SetScrollPos等API函数.
    看了一些专业的界面设计库,对这问题的处理也似乎比较复杂,就是类似"HOOK"API调用,而且不同的系统(win9x和winnt),他们的方法还不同.
    似乎没有简单的解决方法,而且比较难把握.没什么信心~~~~
      

  4.   

    Window的控件基本上都可以自绘,就是SCROLLBAR的自绘最麻烦.
    我留意了这么久,也没有完美的解决方案.真是有点U**)*)
      

  5.   

    这个问题估计是得不到更好的解决方法了。因为List、Tree中的scrollbar根本就不是一个窗口,你当然不能subclass了。
      

  6.   

    但是QQ,泡泡,还有其他有些软件,看他们的SCROLLBAR都挺好的,不知道他们怎么实现的.
    即使不是用SUBCLASS,有没有其他好点的方法呢,最好不用HOOK SETSCROLLINFO等API来实现的.
      

  7.   

    不是codeproject.com有个cool scrollbar吗?就是完全把系统提供的sb自绘了。好像涉及到hooks等很多技术,可以拿来直接用
    http://www.codeproject.com/dialog/coolscroll.asp
      

  8.   

    QQ中的ScrollBar也只是把原来的去掉,然后从CWnd派生一个类来自绘成ScrollBar加在上面而已。