VB.NET调用Windows API函数(整理中)

前端之家收集整理的这篇文章主要介绍了VB.NET调用Windows API函数(整理中)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1、发送Windows消息:

Private Declare Auto Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Integer,ByVal wMsg As Integer,ByVal wParam As Integer,ByVal lParam As String) As Integer

Private Const EM_SETTEXT = &HC ' VB中&H表示16进制

'Private Const WM_GETTEXT = &HC


'Sendmessage(目标控件句柄,自定义消息类型,参数个数,消息内容)

SendMessage(Form1.Text.Handle,EM_SETTEXT,"heyinjie")



函数原型:Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long,ByVal wMsg As Long,ByVal wParam As Long,lParam As Any) As Long (注:SendMessageA表示以Ansi,SendMessageW表示Unicode。发送的消息中含汉字等双字节字的话,使用SendMessageW)

其中四个参数的含义和说明如下:

1.hWnd:
对象的句柄。希望将消息传送给哪个对象,就把该对象的句柄作为实参传送,在VB中可以简单地用"对象.hWnd"获得某个对象的句柄,如Text1.hWnd和 Form1.hWnd分别可以得到 Text1和Form1的句柄。它是一个长整型数。Windows给每个控件一个编号,这个编号就称为窗口句柄。有了这个句柄,我们就可告诉 Windows 我们要控制哪个控件,所以这个句柄在 API 调用中至关重要。VB 的大多数控件都包括hwnd属性,如下拉框、TreeView等,窗体也有这个属性。但也有一些控件没有这个属性,如标签控件。没有这个属性就无法利用Windows API函数,但可以节省系统资源。
2.wMsg:
被发送的消息。根据具体需求和不同的对象,将不同的消息作为实参传送,以产生预期的动作。使SendMessage 传递消息,大多是为了完成以下几个工作:
①设置控件的一些选项,象我们要使用的CB_SETDROPPEDWIDTH的就属于这种情况。尽管VB的每个控件都提供了许多属性,但仍然有许多控件的选项没有包括在其中。而这些选项中的大多数都可以利用该函数进行设置。
②获得控件的一些设置。同上一种情况相反,有时我们需要获得控件的一些设置,相当于读取属性。例如,如果想知道一个下拉框的下拉部分的宽度是多少,就可以向控件发送CB_GETDROPPEDWIDTH消息。对于这种情况,SendMessage函数的返回值就是结果。
③执行一定的操作。例如,我们要在下拉框中寻找是否有"ABC"这个字符串,当然,我们可以编写一个循环,逐条比较看是否存在这样的字符串。如果使用API,我们只需要向下拉框发送CB_FINDSTRING消息,这条消息就会自动进行查找工作并返回结果。
④模拟用户操作。我们有时希望模拟用户的操作,比如关闭其他应用程序的窗口。其实只要我们能知道那个窗口的句柄,我们就可以发送WM_CLOSE消息给那个窗口,窗口接受到这条消息就会关闭,如同用户关闭窗口一样。
3.wParam、lParam:
附加的消息信息。这两个是可选的参数,用来提供关于wMsg消息更多的信息,不同的wMsg可能使用这两个参数中的0、1或2个,如果不需要哪个附加参数,则将实参赋为NULL(在VB中赋为0)。lParam定义为Any类型。指定Any类型可禁止VB进行类型检查,从而允许将任意数据类型传递给该过程。由于每条消息对参数的类型和传递方式的要求都不同:有的可能要求为Long型,有的可能要求为自定义类型;大多数要求按传值方式传递,但也有一些要求按传地址方式传递。为了满足各种要求,我们将这个参数定义为Any类型。





2、拦截Windows消息(以下是捕获滚动条消息):

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As IntPtr,ByVal hWnd As IntPtr,ByVal Msg As Integer,ByVal wParam As IntPtr,ByVal lParam As IntPtr) As IntPtr //使用IntPtr类型为兼容32位和64位操作系统

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer) As IntPtr

Private Declare Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer) As IntPtr

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer,ByVal dwNewLong As MyWindowProcHandle) As IntPtr

Private Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As IntPtr,ByVal dwNewLong As MyWindowProcHandle) As IntPtr

Private Declare Function GetScrollPos Lib "user32" (ByVal hWnd As IntPtr,ByVal nbar As Integer) As IntPtr

Private Const GWL_WNDPROC As Integer = (-4) ' set this const inorder to get address of window procedure by GetWindowLong function

Private Const WM_PAINT As Integer = &HF ' message of paint

Private _oldWndProc As IntPtr ' original address of window procedure

Private _hWnd As IntPtr ' handle of control(or window)

Private Const WM_MOUSEWHEEL = &H20A

Private Const WM_HSCROLL = &H114

Private Const WM_VSCROLL = &H115

Private Delegate Function MyWindowProcHandle(ByVal hwnd As IntPtr,ByVal uMsg As Integer,ByVal lParam As IntPtr) As IntPtr



' Call back function inorder to processes windows message.

Private Function MyWndProc(ByVal hWnd As IntPtr,ByVal lParam As IntPtr) As IntPtr

MyWndProc = CallWindowProc(_oldWndProc,hWnd,uMsg,wParam,lParam) ' let window process first

Dim hScroll As Integer = 0

Dim vScroll As Integer = 1

If uMsg = WM_MOUSEWHEEL OrElse uMsg = WM_VSCROLL Then

… do some thing when VScroll

ElseIf uMsg = WM_HSCROLL Then

… do some thing when HScroll

End If

End Function



Private Sub Hook()

_hWnd = Me.RichTextBox_RewriteRules.Handle

Try

_oldWndProc = GetWindowLongPtr(Me.RichTextBox_RewriteRules.Handle,GWL_WNDPROC)

Catch

_oldWndProc = GetWindowLong(Me.RichTextBox_RewriteRules.Handle,GWL_WNDPROC)

End Try

Dim delegateWndProc As New MyWindowProcHandle(AddressOf MyWndProc)

Try

SetWindowLongPtr(_hWnd,GWL_WNDPROC,delegateWndProc)

Catch

SetWindowLong(_hWnd,delegateWndProc)

End Try

Runtime.InteropServices.GCHandle.Alloc(delegateWndProc) End Sub

Private Sub UnHook()

'SetWindowLong(_hwnd,_oldWndProc)

End Sub



Private Sub Form_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.Load

_hWnd = Me.TextBox.Handle

Hook()

End Sub



关于CallWindowProc函数:该函数将消息信息传送给指定的窗口过程。

参数:

lpPrevWndFunc:指向前一个窗口过程的指针。若该值是通过调用GetWindowLong函数,并将该函数中的nlndex参数设为GWL_WNDPROC或DWL_DLGPROC而得到的,那么它实际上要么是窗口或者对话框的地址,要么就是代表该地址的句柄。

hWnd:指向接收消息的窗口过程的句柄。

Msg:指定消息类型。

wParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

IParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

返回值:返回值指定了消息处理结果,它与发送的消息有关。


关于GetWindowLong函数:该函数是在指定的窗口中获取信息。也可以在指定window内存偏移量的情况下获取32位值。注:要兼容32位和64位操作系统,请使用GetWindowLongPtr函数

关于SetWindowLong函数:该函数修改有关指定窗口的指定信息,并在该窗口的附加窗口内存中的指定偏移量处设置一个32位整型值。第一个参数是窗口句柄,用来指定窗口(控件);第二个参数是要修改的窗口信息(每个常量对应一种信息);第三个参数是要修改的窗口信息的替换值。例如:前面的代码用来截获textBox收到的消息,就要替换窗口过程(消息处理函数),所以将第二个参数设为GWL_WNDPROC(-4),表示要给窗口过程设置新地址(即:自己写个过程函数取代默认的窗口过程),新地址就是第三个参数,而窗口过程是一个过程(视为函数),第三个参数应该是一个函数地址,所以要用到回调函数,在VB.NET中不支持回调函数直接作为integer类型的参数传入,所以要用委托来调用回调函数,第三个参数填入一个自定义回调函数的委托delegateWndProc。用SetWindowLog函数调用新的窗口过程替换原来的窗口过程之后,还必须通过调用CallWindowsProc来将新窗口过程没有处理的任何消息传送到以前的窗口过程中。

最近在调68013A的上位机程序,用的是VB.NET。由于没有例程,完全靠自己摸索,过程可真叫生不如死。连个基于VB.NETAPI函数调用都搞不定,网上虽然有很多例子,但一一试过之后都不可行,不知哪些留贴的人怎么就能用(汗一个)。最后在MSDN里边搜啊搜,搜到了一个能用的,赶紧记录下来。

CreateFile()定义方式:

1. VB.NET定义方式:

Public Declare Auto Function CreateFile Lib "kernel32.dll" _

(ByVal lpFileName As String,ByVal dwDesiredAccess As Int32,_

ByVal dwShareMode As Int32,ByVal lpSecurityAttributes As IntPtr,_

ByVal dwCreationDisposition As Int32,ByVal dwFlagsAndAttributes As Int32,_

ByVal hTemplateFile As IntPtr) As IntPtr

2. VB6.0中定义方式

Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String,ByVal dwDesiredAccess As Long,ByVal dwShareMode As Long,lpSecurityAttributes As SECURITY_ATTRIBUTES,ByVal dwCreationDisposition As Long,ByVal dwFlagsAndAttributes As Long,ByVal hTemplateFile As Long) As Long

两者看起来差别不大,可用起来就差远了,用VB6.0的定义方式在VB.NET中完全行不通,不知为什么前后两版本兼容性如此糟糕。

最后讲讲调用方法

Public Const GENERIC_READ = &H80000000

Public Const GENERIC_WRITE = &H40000000

Public Const OPEN_EXISTING = 3

result = CreateFile(driverName,GENERIC_READ Or GENERIC_WRITE,(FILE_SHARE_READ Or FILE_SHARE_WRITE),OPEN_EXISTING,0)

http://support.microsoft.com/kb/823179

猜你在找的VB相关文章