回调注册方法
此方法接受对脚本函数的引用,并将其转换为可以传递给 API 函数的指针。然后该 API 函数可以使用这个指针来调用脚本函数。例如,EnumWindows 需要这样一个指向回调函数的指针(参见下面的代码)。对于找到的每个窗口,它将调用回调函数,并将窗口句柄传递给它。如果回调过程返回 1,枚举继续,如果返回 0,枚举则停止。脚本函数引用本身无法达到此目的,因为 JScript 和 VBScript 中的函数是对象,它们的引用是指向 IDispatch 接口的指针。因此,引用被传递给 RegisterCallback,API 函数接收到一个指向 dynwrapx 中的中间过程的指针,它将转换对脚本函数的调用,并将其返回值传回 API 函数。
在 JScript 中,函数名(不带括号)将用作其引用,而在 VBScript 中,您必须事先使用 GetRef。除了函数的引用之外,您可能还必须指定其参数类型(如果有)及其返回值 —— 就像使用 Register 方法一样(但只能使用小写字母)。
默认情况下,回调函数的调用约定为 stdcall,这对于 Windows API 来说是正常的。如果您使用的第三方 DLL 需要 C 调用约定 (cdecl) ,您可以在标志参数 ("f=c") 中指定它。
JScript
DWX = new ActiveXObject("DynamicWrapperX"); DWX.Register("user32", "EnumWindows", "i=ph"); DWX.Register("user32", "GetWindowTextW", "i=hpl"); // Unicode // DWX.Register("user32", "GetWindowText", "i=hpl"); // ANSI // 将 CbkEnumWin 注册为回调过程并获取其指针。 pCbkFunc = DWX.RegisterCallback(CbkEnumWin, "i=hh", "r=l"); n=0, m=0, WinList=""; Buf = DWX.MemAlloc(256); // 窗口标题的缓冲区(输出字符串)。 // 调用 EnumWindows 并将指针传递给回调过程。 DWX.EnumWindows(pCbkFunc, 0); DWX.MemFree(Buf); WScript.Echo("窗口总数:" + m + "\n带标题:" + n + "\n\n" + WinList); // ................ 回调函数本身 ....................... function CbkEnumWin(hwnd, lparam) { var Title; DWX.GetWindowTextW(hwnd, Buf, 128); // Unicode Title = DWX.StrGet(Buf, "w"); //DWX.GetWindowText(hwnd, Buf, 256); // ANSI //Title = DWX.StrGet(Buf, "s"); if(Title.length > 0) { WinList += hwnd + "\t" + Title + "\n"; ++n; } ++m; return 1; // 返回 0 将停止调用。 }VBScript
Set DWX = CreateObject("DynamicWrapperX") DWX.Register "user32", "EnumWindows", "i=ph" DWX.Register "user32", "GetWindowTextW", "i=hpl" '支持 Unicode 格式宽字符编码 'DWX.Register "user32", "GetWindowText", "i=hpl" '支持 ANSI 编码 Set Ref = GetRef("CbkEnumWin") '获取对函数的引用。 '将 CbkEnumWin 注册为回调过程并获取其指针。 pCbkFunc = DWX.RegisterCallback(Ref, "i=hh", "r=l") n = 0 : m = 0 : WinList = "" Buf = DWX.MemAlloc(256) '窗口标题的缓冲区(输出字符串)。 ' 调用 EnumWindows 并将指针传递给回调过程。 DWX.EnumWindows pCbkFunc, 0 DWX.MemFree Buf WScript.Echo "窗口总数:" & m & vbCrLf & "带标题:" & n & _ vbCrLf & vbCrLf & WinList '................ 回调函数本身 ....................... Function CbkEnumWin(hwnd, lparam) DWX.GetWindowTextW hwnd, Buf, 128 ' Unicode Title = DWX.StrGet(Buf, "w") 'DWX.GetWindowText hwnd, Buf, 256 ' ANSI 'Title = DWX.StrGet(Buf, "s") If Len(Title) > 0 Then WinList = WinList & hwnd & vbTab & Title & vbCrLf n = n+1 End If m = m+1 CbkEnumWin = 1 '返回 0 将停止调用。 End Function