Navigation:  Tutorial >

The XppCbk.exe callback compiler

Previous pageReturn to chapter overviewNext page

xppcbk.exe generate a OBJ from a simple syntax script allowing your Xbase++ functions act as true callbacks in any API that require a callback pointer.

 

In this example we will use the winapi function EnumWindows() that require a pointer to a custom __stdcall function with the following prototype.

 

BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam);

 

Because Xbase++ functions cannot be called directly like a C function we will need a intermediate function that fulfill the required prototype and act as a proxy between the caller function and our Xbase++ function.

 

And this is just the task of our callback compiler so as the first we will create a cbk script file that will produce a .obj with the callback proxy function.

 

 

// ---------  CALLBACKS.CBK  --------- 

BEGIN CALLBACK MyEnumWndProc AS BOOL

   PARAM HANDLE   // hWnd

   PARAM DWORD    // dwCargo

END CALLBACK                   

// ------------------------------- 

 

Then in our build.bat or from the command line we call the callback compiler to get callbacks.obj from callbacks.cbk ready to be linked or included in our project.

 

C:\sample>XPPCBK CALLBACKS.CBK

Callback Compiler for Xbase++ Ver 1.0

(c) Pablo Botella Navarro. (2006) http://www.xbwin.com

Compiling CALLBACKS.CBK ...

flat assembler  version 1.64

3 passes, 1216 bytes.

C:\sample>

 

Now we can start writing our PRG

 

// ------------  TEST.PRG  ------------ 

#include  "ot4xb.ch"

// ------------------------------------ 

function Main()

? EnumWindows( _callback_MyEnumWndProc() , 0 )

 

The function _callback_MyEnumWndProc() will return a pointer to our proxy function.

 

 

inkey(0)

return NIL

// ------------------------------------ 

DLL USER32 IMPORT BOOL EnumWindows( POINTER32 fpEnum, LPARAM lp)

// ------------------------------------ 

DLL USER32 IMPORT int GetWindowText( HWND hWnd,LPSTR pStr, int nSize) ;

                       SYMBOL GetWindowTextA

// ------------------------------------ 

 

The next step will be to create our Xbase++ called function.

 

function MyEnumWndProc( hWnd , nCargo )

local cBuffer := ChrR(0,256)

local nLen    := GetWindowText(hWnd,@cBuffer,256)

local cStr    := Left(cBuffer,nLen)

if !Empty( cStr ) 

   ? ConvToOemCP( cStr)

end

return .T.

// ------------------------------------ 

 

The proxy function will call our MyEnumWndProc() providing the 2 parameters and will pass back the return value of MyEnumWndProc() as the result of the proxy callback.

 

Now our project file will be something like this:

 

// ------------  TEST.XPJ  ------------ 

[PROJECT]

    COMPILE       = xpp

    COMPILE_FLAGS = /n/m/w

    GUI           = yes

    LINKER        = alink

    PROJECT.XPJ

 

[PROJECT.XPJ]

    Test.exe

 

[Test.exe]

Test.prg 

callbacks.obj