史萊姆論壇

史萊姆論壇 (http://forum.slime.com.tw/)
-   程式語言討論區 (http://forum.slime.com.tw/f76.html)
-   -   VB .Net TextBox物件重拾 捲軸事件 (http://forum.slime.com.tw/thread286023.html)

mini 2016-10-15 08:33 PM

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 IntegerhWnd As IntPtr
                    Pos 
GetScrollPos(m.LParamSBOrientation.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:=TrueCharSet:=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:=TrueCharSet:=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 是因為確保訊息一定會給 接收物件給接收

以上~如有疑惑歡迎提問


所有時間均為台北時間。現在的時間是 05:56 AM

Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2025, Jelsoft Enterprises Ltd.

『服務條款』

* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *


SEO by vBSEO 3.6.1