获取滚动条的位置'在RichTextBox中禁用滚动条

时间:2014-03-31 09:03:16

标签: c# winapi scroll scrollbar richtextbox

我之前的post here显示了如何获取RichTextbox中水平或垂直滚动​​条的位置。但是,这些仅在启用滚动条时有效。如果您将滚动条设置为无(通过richTextBox1.ScrollBars = RichTextBoxScrollBars.None;),那么您仍然可以向下滚动框的底部(如果禁用WordWrap则向右滚动)。但是,getVerticalScroll()getHorizontalScroll()方法(如我发布的链接中所示)现在只返回0。他们似乎需要“看到”滚动条才能真正发挥作用。

那么如何在滚动条被禁用的情况下获取(并设置)'滚动位置'?

2 个答案:

答案 0 :(得分:6)

RichTextBox类有几个辅助方法,可以让您发现窗口内文本的位置。这是您需要在这里使用的内容,因为您不再需要滚动条的直接反馈。

您可以找到哪条线显示为RichTextBox.GetCharIndexFromPosition()的第一条可见线,以查找第一个可见字符,然后是GetLineFromCharIndex()以找出包含该字符的行:

    public static double GetVerticalScrollPos(RichTextBox box) {
        int index = box.GetCharIndexFromPosition(new Point(1, 1));
        int topline = box.GetLineFromCharIndex(index);
        int lines = box.Lines.Length;
        return lines == 0 ? 0 : 100.0 * topline / lines; 
    }

通过查看插入符当前所在的行,可以找到水平滚动位置。并将行的开头映射回位置:

    public static double GetHorizontalScrollPos(RichTextBox box) {
        int index = box.SelectionStart;
        int line = box.GetLineFromCharIndex(index);
        int start = box.GetFirstCharIndexFromLine(line);
        Point pos = box.GetPositionFromCharIndex(start);
        return 100 * (1 - pos.X) / box.ClientSize.Width;
    }

您可能想重新定义100%的含义,原始问题没有提供任何指导。

这个问题具有XY Problem的各个方面,它会让你真正想要做的就是用更大的滚动条替换滚动条。不要忽略这个愚蠢的简单解决方案,您可以通过正确放置现有的解决方案覆盖现有的解决方案,以便它们重叠并隐藏它们。你只需要改变边框,这样就不那么明显了。

答案 1 :(得分:5)

我想你会找到一些有趣的东西here。它在.Net中RichEdit背后使用的RichTextBox的描述。

还解决了你的问题:

var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(POINT)));
Marshal.StructureToPtr(new POINT(), ptr, false);
SendMessage(this.richTextBox1.Handle, EM_GETSCROLLPOS, IntPtr.Zero, ptr);
var point = (POINT)Marshal.PtrToStructure(ptr, typeof(POINT));
Marshal.FreeHGlobal(ptr);

其中:

EM_GETSCROLLPOS = WM_USER + 221

来自pinvoke.netPOINT结构。