2014-03-31 91 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的回答(或者你的可能)是一種享受。即使你有幫助,這也意味着我的代碼將大量返工。 (旁註,哇,你也是這樣回答的,難怪你的代表太高了!)。 –