2012-06-19 44 views
4

我有一個標籤,它根據RichTextBox上的文本標記行號。我已經掛鉤了Vscroll的事件來處理標籤。禁用Richtextbox上的平滑滾動

private void rtbLogicCode_VScroll(object sender, EventArgs e) 
{ 
    Point pt = new Point(0, 1); 
    int firstIndex = rtbLogicCode.GetCharIndexFromPosition(pt); 
    int firstLine = rtbLogicCode.GetLineFromCharIndex(firstIndex); 

    pt.X = ClientRectangle.Width; 
    pt.Y = ClientRectangle.Height; 
    int lastIndex = rtbLogicCode.GetCharIndexFromPosition(pt); 
    int lastLine = rtbLogicCode.GetLineFromCharIndex(lastIndex); 

    // Small correction 
    if (rtbLogicCode.Text.EndsWith("\n")) 
     lastLine++; 

    labelLogicCode.ResetText(); 
    LabelLineNum(firstLine+1,lastLine); 
} 
#endregion 

private void LabelLineNum(int startNum, int lastNum) 
{ 
    labelLogicCode.Font = UIConstant.DDCLogicCodeFont; 
    for (int i = startNum; i < lastNum; i++) 
    { 
     labelLogicCode.Text += i + Environment.NewLine; 
    } 
} 

一切似乎除了RichTextBox的使用平滑滾動功能,它搞砸了我的行號在許多情況下,用戶一路尚未滾動到下一行的正常工作。這會導致行號與RichTextBox上顯示的實際文本不同步。

最後,我需要禁用平滑滾動功能來完成此操作。我被告知你可以重寫RichTextBox的postMessage API以禁用所提到的功能,但是在搜索了很多文檔後,我找不到任何好的文檔。

我將不勝感激儘可能詳細的解決方案,如何禁用平滑滾動功能。謝謝。

+0

不回答你的問題,但是從長遠來看,更先進的編輯控制可能是爲了... [Scintilla的(HTTP:// scintillanet .codeplex.com /)是一種可能性。 –

+0

您無法關閉此功能。 –

+0

'See this' - http://stackoverflow.com/a/4920372/763026'&this' - http://www.codeproject.com/Articles/7830/Scrolling-A-round-with-the-RichTextBox-Control –

回答

5

這是微軟提供的VB example,建議您需要攔截WM_MOUSEWHEEL消息。

這裏有一個快速原型在C#:

class MyRichTextBox : RichTextBox { 

    [DllImport("user32.dll")] 
    public static extern IntPtr SendMessage(
      IntPtr hWnd,  // handle to destination window 
      uint Msg,  // message 
      IntPtr wParam, // first message parameter 
      IntPtr lParam // second message parameter 
    ); 

    const uint WM_MOUSEWHEEL = 0x20A; 
    const uint WM_VSCROLL = 0x115; 
    const uint SB_LINEUP = 0; 
    const uint SB_LINEDOWN = 1; 
    const uint SB_THUMBTRACK = 5; 

    private void Intercept(ref Message m) { 
     int delta = (int)m.WParam >> 16 & 0xFF; 
     if((delta >> 7) == 1) { 
      SendMessage(m.HWnd, WM_VSCROLL, (IntPtr)SB_LINEDOWN, (IntPtr)0); 
     } else { 
      SendMessage(m.HWnd, WM_VSCROLL, (IntPtr)SB_LINEUP, (IntPtr)0); 
     } 
    } 

    protected override void WndProc(ref Message m) { 
     switch((uint)m.Msg) { 
      case WM_MOUSEWHEEL: 
       Intercept(ref m); 
       break; 
      case WM_VSCROLL: 
       if(((uint)m.WParam & 0xFF) == SB_THUMBTRACK) { 
        Intercept(ref m); 
       } else { 
        base.WndProc(ref m); 
       } 
       break; 
      default: 
       base.WndProc(ref m); 
       break; 
     } 
    } 
} 
+0

我查看了一段時間的代碼,並且誠實地不理解代碼是如何工作的,因爲我對VB沒有專業知識。也許我可以在C#中獲得對代碼的解釋嗎? – l46kok

+0

我在C#中添加了一個類似的例子 - 它的邊緣有點粗糙,但應該讓你開始。 – PhilMY

+0

這部分if(((uint)m.WParam&0xFF)== SB_THUMBTRACK){ Intercept(ref m); }'當按下滾動條時不會刷新內容的副作用。我不確定它的目的。 (好的,這是一箇舊的答案。) –