| **Navigation:**  [[introduction.htm|Language Reference]] > 13 - Built-in Functions >====== CALLBACK (register or unregister a FileCallBackInterface) ====== | [[call call procedure from a dll .htm|{{btn_prev_n.gif|Previous page}}]][[introduction.htm|{{btn_home_n.gif|Return to chapter overview}}]][[center return centered string .htm|{{btn_next_n.gif|Next page}}]] | | || {{newc7.jpg|NewC7.jpg}} **CALLBACK(**//entity//, //FileCallBackInterface//, [//flag//]**)** {{blk2blue.jpg|blk2blue.jpg}} | **CALLBACK** | Register or unregister a FileCallBackInterface. | | //Entity// | The label of a FILE or VIEW. | | //FileCallBackInterface// | The label of the interface that implements the [[driverops.htm|FileCallBackInterface]]. The methods of the FileCallbackInterface are called automatically before (method FunctionCalled) and after (method FunctionDone) each file operation. | | //Flag// | An integer constant, variable, EQUATE, or expression that indicates whether or not to unregister an interface associated with a FILE or VIEW. A value of one (1 or TRUE) unregisters the interface. If omitted, the interface is registered with the //entity.// | The **CALLBACK** method registers a callback interface with the specified //entity//. The methods of the registered interface are called whenever a file operation is done. Multiple interfaces can be registered with an entity. To unregister an interface, set the //flag //to TRUE. Any registered interfaces must be unregistered before the object that implements the interface is removed. If a VIEW has callbacks registered with it and the primary FILE of that VIEW also has callbacks registered, then all the callbacks registered for the VIEW are called //before// the callbacks for the primary FILE. To distinguish if a callback method is being called by a FILE operation or a VIEW operation you need to check the new Params.View field. It will be NULL for FILE operations and equal to the VIEW that is being used for VIEW operations. **Example:** **PROGRAM** **    MAP** **    END** **    INCLUDE ('FILECB.INC'),ONCE** **!Data file** **People      FILE,DRIVER('TOPSPEED'),PRE(PEO),CREATE,BINDABLE,THREAD** **KeyId       KEY(PEO:Id),NOCASE,OPT** **KeyLastName KEY(PEO:LastName),DUP,NOCASE** **Record       RECORD,PRE()** **Id            LONG** **FirstName     STRING(30)** **LastName      STRING(30)** **Gender        LONG** **             END** **            END** **!Log File** **LogFile     FILE,DRIVER('BASIC','/ALWAYSQUOTE=OFF /COMMA=1,1'),CREATE,NAME('logfile.txt')** **Record       RECORD** **Operation     STRING(200)** **             END** **            END** **!FileCallBack Class** **FCB CLASS,IMPLEMENTS(FileCallBackInterface)** **    END** **    CODE** **   ****CALLBACK****(People, FCB.FileCallBackInterface) !Register FCB interface** **    CREATE(Logfile)                             !Create log file** **    OPEN(Logfile)                               !Open log file** **    OPEN(People)                                !Open data file** **    SET(PEO:KeyId, PEO:KeyID)                   !Set and ** **     LOOP                                       !loop thru** **      NEXT(People)                              !data until** **      IF ERRORCODE()** **       BREAK                                    !end of file** **      END** **     END** **    CLOSE(People)                               !Close data file** **!Unregister FCB interface:** ** ****CALLBACK****(People, FCB.FileCallBackInterface, TRUE)** **!This method is called prior to each operation of the data file.** **!The log file is updated with the file operation that is being executed.** **FCB.FileCallBackInterface.FunctionCalled |** **   PROCEDURE(SIGNED opCode, *Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)** **p LIKE(Params)** **  CODE** **    p = Parameters** **    IF p.View &= NULL !used to detect VIEW or FILE callback** **      f = 'FILE'** **    ELSE** **      f = 'VIEW'** **    END** **    CASE opCode** **    OF DriverOp:ADD** **      logFile.Operation = 'ADD(f)'** **    OF DriverOp:APPEND** **      logFile.Operation = 'APPEND(f)'** **    OF DriverOp:CLOSE** **      logFile.Operation = 'CLOSE(f)'** **    OF DriverOp:COPY** **      logFile.Operation = 'COPY(f,'''&CLIP(Parameters.Text)&''')'** **    OF DriverOp:CREATE** **      logFile.Operation = 'CREATE(f)'** **    OF DriverOp:DELETE** **      logFile.Operation = 'DELETE(f)'** **    OF DriverOp:NEXT** **      logFile.Operation = 'NEXT(f)'** **    OF DriverOp:OPEN** **      logFile.Operation = 'OPEN(f,'&Parameters.openMode&')'** **    OF DriverOp:PUT** **      logFile.Operation = 'PUT(f)'** **    OF DriverOp:SETkeykey** **      logFile.Operation = 'SET(k,k)'** **    END** **    ADD(logFile)** **    RETURN TRUE** **!This method is called after each operation to the data file.** **!This simply returns a TRUE according to the rules of the FileCallBackInterface.** **FCB.FileCallBackInterface.FunctionDone |** **    PROCEDURE(SIGNED opCode, Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)** **  CODE** **    RETURN TRUE** __**Additional Example:**__ **  PROGRAM** **  INCLUDE('FILECB.INC')** **  MAP** **    viewTest(VIEW v)** **    check(STRING msg)** **    Test(STRING Name, FILE log, FILE f, VIEW v1, VIEW v2)** **  END** **Dept FILE,DRIVER('Memory'),NAME('DEPT'),PRE(DEP),CREATE** **PK_DEPT KEY(DEP:DEPTNO),PRIMARY** **Record  RECORD** **DEPTNO    BYTE** **DNAME     CSTRING(15)** **LOC       CSTRING(14)** **        END** **      END** **LogFile FILE,DRIVER('ASCII'),CREATE,NAME('CB.LOG')** **Record   RECORD** **Line      STRING(100)** **         END** **        END** **MyClass CLASS,IMPLEMENTS(FileCallBackInterface),TYPE** **Name     CSTRING(30),PRIVATE** **logf     &FILE,PRIVATE** **baseF    &FILE,PRIVATE** **line     ANY,PRIVATE** **inView   BOOL,PRIVATE** **Init     PROCEDURE(STRING n, FILE f, FILE log)** **Kill     PROCEDURE()** **        END** **MemoryFile MyClass** **ISAMView   MyClass** **iView1 VIEW(Dept).** **iView2 VIEW(Dept).** **  CODE** **  CREATE(LogFile)** **  Check('Create LogFile')** **  OPEN(LogFile)** **  Check('OPEN LogFile')** **  MemoryFile.Init('Memory', Dept, LogFile)** **  ISAMView.Init('ISAMView', iView1, LogFile)** **  CREATE(Dept)** **  Check('Create Dept')** **  Test('Memory', LogFile, Dept, iView1, iView2)** **  MemoryFile.Kill()** **  ISAMView.Kill()** **  MESSAGE('Done')** **viewTest PROCEDURE(VIEW v)** **  CODE** **    OPEN(v)** **    SET(v)** **    NEXT(v)** **    CLOSE(v)** **Check PROCEDURE(STRING msg)** **  CODE** **   IF ERRORCODE()** **    IF ERRORCODE() = 90** **     HALT(1, msg & ' caused system error ' & FILEERRORCODE() & ' : ' |** **          & FILEERROR())** **    END** **    HALT(1, msg & ' caused error ' & ERRORCODE() & ' : ' & ERROR())** **   END** **Test PROCEDURE(STRING msg, FILE log, FILE f, VIEW v1, VIEW v2)** **g   &GROUP** **l   ANY** **  CODE** **   g &= log{PROP:Record}** **   l &= WHAT(g, 1)** **   l = '!File Operations'** **   ADD(log)** **   OPEN(f)** **   Check(msg & ' OPEN')** **   SET(f)** **   NEXT(f)** **   l = '!View 1 Operations'** **   ADD(log)** **   viewTest(v1)** **   l = '!View 2 Operations'** **   ADD(log)** **   viewTest(v2)** **   l = '!Done'** **   ADD(log)** **   CLOSE(f)** **MyClass.Init      PROCEDURE(STRING n, FILE f, FILE log)** **g &GROUP** **  CODE** **   CALLBACK(f, SELF.FileCallBackInterface)** **   SELF.logf &= log** **   SELF.basef &= f** **   SELF.Name = CLIP(n)** **   g &= SELF.logf{PROP:Record}** **   SELF.line &= WHAT(g, 1)** **MyClass.Kill  PROCEDURE()** **  CODE** **   CALLBACK(SELF.baseF, SELF.FileCallBackInterface, TRUE)** **   Check('Uncallback ' & SELF.Name)** **   SELF.line &= NULL** **MyClass.FileCallBackInterface.FunctionCalled  PROCEDURE(SIGNED opCode, |** ***Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)** **p     LIKE(Params)** **f     CSTRING(5),AUTO** **logit BOOL(true)** **  CODE** **   p = Parameters** **   IF p.View &= NULL** **    f = 'FILE'** **   ELSE** **    f = 'VIEW'** **   END** **   CASE opCode** **   OF DriverOp:Create** **    SELF.line = 'CREATE(' & f & ' ' & SELF.Name & ')'** **   OF DriverOp:NEXT** **    SELF.line = 'NEXT(' & f & ' ' & SELF.Name & ')'** **   OF DriverOp:OPEN** **    SELF.line = 'OPEN(' & f & ' ' & SELF.Name & ','&Parameters.openMode&')'** **   OF DriverOp:PUT** **    SELF.line = 'PUT(' & f & ' ' & SELF.Name & ')'** **   OF DriverOp:VIEWSTART** **    SELF.InView = TRUE** **    logit = FALSE** **   OF DriverOp:VIEWSTOP** **    SELF.InView = FALSE** **    logit = FALSE** **   ELSE** **    logit = FALSE** **   END** **   IF logit AND ~SELF.InView** **    ADD(SELF.logF)** **   END** **   RETURN TRUE** **MyClass.FileCallBackInterface.FunctionDone |** **    PROCEDURE(SIGNED opCode, Params Parameters, *CSTRING ErrCode, |** **              *CSTRING ErrMsg)** **  CODE** **   RETURN TRUE** The program above will produce a log file that looks like this: **CREATE(FILE Memory)** **!File Operations** **OPEN(FILE Memory,34)** **NEXT(FILE Memory)** **!View 1 Operations** **OPEN(FILE ISAMView,34)** **OPEN(VIEW Memory,34)** **NEXT(FILE ISAMView)** **NEXT(VIEW Memory)** **!View 2 Operations** **OPEN(VIEW Memory,34)** **NEXT(VIEW Memory)** **!Done** **See Also:** [[driverops.htm|FileCallbackInterface]] [[adm14 triggers.htm|Trigger Properties]]