none
如何在Listbox的非客户区添加滚动条控件,覆盖原来的滚动条。 RRS feed

  • 问题

  • .NET Framework 2.0,重写Listbox控件,发现滚动条无法进行覆盖。
    试过截获WM_HSCROLL 消息,但是发现默认滚动条依然会出现,同时自定义的NCPAINT消息也失效。
    现在自己写了一个滚动条控件,请问如何将该滚动条到Listbox的非客户区,覆盖原有的滚动条。
    2011年4月7日 11:51

答案

  • 您好,

    当你要在一个ListBox中显示更多的item的时候,它的Vertical ScrollBar会自动的显示,这是默认的行为。

    但是我们可以用Win32 API SetWindowLong函数来移除Vertical ScroolBar。但是,即使我们用那个方法来确保ListBox控件不显示Vertical ScrollBar, 那也是暂时的。 当我们使用向下的箭头的案件时,它的Vertical ScroolBar会再次出现,所以我们要移除它的Vertica ScroolBar的话,就必须还得除了SelectedIndexChanged时间或者重写它的OnSelectedChanged方法。

    另外,当我绑定一些数据到ListBox和ComboBox控件,这样当我在ComboBox控件中选择最有一个item的时候,在ListBox控件中也相应的最后一个item也会被选中,但是这样ListBox中的Vertical Scrollbox 有出现了,所以我有Spy++去监控一下windows messages。 我发现当出现Vertical ScrollBar的时候,会有2个messages会被发送: WM_PRINT 和 WM_PRINTCLIENT。 如果我过滤掉这两个messages,这样这个Vertical ScroolBar就永远不会出现了。 这里是我的一个例子:

    class MyListBox:ListBox
    {
    int WM_PRINT = 0x0317;
    int WM_PRINTCLIENT = 0x0318;
    
    int WS_VSCROLL = 0x00200000;
    int GWL_STYLE = -16;
    int SWP_FRAMECHANGED = 0x0020;
    int SWP_NOMOVE = 0x0002;
    int SWP_NOSIZE = 0x0001;
    int SWP_NOZORDER = 0x0004;
    
    
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int
    dwNewLong);
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr
    hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
    
    protected override void WndProc(ref Message m)
    {
    if (m.Msg == WM_PRINT || m.Msg == WM_PRINTCLIENT)
    { }
    else
    {
    base.WndProc(ref m);
    }
    }
    
    private void SetNonVerScrollbar()
    {
    int style = GetWindowLong(this.Handle, GWL_STYLE);
    style = style & ~WS_VSCROLL;
    SetWindowLong(this.Handle, GWL_STYLE, style);
    SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE |
    SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }
    
    protected override void OnSelectedIndexChanged(EventArgs e)
    {
    SetNonVerScrollbar();
    base.OnSelectedIndexChanged(e);
    
    }
     
    

    Vin Jin [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Aspen VJ 2011年4月14日 2:35
    2011年4月11日 2:50