vb.net回调函数,VB函数调用
VB.net 中创建线程时,线程所要执行的 任务函数 怎么实现后期定义(就像回调函数一样的)?
这个线程对象一定有个完成时或者进行中的动作,你可以用AddHandler语句来将过程委托给ProcessChanged或者ProcessConpleted动作。
创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的秦皇岛网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
求vb.net句柄实例,实现操作其他程序窗口。如我给的例子
Imports System.Text
Imports System.Runtime.InteropServices
Public Class Form1
' 相关API函数声明,注释掉的这里没用到,但是也比较常用吧,这些函数的功能都能搜到。
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
Private Delegate Function EnumChildProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumChildProc, ByVal lParam As Integer) As Boolean
Private Declare Auto Function SendMessage Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
'Private Declare Function CheckDlgButton Lib "user32" Alias "CheckDLGButtonA" (ByVal hDlg As IntPtr, ByVal nIDButton As IntPtr, ByVal wCheck As Integer) As Integer
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
'Private Declare Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As IntPtr, ByVal lpdwProcessId As Long) As Integer
Private Declare Auto Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLength" (ByVal hwnd As IntPtr) As Integer
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
' 相关消息定义,也有没用到的
Const WM_SETTEXT = HC
Const WM_GETTEXT = HD
'Const WM_SETFOCUS = H7
'Const WM_KILLFOCUS = H8
'Const WM_CLOSE = H10
'Const WM_SYSCOMMAND = H112
'Const SC_CLOSE = HF060
'Const SC_MINIMIZE = HF020
Const BM_GETCHECK = HF0
Const BM_SETCHECK = HF1
Const BM_GETSTATE = HF2
Const BM_SETSTATE = HF3
Const BM_SETSTYLE = HF4
Const BM_CLICK = HF5
'Const BM_GETIMAGE = HF6
'Const BM_SETIMAGE = HF7
Const BST_UNCHECKED = O0
Const BST_CHECKED = O1
Const BST_INDETERMINATE = O2
' 储存窗口句柄
Dim WindowHandle As IntPtr
' 储存两个(或者多个)编辑框句柄
Dim EditHandle As New List(Of IntPtr)
Dim EditWindowsText As List(Of String)
' 储存复选框句柄
Dim CheckHandle As IntPtr = 0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Button1_Click(sender, e)
End Sub
' EnumChildWindows 回调函数,该函数名作为API函数EnumChildWindows 的一个参数
' 该函数实现了枚举各个子窗口,找出编辑框属性的功能
Public Function EnumChildProcC(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
Dim dwWindowClass As StringBuilder = New StringBuilder(100)
' 获得某一个句柄的类名
GetClassName(hwnd, dwWindowClass, 100)
If dwWindowClass.ToString.Contains("EDIT") Or dwWindowClass.ToString.Contains("Edit") Then ' 类名包含EDIT的为编辑框
EditHandle.Add(hwnd) ' 存储该句柄
End If
' 返回 True 一直枚举完
Return True
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
WindowHandle = FindWindow(vbNullString, "登陆")
If WindowHandle.ToInt32 = 0 Then
MsgBox("未捕获到窗口" + "登陆")
Return
End If
' 枚举所有主窗口的子窗口(控件),枚举时自动调用回调函数,完成编辑框句柄的获取
EnumChildWindows(WindowHandle, AddressOf EnumChildProcC, 0)
' 寻找复选框
CheckHandle = FindWindowEx(WindowHandle, IntPtr.Zero, vbNullString, "记住密码")
Dim str As New StringBuilder
Dim j As Integer = 0
' 对编辑框文本赋值
For j = 0 To EditHandle.Count - 1
SendMessage(EditHandle(j), WM_SETTEXT, 0, "Text")
'GetWindowText(EditHandle(j), str, 20)
'EditWindowsText.Add(Str.ToString)
'Str.Clear()
Next
If EditHandle.Count = 0 Then
MsgBox("未找到输入框!")
End If
If CheckHandle.ToInt32 0 Then
'CheckDlgButton(WindowHandle, id, 1)
' 对复选框进行鼠标单击操作
SendMessage(CheckHandle, BM_CLICK, 0, 0)
'SendMessage(CheckHandle, BM_SETCHECK, True, 0)
End If
End Sub
End Class
vb.net问题:如何将回调函数中取得的结果返回到主程序
你先定义一个公用变量
将你获得的hwdn传递到这个公用变量上
再调用这个公用变量不久可以了么
VB.NET Socket通信 回调函数里的数据无法显示到界面控件内
a+=1; 这条指令必须在dosomething()方法执行完毕返回结果后才可以执行,否则就乱了套
异步:异步概念和同步相对,当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者(百度上抄的)。理解了同步概念后异步也就不难理解了,以javascript的ajax为例
ajax(arg1,arg2,function(){
//回调函数
a=3;
});
a=4;
这个代码段执行完成后一般情况会把a赋值为3而不是4,因为在ajax方法调用后,a=4;这条语句并没有等待ajax()返回结果就执行了,也就是在ajax()执行完成调用回调函数之前,a=4;已经执行了,回调函数再把a赋值为3使之成为最后结果,为此在ajax调用中我们经常会使用回调函数,其实在很多异步处理中我们都会使用到回调函数。
阻塞
阻塞操作是指,在执行设备操作时,若不能获得资源,则进程挂起直到满足可操作的条件再进行操作。
vb的回调函数转为vb.NET
先声明一个委托:
Public Delegate Function EnumChildProc(hwnd As Integer, iParam As Integer) As Integer
然后才能使用回调函数,回调函数的参数要和委托完全一致。
然后那个 API 函数需要这样声明:
Declare Function EnumChildWindows Lib "user32" (hWndParent As Integer, lpEnumFunc As EnumChildProc, lParam As Integer) As Integer
vb.net 中的异步委托机制,最好有相关的详细资料讲解,我是新手
所谓的委托(Delegate)实际上就是和C/C++里面的函数指针差不多,只是增强了类型检查等其它健壮性方面的内容。异步调用的回调函数有格式要求,所谓格式要求就是参数数量及类型顺序的要求,具体是什么样的你要看文档了。一般.NET Framework里面都是AsyncCallBack。
所谓异步编程,就是说你要求做某样事情,但是在完成这件事之前,我能接着做下一件事,而当这件事情完成之后,能够有一种机制通知我完成了。相反,在完成之前一直等待,直到完成了才能进行下一步操作,叫做同步。一般来说,我们平常写的程序都是“同步”,或者成为“顺序执行”更加贴切,而“异步”则可以说是“乱序执行”的。
可以看到,同步的代码非常好写,因为我们可以预测执行的顺序和情况。而异步就不是很好写了,因为无法得知完成的时候我正在做什么、做到什么程度。过去写这些代码是比较麻烦的,实现的办法就是自己建立一个处理异步事物的线程,然后在这个线程和主线程之间建立联系。而现在这个过程大部分已经被系统封装起来了,你只要调用BeginXXX,系统就会为你自动建立一个新的线程处理这个事情,当前线程不阻塞,可以马上进行下一项操作,于是就实现了“异步”了。但是从前面我讲道的你就应该知道,开始异步操作并没有完事,还需要能够得知操作完成,并能够进行相应的处理。于是你在调用BeginXXX的时候就需要传递一个回调函数,在.NET里是以委托的方式传递的。回调函数的意思就是“回过头来调用你”,或者说A调用B并且传递函数C的地址,于是B在指定的情况下调用A指定的函数C。现在就应该明白这个回调函数在BeginXXX中的作用就是,当你指定的事情做完之后将会调用这个回调函数。
在这个回调函数里面,我们就可以进行一些后续的工作,例如接着进行性质相同的工作,或者相应的处理。在这里,我们也许向知道刚才那件事情执行的情况和结果,这个时候我们就可以通过EndXXX来获得这些东西。说到这里,结合上面说到的AsyncCallBack以及随便哪个BeginXXX,我们可能会对下列两个东西感到困惑:
IAsyncResult
stateObject
首先说IAsyncResult,这个是一个接口,你在回调函数中通过参数获得的对象具体是什么类型的一般我们不需要关心,我们只需要依照这个接口的定义进行访问就可以了。简单点说,这个接口规定了顺利完成异步操作所需信息的最小集合。一般来说,我们需要通过这个参数(ar)来识别异步操作。比如说,你在一瞬间发起一百个“从不同的网络连接获取数据”的异步请求,当某一个请求被完成的时候,如何判断是那个请求被完成呢?就是依靠回调函数的参数ar。实际上你一般是不需要参与判断的,你只要将这个ar传递给EndXXX就可以了,EndXXX会根据这个ar自行判断的。需要注意的是,这个ar就是你调用BeginXXX的时候的返回值,可以说是一个存根,如果你需要在完成操作前终止他,也可以通过将这个存根传递给EndXXX,EndXXX就会根据情况终止操作。(IAsyncResult里面的IsCompleted提供了是否已经完成的判断,EndXXX就是根据这个值决定是否有必要终止。当然,你不需要关心他。)
接下来我们看看stateObject,这个东西被称为状态对象。于是大家就可能奇怪了:那个ar不也是状态吗?实际上stateObject是一个留给用户使用的东西,BeginXXX/EndXXX根本就不使用。这个stateObject会被装到ar的AsyncState里面,也就是说这个stateObject可以随时通过访问存根(BeginXXX的返回值)或者回调函数里的ar得到,你完全没必要额外的保存到什么地方,更不需要费神的去考虑如何和你的某个异步操作对应起来。说了半天,这个东西有什么用呢?你想怎么用就怎么用呗,发挥一下你的想象力。比如说,你可以保存这是第几次操作,或者在多个异步操作之间要同步的时候可以作为信号旗,再或者直接是操作这个异步操作的对象(x.BeginXXX的时候将x传递到stateObject参数上)。
第一种用法有点多余,第二种用法有点复杂,第三种我用得最多。因为你很可能在协一个服务端,而服务段必须能够响应多个客户端,这决定了必须用异步。同时,对于多个客户端必然有多个对象,例如网络连接的时候可能是Socket。而实际上处理的方法或者协议是和具体哪个客户端没有关联的,因此我们只需要一套处理程序就够了。这个时候第三种用法就很有用处,我们完全可以把代码写成这样:
Sub DataReceived(ByVal ar As IAsyncResult)
ar.AsyncState.EndReceive(ar)
ar.AsyncState.BeginReceive(... , ar.AsyncState)
End Sub
这样就不需要额外的数据结构去记录有那些正在活动的对象了。
分享文章:vb.net回调函数,VB函数调用
链接地址:http://pwwzsj.com/article/hescch.html