سؤال

My earlier post here shows how to obtain the position of the horizontal or vertical scrollbars in a RichTextbox. However, these only work if scrollbars are enabled. If you set scrollbars to None (via richTextBox1.ScrollBars = RichTextBoxScrollBars.None;), then you can still scroll down off the bottom of the box (and off to the right if you disable WordWrap). However, the getVerticalScroll() and getHorizontalScroll() methods (as shown in the link I posted) only return 0 now. They seem to need to 'see' the scrollbars to actually work.

So how can I get (and set) the 'scroll position' whilst scroll bars are disabled?

هل كانت مفيدة؟

المحلول 2

I think you will find something interesting here. It's description of RichEdit used behind RichTextBox in .Net.

Also solution of your question:

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);

Where:

EM_GETSCROLLPOS = WM_USER + 221

And POINT structure from pinvoke.net.

نصائح أخرى

The RichTextBox class has several helper methods that lets you discover the position of text inside the window. Which is what you need to use here since you don't have a direct feedback from a scrollbar anymore.

You can find which line is displayed as the first visible line with RichTextBox.GetCharIndexFromPosition() to find the first visible character, followed by GetLineFromCharIndex() to figure out the line that contains that character:

    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; 
    }

The horizontal scroll position can be found by looking on which line the caret is currently located. And mapping the start of the line back to a position:

    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;
    }

You may want to redefine what 100% means, your original question didn't give any guidance.

This question has the aspects of an XY Problem and it smells that what you really want to do is to replace the scrollbars with bigger ones. Don't overlook the silly simple solution, you can just overlay the existing ones by placing yours correctly so they overlap and hide them. You just need to change the border so it isn't so obvious.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top