Метод RegisterCallback
Этот метод нужен для получения указателя на скриптовую функцию, пригодного для передачи какой-либо функции API. Которая потом, используя этот указатель, могла бы данную скриптовую функцию вызывать. Пример такой API-функции — EnumWindows (см. код ниже). Она перебирает существующие окна и хэндл каждого окна передаёт callback-функции в качестве параметра. После этого она ждёт, что вернёт callback-функция. Если 1, то перебор идёт дальше, если 0 — прекращается.В JScript и VBScript функция является объектом, и ссылка на неё для таких целей не годится. Поэтому ссылка на скриптовую функцию сначала передаётся методу RegisterCallback, а API-функция получает возвращённый им указатель на одну из вспомогательных процедур внутри dynwrapx.dll, вызовы которой будут транслироваться в вызовы скриптовой функции, а возвращаемые значения — в обратном направлении.
В JScript ссылка на функцию — это её имя без скобок, а в VBScript сначала нужно использовать GetRef. Кроме ссылки на функцию задаются также типы её параметров и возвращаемого значения — аналогично методу Register (но используются только маленькие буквы).
По умолчанию соглашение вызова callback-функции будет stdcall, что подходит для Windows API. Если используется какая-то сторонняя библиотека, которой требуется соглашение вызова С (cdecl), это можно указать во флаговом параметре ("f=c").
Пример на JScript (VBScript см. ниже)
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 с передачей ей указателя на callback-функцию.
DWX.EnumWindows(pCbkFunc, 0);
DWX.MemFree(Buf);
WScript.Echo("Всего окон: " + m + "\nС заголовками: " + n +
"\n\n" + WinList);
// ............... Собственно callback-функция ....................
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 с передачей ей указателя на callback-функцию.
DWX.EnumWindows pCbkFunc, 0
DWX.MemFree Buf
WScript.Echo "Всего окон: " & m & vbCrLf & "С заголовками: " & n & _
vbCrLf & vbCrLf & WinList
' ................ Собственно callback-функция .......................
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