Русский   Home

RegisterCallback method

This method takes a reference to a script function and transforms it into a pointer that can be passed to an API function. Then that API function can use this pointer to call the script function. EnumWindows, for example, requires such a pointer to a callback procedure for its work (see the code below). For each window that it finds, it calls the callback procedure, passing it the window handle. Then if the callback procedure returns 1, enumeration continues, and if 0, it stops.

A script function reference by itself cannot serve this purpose because functions in JScript and VBScript are objects and their references are pointers to IDispatch interfaces. So the reference is passed to RegisterCallback, and the API function receives a pointer to one of the intermediary procedures inside dynwrapx.dll, which will translate calls to the script function and transfer its return values back to the API function.

In JScript the name of a function (without parentheses) will serve as its reference, and in VBScript you will have to use GetRef beforehand. In addition to the function's reference, you may have to specify the types of its parameters (if any) and its return value — just as with the Register method (but only small letters can be used).

By default, the calling convention of the callback function will be stdcall, which is normal for Windows API. If you use a third-party DLL that requires the C calling convention (cdecl), you can specify it in the flag parameter ("f=c").

JScript (VBScript is further below)
DWX = new ActiveXObject("DynamicWrapperX");

DWX.Register("user32", "EnumWindows",    "i=ph");
DWX.Register("user32", "GetWindowTextW", "i=hpl");   // Unicode
// DWX.Register("user32", "GetWindowText", "i=hpl"); // ANSI

// Register CbkEnumWin as a callback procedure and get its pointer.
pCbkFunc = DWX.RegisterCallback(CbkEnumWin, "i=hh", "r=l");

n=0, m=0, WinList="";
Buf = DWX.MemAlloc(256); // Buffer for the window titles (an output string).

// Call EnumWindows and pass it the pointer to the callback procedure.
DWX.EnumWindows(pCbkFunc, 0);

DWX.MemFree(Buf);

WScript.Echo("Windows in total: " + m + "\nWith a title: " + n +
                                "\n\n" + WinList);


// ............... The callback function itself ....................

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; // Returning 0 will stop the calls.
}
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") ' Get a reference to the function.

' Register CbkEnumWin as a callback procedure and get its pointer.
pCbkFunc = DWX.RegisterCallback(Ref, "i=hh", "r=l")

n = 0 : m = 0 : WinList = ""
Buf = DWX.MemAlloc(256) ' Buffer for the window titles (an output string).

' Call EnumWindows and pass it the pointer to the callback procedure.
DWX.EnumWindows pCbkFunc, 0

DWX.MemFree Buf

WScript.Echo "Windows in total: " & m & vbCrLf & "With a title: " & n & _
              vbCrLf & vbCrLf & WinList


' ................ The callback function itself .......................

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 ' Returning 0 will stop the calls.
End Function