1、发送Windows消息:@H_403_1@ @H_403_1@ 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@H_403_1@ @H_403_1@ Private Const EM_SETTEXT = &HC ' VB中&H表示16进制@H_403_1@ @H_403_1@ 'Private Const WM_GETTEXT = &HC@H_403_1@ @H_403_1@ @H_403_1@ 'Sendmessage(目标控件句柄,自定义消息类型,参数个数,消息内容)@H_403_1@ @H_403_1@ SendMessage(Form1.Text.Handle,EM_SETTEXT,"heyinjie")@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ 函数原型: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)@H_403_1@ @H_403_1@ 其中四个参数的含义和说明如下:@H_403_1@ @H_403_1@ 1.hWnd:@H_403_1@ 对象的句柄。希望将消息传送给哪个对象,就把该对象的句柄作为实参传送,在VB中可以简单地用"对象.hWnd"获得某个对象的句柄,如Text1.hWnd和 Form1.hWnd分别可以得到 Text1和Form1的句柄。它是一个长整型数。Windows给每个控件一个编号,这个编号就称为窗口句柄。有了这个句柄,我们就可告诉 Windows 我们要控制哪个控件,所以这个句柄在 API 调用中至关重要。VB 的大多数控件都包括hwnd属性,如下拉框、TreeView等,窗体也有这个属性。但也有一些控件没有这个属性,如标签控件。没有这个属性就无法利用Windows API函数,但可以节省系统资源。@H_403_1@ 2.wMsg:@H_403_1@ 被发送的消息。根据具体需求和不同的对象,将不同的消息作为实参传送,以产生预期的动作。使SendMessage 传递消息,大多是为了完成以下几个工作:@H_403_1@ ①设置控件的一些选项,象我们要使用的CB_SETDROPPEDWIDTH的就属于这种情况。尽管VB的每个控件都提供了许多属性,但仍然有许多控件的选项没有包括在其中。而这些选项中的大多数都可以利用该函数进行设置。@H_403_1@ ②获得控件的一些设置。同上一种情况相反,有时我们需要获得控件的一些设置,相当于读取属性。例如,如果想知道一个下拉框的下拉部分的宽度是多少,就可以向控件发送CB_GETDROPPEDWIDTH消息。对于这种情况,SendMessage函数的返回值就是结果。@H_403_1@ ③执行一定的操作。例如,我们要在下拉框中寻找是否有"ABC"这个字符串,当然,我们可以编写一个循环,逐条比较看是否存在这样的字符串。如果使用API,我们只需要向下拉框发送CB_FINDSTRING消息,这条消息就会自动进行查找工作并返回结果。@H_403_1@ ④模拟用户操作。我们有时希望模拟用户的操作,比如关闭其他应用程序的窗口。其实只要我们能知道那个窗口的句柄,我们就可以发送WM_CLOSE消息给那个窗口,窗口接受到这条消息就会关闭,如同用户关闭窗口一样。@H_403_1@ 3.wParam、lParam:@H_403_1@ 附加的消息信息。这两个是可选的参数,用来提供关于wMsg消息更多的信息,不同的wMsg可能使用这两个参数中的0、1或2个,如果不需要哪个附加参数,则将实参赋为NULL(在VB中赋为0)。lParam定义为Any类型。指定Any类型可禁止VB进行类型检查,从而允许将任意数据类型传递给该过程。由于每条消息对参数的类型和传递方式的要求都不同:有的可能要求为Long型,有的可能要求为自定义类型;大多数要求按传值方式传递,但也有一些要求按传地址方式传递。为了满足各种要求,我们将这个参数定义为Any类型。@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ 2、拦截Windows消息(以下是捕获滚动条消息):@H_403_1@ @H_403_1@ 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位操作系统@H_403_1@ @H_403_1@ Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer) As IntPtr@H_403_1@ @H_403_1@ Private Declare Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer) As IntPtr@H_403_1@ @H_403_1@ Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As IntPtr,ByVal nIndex As Integer,ByVal dwNewLong As MyWindowProcHandle) As IntPtr@H_403_1@ @H_403_1@ Private Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As IntPtr,ByVal dwNewLong As MyWindowProcHandle) As IntPtr@H_403_1@ @H_403_1@ Private Declare Function GetScrollPos Lib "user32" (ByVal hWnd As IntPtr,ByVal nbar As Integer) As IntPtr@H_403_1@ @H_403_1@ Private Const GWL_WNDPROC As Integer = (-4) ' set this const inorder to get address of window procedure by GetWindowLong function@H_403_1@ @H_403_1@ Private Const WM_PAINT As Integer = &HF ' message of paint@H_403_1@ @H_403_1@ Private _oldWndProc As IntPtr ' original address of window procedure@H_403_1@ @H_403_1@ Private _hWnd As IntPtr ' handle of control(or window)@H_403_1@ @H_403_1@ Private Const WM_MOUSEWHEEL = &H20A@H_403_1@ @H_403_1@ Private Const WM_HSCROLL = &H114@H_403_1@ @H_403_1@ Private Const WM_VSCROLL = &H115@H_403_1@ @H_403_1@ Private Delegate Function MyWindowProcHandle(ByVal hwnd As IntPtr,ByVal uMsg As Integer,ByVal lParam As IntPtr) As IntPtr@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ ' Call back function inorder to processes windows message.@H_403_1@ @H_403_1@ Private Function MyWndProc(ByVal hWnd As IntPtr,ByVal lParam As IntPtr) As IntPtr@H_403_1@ @H_403_1@ MyWndProc = CallWindowProc(_oldWndProc,hWnd,uMsg,wParam,lParam) ' let window process first@H_403_1@ @H_403_1@ Dim hScroll As Integer = 0@H_403_1@ @H_403_1@ Dim vScroll As Integer = 1@H_403_1@ @H_403_1@ If uMsg = WM_MOUSEWHEEL OrElse uMsg = WM_VSCROLL Then@H_403_1@ @H_403_1@ … do some thing when VScroll@H_403_1@ @H_403_1@ ElseIf uMsg = WM_HSCROLL Then@H_403_1@ @H_403_1@ … do some thing when HScroll@H_403_1@ @H_403_1@ End If@H_403_1@ @H_403_1@ End Function@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ Private Sub Hook()@H_403_1@ @H_403_1@ _hWnd = Me.RichTextBox_RewriteRules.Handle@H_403_1@ @H_403_1@ Try@H_403_1@ @H_403_1@ _oldWndProc = GetWindowLongPtr(Me.RichTextBox_RewriteRules.Handle,GWL_WNDPROC)@H_403_1@ @H_403_1@ Catch@H_403_1@ @H_403_1@ _oldWndProc = GetWindowLong(Me.RichTextBox_RewriteRules.Handle,GWL_WNDPROC)@H_403_1@ @H_403_1@ End Try@H_403_1@ @H_403_1@ Dim delegateWndProc As New MyWindowProcHandle(AddressOf MyWndProc)@H_403_1@ @H_403_1@ Try@H_403_1@ @H_403_1@ SetWindowLongPtr(_hWnd,GWL_WNDPROC,delegateWndProc)@H_403_1@ @H_403_1@ Catch@H_403_1@ @H_403_1@ SetWindowLong(_hWnd,delegateWndProc)@H_403_1@ @H_403_1@ End Try@H_403_1@ @H_403_1@ Runtime.InteropServices.GCHandle.Alloc(delegateWndProc) End Sub@H_403_1@ @H_403_1@ Private Sub UnHook()@H_403_1@ @H_403_1@ 'SetWindowLong(_hwnd,_oldWndProc)@H_403_1@ @H_403_1@ End Sub@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ Private Sub Form_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.Load@H_403_1@ @H_403_1@ _hWnd = Me.TextBox.Handle@H_403_1@ @H_403_1@ Hook()@H_403_1@ @H_403_1@ End Sub@H_403_1@ @H_403_1@ @H_403_1@ @H_403_1@ 关于CallWindowProc函数:该函数将消息信息传送给指定的窗口过程。@H_403_1@ @H_403_1@ 参数:@H_403_1@ @H_403_1@ lpPrevWndFunc:指向前一个窗口过程的指针。若该值是通过调用GetWindowLong函数,并将该函数中的nlndex参数设为GWL_WNDPROC或DWL_DLGPROC而得到的,那么它实际上要么是窗口或者对话框的地址,要么就是代表该地址的句柄。@H_403_1@ @H_403_1@ hWnd:指向接收消息的窗口过程的句柄。@H_403_1@ @H_403_1@ Msg:指定消息类型。@H_403_1@ @H_403_1@ wParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。@H_403_1@ @H_403_1@ IParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。@H_403_1@ @H_403_1@ 返回值:返回值指定了消息处理结果,它与发送的消息有关。@H_403_1@ @H_403_1@ @H_403_1@ 关于GetWindowLong函数:该函数是在指定的窗口中获取信息。也可以在指定window内存偏移量的情况下获取32位值。注:要兼容32位和64位操作系统,请使用GetWindowLongPtr函数。@H_403_1@ @H_403_1@ 关于SetWindowLong函数:该函数修改有关指定窗口的指定信息,并在该窗口的附加窗口内存中的指定偏移量处设置一个32位整型值。第一个参数是窗口句柄,用来指定窗口(控件);第二个参数是要修改的窗口信息(每个常量对应一种信息);第三个参数是要修改的窗口信息的替换值。例如:前面的代码用来截获textBox收到的消息,就要替换窗口过程(消息处理函数),所以将第二个参数设为GWL_WNDPROC(-4),表示要给窗口过程设置新地址(即:自己写个过程函数取代默认的窗口过程),新地址就是第三个参数,而窗口过程是一个过程(视为函数),第三个参数应该是一个函数地址,所以要用到回调函数,在VB.NET中不支持回调函数直接作为integer类型的参数传入,所以要用委托来调用回调函数,第三个参数填入一个自定义回调函数的委托delegateWndProc。用SetWindowLog函数来调用新的窗口过程替换原来的窗口过程之后,还必须通过调用CallWindowsProc来将新窗口过程没有处理的任何消息传送到以前的窗口过程中。
最近在调68013A的上位机程序,用的是VB.NET。由于没有例程,完全靠自己摸索,过程可真叫生不如死。连个基于VB.NET的API函数调用都搞不定,网上虽然有很多例子,但一一试过之后都不可行,不知哪些留贴的人怎么就能用(汗一个)。最后在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