使用 API 控制滚动






4.74/5 (17投票s)
2004 年 2 月 5 日
2分钟阅读

133827

1461
使用 API 进行滚动。
引言
在某些情况下,我们需要能够通过代码控制滚动条。这看起来应该很容易用标准方法完成,但实际上它们隐藏在 API 中。我将告诉你我是如何在正在开发的应用程序中解决这个问题的。
导入
你必须导入
System.Runtime.InteropServices.Marshal
命名空间,这样如果你遇到错误,就可以访问 GetLastWin32Error
,这是该命名空间中的一个方法。所以,让我们从 import
指令开始。
Imports System.Runtime.InteropServices.Marshal
常量
除了许多 API 函数之外,还有大量结构、类型和常量可供你使用。对于这一点,我只使用几个常量(我们真的不需要其余的)。但是,如果你想知道其他滚动条常量是什么,请查看 WinUser.h(位于 .NET SDK 目录树中)。这是我将要使用的常量
' Scrollbar direction
'
Const SBS_HORZ = 0
Const SBS_VERT = 1
' Windows Messages
'
Const WM_VSCROLL = &H115
Const WM_HSCROLL = &H114
Const SB_THUMBPOSITION = 4
声明函数
现在到了(不那么)有趣的部分,声明函数。我们要使用的第一个函数叫做 GetScrollPos
(位于 afxwin.h 中)。我们向这个函数发送一个句柄和一个方向。它返回一个整数,表示当前的滚动位置。
Private Declare Function GetScrollPos Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal nBar As Integer) As Integer
'Example: position = GetScrollPos(textbox1.handle, SBS_HORZ)
下一个函数叫做 SetScrollPos
,我们向 SetScrollPos
发送句柄、方向、值和一个标志,指示是否应该重绘控件。
Private Declare Function SetScrollPos Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal nBar As Integer, _
ByVal nPos As Integer, _
ByVal bRedraw As Boolean) As Integer
'Example: SetScrollPos(hWnd, SBS_HORZ, position, True
我们要使用的最后一个函数是 PostMessageA
。 PostMessageA
向控件发送关于接下来要做什么的指令。通常,你不需要为此担心,因为它会为你处理。我们向这个函数发送一个句柄、命令、参数和滚动条的 hWnd (可选)。
Private Declare Function PostMessageA Lib "user32.dll" ( _
ByVal hwnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Boolean
'Example: PostMessageA(hWnd, WM_HSCROLL, SB_THUMBPOSITION _
' + &H10000 * position, Nothing)
用法
假设你的表单上有一个名为 textbox1
的控件,并且你想将其滚动到第 100 行。你可以使用 SetScrollPos
和 PostMessageA
轻松完成此操作。以下是完成此操作的一个示例
If (SetScrollPos(hWnd, SBS_HORZ, position, True) <> -1) Then
PostMessageA(hWnd, WM_HSCROLL, SB_THUMBPOSITION +_
&H10000 * position, Nothing)
Else
MsgBox("Can't set info (Err: " & GetLastWin32Error() & ")")
End If
记住我们的 imports
指令,这就是 GetLastWin32Error
的位置。如果出现问题,GetLastWin32Error
将返回一个数字错误代码。你可以在 WinError.h 文件中查找这些错误代码。
现在,假设你想向下滚动几行,但你不知道你需要滚动到的确切行。你可以使用这三个函数来完成这项任务
Dim Position = GetScrollPos(hWnd, SBS_VERT) + 20
If (SetScrollPos(hWnd, SBS_VERT, position, True) <> -1) Then
PostMessageA(hWnd, WM_VSCROLL, SB_THUMBPOSITION + _
&H10000 * position, Nothing)
Else
MsgBox("Can't set info (Err: " & GetLastWin32Error() & ")")
End If
好了,关于使用 API 进行滚动就这些了。
我希望这篇文章对你有所帮助。我将包含一个我在探索这些函数时编写的示例应用程序。