    '
    ' ------------------------------------------------------------------------
    ' MULTIPLE CALLBACK UNDER RAPIDQ      Text  Documentation       by Jacques
    '
    ' September 25rd, 2005
    ' August 13th, 2006
    ' This turn around was a group work. Thanks to John, Paul and Warriant
    ' ------------------------------------------------------------------------
    '
    ' ------------------------------------------------------------------------
    ' A Short Example is Better than a long Theory for a Four Arguments CallBack
    ' The Extra Argument not counted
    ' ------------------------------------------------------------------------
    ' $Include "CallBack_4.Inc"        ' _4 may be _0, _1, ..., _8   = Nbr of arguments of Your CallBack
    '
    ' Function UserCallBackFunctionName (A1 As Long, A2 As Long, A3 as Long , A4 As Long) As Long
    '     ' nice efficient code
    ' End Function
    '
    ' DefInt iAnyName
    ' Bind iAnyName To UserCallBackFunctionName            ' iAnyName maybe reused but in some case not
    ' DefInt lpfnCallBack = SetNewCallBack_4 (iAnyName)    ' _4 = Nbr of arguments of your CallBack
    '
    ' ------------------------------------------------------------------------
    ' That's it
    '
    ' CallBack_x.Inc automatically include CallBackForwarder.Inc if not yet included.
    ' LIMITATIONS :
    '   - _4 Can be _1, _2, _3, _4, _5, _6, _7, _8  for  1,2,3,4,4,6,7,8 Arguments
    '   - There is no maximum number of callback anymore
    '   - Any Use of the RapidQ CodePtr Word will DEEPLY harm this
    '     !!!!!!!!!!  YOU CANNOT USE CODEPTR ANYMORE  !!!!!!!!!!!!!
    '     RapidQ allows only one CodePtr for Each Function Prototype, if
    '     two CodePtr are used to point 4 arguments functions, the latter
    '     will overwrite the former (See CallBackBugDemo.Bas).
    ' ----------------------------------------------------------------------------------
    ' ----------------------------------------------------------------------------------
    ' HOW IT WORKS :
    ' ----------------------------------------------------------------------------------
    '  - the external process calls the CallBack Forwarder
    '  - the callback forwarder forwards the Caller to the master callback function
    '    (i.e MasterCallBack_4 in CallBack_4.Inc). It adds a first argument which is an
    '    the RapidQ handle of the RqFunction to forward to (Bind RqFuncHandle To YourCallBackFunc).
    '  - the master callback use CallFunc to Call the User CallBack. The Master Callback
    '    is built in the callback_X Include file.
    '
    '  The Programmer Must (example for a 4 arguments CallBack):
    '    1 - Get the RapidQ Function Handle of his CallBack Function
    '          DefInt hRqFunction
    '          Bind hRqFunction To RqCallBackFunction
    '    2 - Create a CallBack Forwarder for his CallBack by calling
    '      lpfnCallBackForwarder = SetNewCallBack_4 (hRqFunction)
    '      lpfnCallBackForwarder returned by SetNewCallBack_4 is the address/lpfn
    '      you have to pass to the external process.
    ' **********************************************************************************
    ' ---- CallBack Forwader Documentation ---------------------------------------------
    ' The CallBack Forwarder Code (14 bytes) will be Generated in an allocated memory space,
    ' the pointer to that space is returned by the function.
    ' ForwardTo : a function pointer to our callback funtion (+ one one : first = CallBack
    '             Index you choose)
    ' CBIndex   : a user choosen number to identify this CallBack forwarder
    ' --- CallBack Forwarder Nasm Assembler code ---- Nasm List ------------------------
    ' ----------------------------------------------------------------------------------
    '  Offset   Hexadecimal   Cycles  Memory     Mnemonic                Comments
    ' decimal   Code         486 CPU
    ' ----------------------------------------------------------------------------------
    '    0000   58                 1       1     pop    eax              ; eax = return address
    '    0001   68DDCCBBAA         4       2     push   dword CBIndex    ; CBIndex 5th Argument
    '    0005   50                 1       1     push   eax              ; return address back on the stack
    '    0007   B8DDCCBBAA         1       1     mov    eax, ForwardTo   ; eax = lpfnForwardTo
    '    0012   FFE0               5       0     jmp    eax              ; Goto lpfnForwardTo
    ' ----------------------------------------------------------------------------------
    ' tot: 14                     12       5
    ' ----------------------------------------------------------------------------------
    ' The job is done in 12 processor cycles and 5 memory access ! For a 2GHz processor
    ' it will take 6 billionth of a second + 5 memory access whose duration are unpredictable.
    ' ----------------------------------------------------------------------------------
    ' **********************************************************************************
    '