2014-03-31 84 views
5

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

那么我怎样才能得到(和设置)“滚动位置”,而滚动条被禁用?

回答

5

我想你会发现一些有趣的东西here。这是在.Net中使用RichTextBox后面的RichEdit的描述。

你的问题的同时解决方案:

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结构。

+0

感谢这看起来很有前途,但我仍然得到零后返回point.X或point.Y,即使滚动条已启用。我将WM_USER更改为1024 - 是吗?我还添加了以下几行:'[DllImport(“User32.Dll”]'和'static extern bool SendMessage(IntPtr hWnd,uint msg,IntPtr wParam,IntPtr lParam);'。是不是也可以? –

+0

是的,WM_USER和DllImport但是为什么你仍然会得到零呢?我已经在发布前测试了这个代码,对我来说工作得很好。如果我能看到你的代码,那将是非常棒的。你还必须发布'ptr'(在代码中添加代码)。 – user3449857

+0

我的不好意思,我不小心在DllImport位中有'EntryPoint =“PostMessageA”'我以为我早些时候删除了它,但也许其他的东西出了问题,于是我解开了那个删除,之后忘了它。是你的 - 非常感谢你!:D –

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的方面,它闻到你真的想要做的是将滚动条替换为更大的滚动条。不要忽视愚蠢的简单解决方案,你可以通过正确放置你的正确方式覆盖现有的解决方案,使它们重叠并隐藏它们。你只需要改变边界,所以它不是那么明显。

+0

非常感谢您的回答。我现在可能会坚持另一个答案(我在看到你之前就奖励赏金),除非你还添加了Set()版本(因为我已经有了互操作版本)。我不能怪你提到XY问题。你是对的,我的问题暗示了一个更深层的问题,但如果你知道它是什么,你会跑一英里(这是它会打开的巨大的兔子洞的十分之一大小,这要归功于它的怪癖的RTB)。 (线索:垂直同步两个RTB并更改RTF内容,将光标保持在同一位置,全部不闪烁)。 –

+0

这是[微不足道](http://stackoverflow.com/a/3823319/17034)。总是一个错误来隐藏意图。 –

+0

我想我可能已经看到了很久以前,但它只是整体问题的一小部分,由于它的复杂性和实时出现故障的问题。我再次怀疑你会想知道涉及到什么。我研究了几天,甚至几周的问题。也许可能有一天我会重新讨论这个问题,但是现在,在这个问题中,user3449857的回答(或者你的可能)是一种享受。即使你有帮助,这也意味着我的代码将大量返工。 (旁注,哇,你也是这样回答的,难怪你的代表太高了!)。 –