回调注册方法
此方法接受对脚本函数的引用,并将其转换为可以传递给 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