c#MouseWheel Scroll和RTB VScroll事件

时间:2011-12-05 18:45:52

标签: winforms .net-4.0 scroll mouse richtextbox

我有点困惑:

我们有一个聊天应用程序,如果用户向上滚动,则需要不滚动聊天;我们有一个scrollInfo类,它使我们能够检查滚动条拇指是否位于滚动条的底部,这样我们就可以确定是否应该滚动。

不幸的是,滚动聊天的方式有很多种。可以使用滚动条上/下框或滚动条滑块,或者只使用鼠标滚轮滚动。

但是,如果使用向上/向下箭头,我们没有问题。

并且,如果使用滚动条拇指,VScroll事件会触发,但是我们无法识别拇指移动的方向,或者如何检查它是否被按下,而不使用计时器来不断查询鼠标左键状态。

最后,如果滚动鼠标滚轮,虽然我们可以通过查看Delta属性来判断它的走向,但在处理鼠标滚轮事件后,VScroll事件仍然会触发。所以,我们基本上会发生重复滚动。

我需要一些帮助。我们的聊天应用程序如下:

  • .NET 4.0 Windows Forms C#Application
  • 内置Visual Studio 2010
  • * 聊天输出:* RichTextBox自动设置输入文字的格式。

这是我们逻辑的一个例子,它只是不起作用:

  1. 用户使用鼠标滚轮向上滚动:当有新消息进入时,他们不应该向下滚动聊天输出框。相反,当滚动事件发生时,它应该能够检测滚动拇指的位置,并进行确定。

  2. 用户使用ScrollBar拇指向上滚动:触发VScroll事件,检查滚动条是否位于滚动框的“底部”。并且,如果是,则执行完全滚动事件,以确保插入符始终位于滚动框的末尾,并且被隐藏(以便READ ONLY聊天输出,没有实际闪烁的I光束)。 / p>

  3. 用户使用滚动条向上/向下箭头滚动:工作得很好。 (不需要解释这个,因为它已经在工作)。

  4. 我需要在这里澄清一下,我该如何正确检查这些事件?

    --------澄清澄清--------- scrollInfo类的内容:

     internal class Scrollinfo
    {
        internal const uint ObjidVscroll = 0xFFFFFFFB;
    
        [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
        private static extern int GetScrollBarInfo(IntPtr hWnd,
                                                   uint idObject,
                                                   ref Scrollbarinfo psbi);
    
        internal static bool CheckBottom(Control rtb, int postion)
        {
            var info = new Scrollbarinfo();
            info.CbSize = Marshal.SizeOf(info);
    
            var chk = GetScrollBarInfo(rtb.Handle,
                                       ObjidVscroll,
                                       ref info);
            if (chk == 0)
                GetScrollBarInfo(rtb.Handle,
                                 ObjidVscroll,
                                 ref info);
    
    
            bool isbottom = info.XyThumbBottom
                            >= (info.RcScrollBar.Bottom - info.RcScrollBar.Top - (info.DxyLineButton + 1));
            if (info.DxyLineButton <= 0) isbottom = true;
            if (info.XyThumbBottom <= 0) isbottom = true;
            return isbottom;
        }
    
    
    }
    
    internal struct Scrollbarinfo
    {
        internal int CbSize;
        internal Rect RcScrollBar;
        internal int DxyLineButton;
        internal int XyThumbTop;
        internal int XyThumbBottom;
        internal int Reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        internal int[] Rgstate;
    }
    
    internal struct Rect
    {
        internal int Left;
        internal int Top;
        internal int Right;
        internal int Bottom;
    }}
    

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

使用要显示的新文本更新框,然后使用以下代码查找最后一行:

rtb.GetLineFromCharIndex(rtb.GetCharIndexFromPosition(new Point(rtb.Width, rtb.Height)));

现在,下次需要将文本放入RichTextBox时,只需使用与上面相同的代码检查最后一行。

如果新的最后一行可见行小于旧版本,则表示用户已向上滚动(或者RichTextBox已调整大小)。在任何一种情况下,您只需将插入符号移动到文本的末尾,然后调用RichTextBox.ScrollToCaret()方法来恢复位置。



我还建议您在MSDN网站上查看以下内容:

¹这可以用来设置插入位置。