簡體   English   中英

使用 SendMessage user32 API 以編程方式滾動 RichTextBox 不能超過整數值

[英]Scroll RichTextBox programatically using SendMessage user32 API cannot exceed Integer value

我正在使用 vb2010 WinForm 制作一個文本編輯器應用程序。 不用滾動條滾動,用戶可以直接用鼠標在richtextbox上滾動,類似於adobe acrobat reader。 要以編程方式滾動richtextbox,我正在使用 SendMessage user32 API。

我有兩個問題:

  1. 如果richtextbox 中的文本很大並且我在整數值的末尾附近滾動,那么滾動條將滾動回其初始位置。
  2. 使用 SendMessage 設置的滾動條值與我們稍后使用 GetScrollPos 讀取時不一樣。 結果,當我使用鼠標拖動文本時,richtextbox 開始時滾動不流暢,它是跳躍的。

這是我所做的:

Public Class Form1
    Dim StartMouseDownPos As New Point
    Dim StartScrollBarPos As New Point
    Const WM_USER = &H400
    Const EM_GETSCROLLPOS = WM_USER + 221
    Const EM_SETSCROLLPOS = WM_USER + 222

    Public Declare Auto Function RtfScroll Lib "user32.dll" Alias "SendMessage" ( _
            ByVal hWnd As IntPtr, _
            ByVal Msg As Integer, _
            ByVal wParam As IntPtr, _
            ByRef lParam As System.Drawing.Point) As Integer

    Private Sub RichTextBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RichTextBox1.MouseDown
        'Capture the initial mouse position
        StartMouseDownPos.X = e.X
        StartMouseDownPos.Y = e.Y
        'Capture the initial scrollbar position
        RtfScroll(RichTextBox1.Handle, EM_GETSCROLLPOS, 0, StartScrollBarPos)
    End Sub

    Private Sub RichTextBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RichTextBox1.MouseMove
        'Verify left button is pressed while the mouse is moving
        If e.Button = Windows.Forms.MouseButtons.Left Then
            'Prevent the text in RichTextBox1 to be unintentionally selected when user dragged the text while the cursor shape at that moment is a hand.
            ActiveControl = Nothing
            NewScrollBarPos.X = StartScrollBarPos.X + (StartMouseDownPos.X - e.X)
            NewScrollBarPos.Y = StartScrollBarPos.Y + (StartMouseDownPos.Y - e.Y)
            RtfScroll(RichTextBox1.Handle, EM_SETSCROLLPOS, 0, NewScrollBarPos)
        End If
    End Sub

我試圖改變上面有問題的陳述: RtfScroll(RichTextBox1.Handle, EM_SETSCROLLPOS, 0, NewScrollBarPos) 如下:

Public Declare Function GetScrollPos Lib "user32.dll" ( _
       ByVal hWnd As IntPtr, _
       ByVal nBar As Integer) As Integer

Public Declare Function SetScrollPos Lib "user32.dll" ( _
       ByVal hWnd As IntPtr, _
       ByVal nBar As Integer, _
       ByVal nPos As Integer, _
       ByVal bRedraw As Boolean) As Integer

Public Declare Function PostMessageA Lib "user32.dll" ( _
       ByVal hwnd As IntPtr, _
       ByVal wMsg As Integer, _
       ByVal wParam As Integer, _
       ByVal lParam As Integer) As Boolean

'Scroll the horizontal scrollbar according to the drag of the mouse
SetScrollPos(RichTextBox1.Handle, SBS_HORZ, NewScrollBarPos.X, True)
SetScrollPos(RichTextBox1.Handle, SBS_VERT, NewScrollBarPos.Y, True)
'Scroll the text according to the drag of the mouse
PostMessageA(RichTextBox1.Handle, WM_HSCROLL, SB_THUMBPOSITION + &H10000 * GetScrollPos(RichTextBox1.Handle, SBS_HORZ), Nothing)
PostMessageA(RichTextBox1.Handle, WM_VSCROLL, SB_THUMBPOSITION + &H10000 * GetScrollPos(RichTextBox1.Handle, SBS_VERT), Nothing)

結果更糟:當我試圖滾動超出整數值時,會在 &H10000 * GetScrollPos(RichTextBox1.Handle, SBS_HORZ), Nothing) 相乘時引發溢出異常。

那么,我的問題是如何解決這兩個問題?

我做了一個小程序來找出問題的原因,結果發現問題是這樣的:使用 Point 作為輸入的RtfScroll函數別名“SendMessage”沒有獲取或設置正確的值。 這不會發生在GetScrollPosSetScrollPosPostMessageA上。

所以,不要使用RtfScroll(RichTextBox1.Handle, EM_SETSCROLLPOS, 0, New Point(countX, countY)) & RtfScroll(RichTextBox1.Handle, EM_GETSCROLLPOS, 0, point)的組合。

只需使用GetScrollPosSetScrollPosPostMessageA的組合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM