VB .Net TextBox物件重拾 捲軸事件
由於 MS為了推廣 RichTextBox物件
將 TextBox物件 .VScroll 及 .HScroll 可控制事件取消了
但
想利用捲軸事件寫功能時
就只能放棄TextBox物件嗎 (使用資源較龐大的RichTextBox物件)?
這裡提供一個最簡單的方法 (WWW上的都蠻麻煩的)
以下範例實踐兩個 TextBox物件(TextBox1 及 TextBox2)
「同步捲動」
先加一段程式碼
PHP 語法:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
'wParam的低16位元為控件的ID。lParam控件句柄(hWnd),wParam的高16位元為 編輯框事件
Select Case m.Msg
Case WM_COMMAND
If (CInt(m.WParam) >> 16) = EN_VSCROLL Then '垂直捲軸事件
Dim Pos As Integer, hWnd As IntPtr
Pos = GetScrollPos(m.LParam, SBOrientation.SB_VERT) '取的Pos
Select Case m.LParam
Case TextBox1.Handle
hWnd = TextBox2.Handle
Case TextBox2.Handle
hWnd = TextBox1.Handle
End Select
PostMessage(hWnd, WM_VSCROLL, &H10000 * Pos + SB_THUMBPOSITION, 0) 'Pos是位置改變量
End If
End Select
MyBase.WndProc(m) '前面插入完自己的功能後,須加這一句,才叫「插入」完成,少了他程式會不正常
End Sub
使用的Win API如下,請加入一個 模組貼上以下文字 (一些<>符號為屬性條件,不需多問為何如此,就把他當成數學公式看待吧)
PHP 語法:
Public Enum SBOrientation As Integer
SB_HORZ = &H0
SB_VERT = &H1
SB_CTL = &H2
SB_BOTH = &H3
End Enum
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Function GetScrollPos( _
hWnd As IntPtr, _
<MarshalAs(UnmanagedType.I4)> nBar As SBOrientation) As Integer
End Function
Public Const EM_SETSEL = &HB1
Public Const WM_COMMAND = &H111
Public Const EN_VSCROLL = &H602
Public Const WM_VSCROLL = &H115
Public Const SB_THUMBPOSITION = 4
Public Const WM_USER = &H400
Public Const EM_GETSCROLLPOS = (WM_USER + 221)
Public Const EM_SETSCROLLPOS = (WM_USER + 222)
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal Msg As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Function PostMessage( _
ByVal hWnd As IntPtr, _
ByVal Msg As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As Boolean
End Function
原理說明:
使用攔截視窗訊息方式
如果核對符合 垂直捲軸事件
就同時發送訊息給另一個 TextBox同樣的動作
Protected Overrides Sub WndProc 是指覆寫 視窗訊息 處理 (插入自己的處理功能)
m.Msg 是訊息種類,如果是 WM_COMMAND 表示為使用者訊息
接著要分析 .LParam及.WParam參數
規定上就是:.WParam的前16個位元數值 如果是 EN_VSCROLL 表示是 垂直捲軸事件
.WParam有32位元長度往右移16位元就能與EN_VSCROLL比對是否相等,寫成: If (CInt(m.WParam) >> 16) = EN_VSCROLL Then
符合動作條件接著就是用兩個Win API指令來實作
GetScrollPos 及 PostMessage
前面是取得捲軸的數值
後面是將此數值發送給另一個(想要同步)的TextBox
以達到「同步捲動」
至於這些參數為何如此填,其實滿死板的,也不難理解 因此不多作解說
P.S.至於為何用 PostMessage而不用SendMessage 是因為確保訊息一定會給 接收物件給接收
以上~如有疑惑歡迎提問
|