' ' ------------------------------------------------------------------------ ' 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 ' ------------------------------------------------------------------------ ' Note: ' All CallBack_X.Inc are fully compatible with all the other CallBack_X.Inc ' and with NewWndProc.Inc. You can include any or all of them in your code. ' CallBackAll.Inc includes all the CallBack_X.Inc and NewWndProc.Inc ' ------------------------------------------------------------------------ ' 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 hRqFunction ; hRqFunction 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. ' ---------------------------------------------------------------------------------- ' ********************************************************************************** '