引用 | 編輯
ebolaman
2012-07-25 23:02 |
5樓
▲ |
• Solution : 使用 API : GetScrollInfo
TextBox 預設沒有 Scroll 的觸發事件,比較難開發 如果改成 RichTextBox,就有 VScroll (垂直捲動,水平捲動是 HScroll) 的觸發事件, 再來用 API 去處理判斷是否捲動到最後一行 以你的需求,底下的程式碼要改成 加上一個 Boolean 值記錄是否已經捲動到最後一行 捲動到最後一行的瞬間,即啟動 下一步 的按鈕,或是改變某個記錄的變數值, 好讓 點按鈕後 知道使用者是否已捲動到最後一行 ▼ 捲動前 ▼ 捲動到最後一行,以下的事件都會觸發 (1) 滑鼠拖曳 Scrollbar 到最後一行 (2) 文字選取使 Scrollbar 捲動到最後一行 (3) 點方向鍵 ↓ 使 Scrollbar 捲動到最後一行 • 方法 : 使用 API 函數 GetScrollInfo() 記錄資料到 SCROLLINFO Structure 後 再用 si.nPos / (si.nMax - si.nPage) 得到 Scrollbar 的 ratio (0 代表第一行、1 代表最後一行) ratio 大於 1 則代表捲動到最後一行 • 程式碼 (VB 2010) : 將以下程式碼貼到一個 Form 中 需要 1 個 RichTextBox 物件,命名為 "RichTextBox1" 複製程式 '[Info.] The following codes show how to detect an event that ' user scroll the scrollbars in a RichTextBox to the end ' ' *Required controls : ' 1x Form ' 1x RichTextBox named as "RichTextBox1" Imports System.Runtime.InteropServices Public Class Form1 '========== API ========== <StructLayout(LayoutKind.Sequential)> Public Structure SCROLLINFO Public cbSize As Integer Public fMask As Integer Public nMin As Integer Public nMax As Integer Public nPage As Integer Public nPos As Integer Public nTrackPos As Integer End Structure Public Declare Function GetScrollInfo Lib "user32" Alias "GetScrollInfo" ( _ ByVal hWnd As IntPtr, _ ByVal nBar As Integer, _ <MarshalAs(UnmanagedType.Struct)> ByRef lpScrollInfo As SCROLLINFO) As Integer Private Const SB_HORZ As Integer = 0 Private Const SB_VERT As Integer = 1 Private Const SIF_RANGE As Integer = &H1 Private Const SIF_PAGE As Integer = &H2 Private Const SIF_POS As Integer = &H4 Private Const SIF_DISABLENOSCROLL As Integer = &H8 Private Const SIF_TRACKPOS As Integer = &H10 Private Const SIF_ALL As Integer = (SIF_RANGE Or SIF_PAGE Or SIF_POS Or SIF_TRACKPOS) '========== Records ========== Dim var_last_scrollbarRatio As Double 'Record last scrollbard ratio, used in 'check_scrollbar_ratio()' func. '========== Functions ========== '\brief Get user-defined scrollbar info '\param ByVal hwnd As System.IntPtr | Handle of object ' ByVal iMode As Integer | Mode (Integer) ' ByRef si As SCROLLINFO | 'SCROLLINFO' structure '\return Result of 'GetScrollInfo' API func. Private Function get_scrollbarInfo(ByVal hwnd As System.IntPtr, ByVal iMode As Integer, _ ByRef si As SCROLLINFO) As Integer Dim iRst As Integer 'Result With si .fMask = SIF_ALL .cbSize = Len(si) iRst = GetScrollInfo(hwnd, iMode, si) End With Return iRst End Function '\brief Get scrollbar value/max (Ratio) '\param ByRef si As SCROLLINFO | 'SCROLLINFO' structure '\return Double type : 0 ~ 1, 0 as first line, 1 as last line Private Function get_scrollbarRatio(ByRef si As SCROLLINFO) As Double If 0 <> (si.nMax - si.nPage) Then Return si.nPos / (si.nMax - si.nPage) Else Return 0 End If End Function '\brief Check scrollbar ratio (User-defined) ' Private Sub check_scrollbar_ratio() Dim si As SCROLLINFO Dim iRst As Integer Dim dRatio As Double iRst = get_scrollbarInfo(RichTextBox1.Handle, SB_VERT, si) dRatio = get_scrollbarRatio(si) '' Debug.Print("Scrollbar ratio : " & dRatio) '_DEBUG_ 'Ratio must exceed 1 and it's not equal to last recorded ratio ' and last recorded ratio is lower than 1 ' (Means that there are two states : one is not scrolled to the end, and otherwise) If dRatio >= 1 And dRatio <> var_last_scrollbarRatio And var_last_scrollbarRatio < 1 Then MessageBox.Show("You have scrolled to last line !!", "Scrollbar said", _ MessageBoxButtons.OK, MessageBoxIcon.Information) End If 'Record last ratio var_last_scrollbarRatio = dRatio End Sub '========== Object events ========== Private Sub RichTextBox1_VScroll(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.VScroll check_scrollbar_ratio() End Sub End Class by Ebola x1 |