/* This is a dynamic link library that runs under Windows 3.00. Duties of this library include saving screen image to a file, retrieving screen image from file & displaying it on screen, and comparing two screen images. Routines in this module are responsible for taking, saving, and deleting screen images. For the usage of this libray, please refer to the WattScr user's guide, WattScrU.doc. For the technical information, please refer to the WattScr maintenance's guide, WattScrT.doc. Revision History: [ 0] 20-Feb-1990 AngelaCh: Created program [ 1] 05-Mar-1990 AngelaCh: Increase limit of screen in file (30 to 100) - changed made in dump.h [ 2] 03-Mar-1990 AngelaCh: add info for version number and programming environment to the header of screen file [ 3] 12-Mar-1990 AngelaCh: added functions for retrieving info on version number, total number of screens in file, and programming enviornment [ 4] 13-Mar-1990 AngelaCh: change return code to 24 when trying to add screen to file with 100 screens [ 5] 14-Mar-1990 AngelaCh: added checking for replacing screen n (n<=0 or n>maxsize) when file is full (bug #39) [ 6] 20-Mar-1990 AngelaCh: add 300 to all return codes [ 7] 20-Mar-1990 AngelaCh: add function fDumpWindow [ 8] 27-Mar-1990 AngelaCh: correct typo in function dec [ 9] 11-Apr-1990 AngelaCh: Changed error codes from num const to symbolic constants [10] 20-Apr-1990 AngelaCh: add parameter fFlag to proc fAddScreen to designate that image is written to a screen file [11] 05-Jul-1990 AngelaCh: add function fIntsToStr for calling functions, which re- quire pointer to a structure, from Excel [12] 18-Jul-1991 DavidSc: Added WattDrvr TRAP support [13] 13-Aug-1991 DavidSc: Add arbitrary screen support [14] 12-16-91 dougbo: add Activate version of some routines ******************************************************************************/ #include "windows.h" #include #include "dump.h" #ifndef WIN32 #define _MT #include #else #define rename MoveFile #endif #define intBase 8 /* Global Variables */ CHAR TempFile[] = "@@@Dump.tmp" ; /* name of temp file */ BOOL fIgnoreEvntErrTrap = FALSE; // Trap either WinMissing, or EvntErr, not both INT vWINTrapID; // WattDrvr TrapID for missing windows INT vERRTrapID; // WattDrvr TrapID for entrypoint errors TrapCallBack WINTrapCallBack = NULL;// WattDrvr Callback for missing windows TrapCallBack ERRTrapCallBack = NULL;// WattDrvr Callback for entrypoint errors /****************************************************************************** * PURPOSE: Returns the internal representation of an integer * * RETURN: A string of 2 characters representing an integer * * GLOBALS: None * * CONDITIONS:x is the integer whose internal representation will be returned * * in s * ******************************************************************************/ VOID fIToS(x, s) /* [11] */ INT x ; LPSTR s ; { if ( x < 0 ) /* if the integer is negative, change */ x = 0 ; /* it to 0 */ *s = x - ( (x >> intBase) << intBase ) ; *(s+1) = (x >> intBase) ; } /****************************************************************************** * PURPOSE: Returns the internal representation of 8 integers * * RETURN: A string of 9 characters representing 8 integers * * GLOBALS: None * * CONDITIONS:x1, y1, x2, y2 are the integers whose internal representation * * will be returned in s * * no error checking will be performed in this routine * * Special Note: This routine is only useful when calling Wattscr functions * * that required pointer to a structure from Excel. Since Excel * * does not support structure data type, a string representing * * the upper-left and lower-rigth coordinates of a screen region* * will be used instead. * ******************************************************************************/ LPSTR FARPUBLIC fIntsToStr (s, x1, y1, x2, y2) LPSTR s ; INT x1 ; INT y1 ; INT x2 ; INT y2 ; { *s = 8 ; /* number of char's will be returned */ fIToS(x1, s+1) ; /* find out the internal represent- */ fIToS(y1, s+3) ; /* ation of these integers 1 integer */ fIToS(x2, s+5) ; /* at a time */ fIToS(y2, s+7) ; return s ; } /****************************************************************************** * PURPOSE: Create the appropriate Screen File Header. * * RETURN: Ture if current video mode is supported; otherwise, False will * * be returned. * * GLOBALS: fssScreen, consisting of information about file, which will be * * filled after this function call * * CONDITIONS:None * ******************************************************************************/ VOID PRIVATE CreateHeader(void) { VM vm ; fssScreen.fst.FileId[0] = '@' ; /* file id for the screen files [2] */ fssScreen.fst.FileId[1] = '@' ; fssScreen.fst.FileId[2] = '@' ; fssScreen.fst.Ver = (BYTE)VerCur ; /* record version number [2] */ fssScreen.fst.Env = (BYTE)EnvCur ; /* record programming env [2] */ fssScreen.cscr = 0 ; /* no screen has been dumped yet */ fssScreen.lfo = 0x20; //sizeof (FSS) /* offset to the 1st screen contents */ GetCurrentVideoMode( &vm ) ; fssScreen.vmG = vm ; } /****************************************************************************** * PURPOSE: Try to compress some bytes of data before writing them out to a * * file; if the compression fails, write out the orginal data * * RETURN: 0 will be returned if the data are written out successfully * * number of bytes written to file will be returned via variable cb* * if compression is successful or not will be returned via IsComp * * GLOBALS: none * * CONDITIONS:fd is a valid file handle * * lpIn points a string of data to be written * * biSize number of bytes to be written * ******************************************************************************/ INT PRIVATE WriteCompBytes(FD fd, LPSTR lpIn, WORD biSize, WORD FAR *cb, INT FAR *IsComp) // FD fd ; /* handle of the screen file */ // LPSTR lpIn ; /* points to data to be written */ // WORD biSize ; /* number of bytes to be written */ // WORD FAR *cb ; /* actual number of bytes written */ // INT FAR *IsComp ; /* is compression done successfully? */ { LPSTR lpOut ; GLOBALHANDLE hGMem ; WORD hb ; INT i = 0 ; hGMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DISCARDABLE, (DWORD)biSize) ; if ( !hGMem ) /* allocate memory for receiving */ return OutOMemory ; /* bytes after compression [6] [9] */ lpOut = (LPSTR) GlobalLock(hGMem) ; /* if compress the data resulting in more bytes, write out original data */ if ( (hb = CompressBytes(lpIn, lpOut, biSize)) > biSize ) if ( M_lwrite(fd, lpIn, biSize) != biSize ) i = WSrnImage ; /* [6] [9] */ else *cb = biSize ; else /* otherwise, write out compressed */ if ( M_lwrite(fd, lpOut, hb) != hb ) /* data */ i = WSrnImage ; /* [6] [9] */ else { *cb = hb ; *IsComp = 1 ; } if ( GlobalUnlock(hGMem) ) { if ( i ) return i ; else return RelMemory ; /* [6] [9] */ } if ( GlobalFree(hGMem) ) { if ( i ) return i; else return RelMemory ; /* [6] [9] */ } else return NoError ; /* [9] */ } /****************************************************************************** * PURPOSE: This routine will be called when a request for adding screen to * * the end of a screen file is received * * RETURN: 0 will be returned if screen is added successfully * * GLOBALS: fssScreen (file header) and rgscr (screen table) * * CONDITIONS:fd is valid file handl * * rn contains the x-y coordinates of the upper-left & lower-right * * of the screen region in concern * * hFlag contains valid info of whether the active window should be* * hidden before taking the snapshot or not * * file header and screen table are assumed to have proper info * ******************************************************************************/ INT PRIVATE fAppendSrn(FD fd, REN FAR *rn, INT hFlag) // FD fd ; /* handle of the sceen file */ // REN FAR *rn ; /* coord of the screen region */ // INT hFlag ; /* where in the file */ { SCR *pscr ; INT i = 0 , j ; pscr = &rgscr[fssScreen.cscr]; /* points to the current screen table */ pscr->lfo = fssScreen.lfo; /* offset to the contents of screen */ pscr->ren = *rn ; /* fill screen table with the x-y */ /* coordinates of the screen region */ j = 0 ; /* [10] */ if ( (i = fAddScreen(fd, pscr, hFlag, &j)) == 0 ) /* add the screen [10] */ { fssScreen.cscr++ ; /* a screen has been added */ fssScreen.lfo = pscr->lfo ; /* update size of screens */ for ( j = 0 ; j < MaxCb ; j++) fssScreen.lfo += pscr->cb[j]; } else /* if error occurs in adding screen */ M_llseek(fd, fssScreen.lfo, smFromBegin) ; /* restore the old file */ j = fReWriteTables(fd) ; /* rewrite tables to file */ M_lclose(fd) ; if ( i ) /* if error occurs in adding screen */ return i ; else return j ; } /****************************************************************************** * PURPOSE: Update information of the screen tables after 1 of the screen * * has been replaced by a new screen snapshot * * RETURN: 0 will be returned if tables are updated successfully * * GLOBALS: fssScreen (file header) and rgscr (screen table) * * CONDITIONS:fd1 and fd2 are valid file handles * * pscr contains the information of the screen before it was re- * * placed * * n is valid screen identifier (n > 0) * * file header and screen table are assumed to have proper info * ******************************************************************************/ INT PRIVATE ReplaceSrnTable(FD fd1, FD fd2, SCR FAR *pscr, INT n) // FD fd1 ; /* handle of the temp (old) file */ // FD fd2 ; /* handle of the screen (new) file */ // SCR FAR *pscr ; /* contains info of the old screen */ // INT n ; /* screen identifier */ { LFO tLfo ; INT i = 0 ; /* part of the info of the old has been copied; skip info of the old */ tLfo = fssScreen.lfo - rgscr[n].lfo ; /* screen and copy the rest */ if ( (i = CpBlock(fd1, rgscr[n].lfo, fd2, 0L, tLfo)) != 0 ) return i ; /* of the file to the new file */ tLfo = 0 ; /* after the screen is replaced */ for ( i = 0 ; i < MaxCb ; i++ ) /* how many bytes of data are */ tLfo += (LFO)rgscr[n-1].cb[i]-(LFO)pscr->cb[i]; /* increased/reduced ? */ fssScreen.lfo += tLfo ; /* update the size of screen info */ /* (offset to the screen tables */ for ( i = n ; i < fssScreen.cscr ; i++ ) /* update the screen tables */ rgscr[i].lfo += tLfo ; /* (offset to the screen info) */ return NoError ; } /****************************************************************************** * PURPOSE: Update information of the screen tables after a new screen has * * been inserted among the old screens * * RETURN: 0 will be returned if tables are updated successfully * * GLOBALS: fssScreen (file header) and rgscr (screen table) * * CONDITIONS:fd1 and fd2 are valid file handles * * pscr contains the information of the screen before a new screen * * takes its place * * n is valid screen identifier (n > 0) * * file header and screen table are assumed to have proper info * ******************************************************************************/ INT PRIVATE AddSrnTable(FD fd1, FD fd2, SCR FAR *pscr, INT n) // FD fd1 ; /* handle of the temp (old) file */ // FD fd2 ; /* handle of the screen (new) file */ // SCR FAR *pscr ; /* contains info of the old screen */ // INT n ; /* screen identifier */ { LFO tLfo ; INT i = 0; /* part of the info of the old */ tLfo = fssScreen.lfo - rgscr[n-1].lfo ; /* has been copied to the new */ if ( (i = CpBlock(fd1, 0L, fd2, 0L, tLfo)) != 0 ) /* file; now copy the */ return i ; /* rest if it to the new file */ tLfo = 0 ; /* after the a screen is added */ for ( i = 0 ; i < MaxCb ; i++ ) /* how many bytes of data are */ tLfo += (LFO) rgscr[n-1].cb[i] ; /* increased ? */ fssScreen.lfo += tLfo ; /* update the size of screen info */ /* (offset to the screen tables */ for ( i = fssScreen.cscr ; i > n ; i-- ) /* update the screen tables */ { /* every single screen after the */ rgscr[i] = rgscr[i-1] ; /* insertion point must be moved */ rgscr[i].lfo += tLfo ; /* down by 1 screen */ } rgscr[n] = *pscr ; /* this is the old nth screen, now */ rgscr[n].lfo = pscr->lfo + tLfo ; /* it becomes the (n+1)th screen */ fssScreen.cscr++ ; /* just added a new screen */ return NoError ; /* [9] */ } /****************************************************************************** * PURPOSE: The routine will be called when a request for inserting or re- * * placing a screen is received * * RETURN: 0 will be returned if screen is updated successfully * * GLOBALS: fssScreen (file header) and rgscr (screen table) * * CONDITIONS:FileName is valid file name in 8.3 format * * rn contains the x-y coordinates of the upper-left & lower-right * * of the screen region in concern * * action contains valid action code for updating file * * hFlag contains valid info of whether the active window should be* * hidden before taking the snapshot or not * * file header and screen table are assumed to have proper info * ******************************************************************************/ INT PRIVATE fUpdateSrnFile(LPSTR FileName, REN FAR *rn, INT action, INT n, INT hFlag) // LPSTR FileName ; /* Name of the screen file */ // REN FAR *rn ; /* coord of the screen region */ // INT action ; /* insert of replace a screen */ // INT n ; /* screen identifier */ // INT hFlag ; /* where in the file */ { FD fd1 = fdNull ; FD fd2 = fdNull ; SCR scr ; SCR *pscr ; INT i = 0, j = 0 ; /* [10] */ OFSTRUCT of; if ( rename(FileName, TempFile) != 0 ) /* rename the screen file */ return CTempFile ; /* [6] [9] */ if ( (fd1 = M_lopen((LPSTR)TempFile, omRead)) == fdNull ) return CTempFile ; /* open temp file [6] [9] */ if ( (fd2 = M_lcreat(FileName, 0)) == fdNull ) /* create a new screen file */ { M_lclose(fd1) ; rename(TempFile, FileName) ; return CTempFile ; /* [6] [9] */ } if ( (i = CpBlock(fd1, 0L, fd2, 0L, rgscr[n-1].lfo)) == 0 ) { /* copy screen info from the temp file until file is at position */ /* where the update should occur */ scr = rgscr[n-1] ; /* record the info of the old screen */ pscr = &rgscr[n-1] ; pscr->ren = *rn ; /* take a snapshot of the screen */ i = fAddScreen(fd2, pscr, hFlag, &j) ; /* that is currently being */ /* displayed [10] */ if ( !i ) /* update screen table differently */ if ( action == Replace ) /* according to different updating */ i = ReplaceSrnTable(fd1, fd2, &scr, n) ; /* actions */ else i = AddSrnTable(fd1, fd2, &scr, n) ; if ( !i ) i = fReWriteTables(fd2) ; /* re-write tables to the file */ } M_lclose(fd1) ; M_lclose(fd2) ; if ( !i ) i = MOpenFile(TempFile, &of, OF_DELETE); /* delete the temp file before */ else { /* if unpected error occurs */ MOpenFile(FileName, &of, OF_DELETE ); /* restore the old screenfile */ rename(TempFile, FileName) ; } return i ; } /****************************************************************************** * PURPOSE: This is called everytime a request to take a picture of a screen* * region that is currently being displayed is received * * RETURN: 0 will be returned if contents of the screen region is written * * to a file successfully * * GLOBALS: fssScreen - information of the file, will be filled * * rgscr - information of a particular screen, will be filled * * ClrTab - information about the colours used, will be filled * * CONDITIONS:FileName is in the correct format (8:3) * * rn consists of (x1, y1) and (x2, y2) which are the opposite * * corner of a rectangular screen region * * action is 0, 1, or 2 * * hFlag is either 0 or 1 * ******************************************************************************/ INT FARPUBLIC fDumpScreenActivate(FileName, OpenKeys,CloseKeys,rn, action, n, hFlag) /* [8] */ LPSTR FileName ; /* name of the screen file */ LPSTR OpenKeys; /* keys to activate something */ LPSTR CloseKeys; /* keys to deactivate something */ REN FAR *rn ; /* xy-coord of the screen region */ INT action ; /* where the screen to be put in file */ INT n ; /* screen identifier */ INT hFlag ; /* if action window need to be hidden */ { INT ret; HWND hWndCallingApp ; /* window of the calling application */ if ( hFlag && !(hWndCallingApp = HideApp()) ) /* application first */ return ErrorTrap(HideWin) ; if (LoadTESTEVT()) return ErrorTrap(LibLoadErr); if (OpenKeys) { DoKeys(OpenKeys); /* do some yields to allow keys to get to app and some time for it ** to respond. */ yield(); yield(); yield(); yield(); yield(); } ret = fDumpScreen(FileName,rn, action, n, FALSE); if (CloseKeys) DoKeys(CloseKeys); if ( hFlag ) /* if window has been hidded */ RestoreApp(hWndCallingApp) ; /* restore it */ FreeTESTEVT(); return NoTrap(ret); } /****************************************************************************** * PURPOSE: This is called everytime a request to take a picture of a screen* * region that is currently being displayed is received * * RETURN: 0 will be returned if contents of the screen region is written * * to a file successfully * * GLOBALS: fssScreen - information of the file, will be filled * * rgscr - information of a particular screen, will be filled * * ClrTab - information about the colours used, will be filled * * CONDITIONS:FileName is in the correct format (8:3) * * rn consists of (x1, y1) and (x2, y2) which are the opposite * * corner of a rectangular screen region * * action is 0, 1, or 2 * * hFlag is either 0 or 1 * ******************************************************************************/ INT FARPUBLIC fDumpScreen(FileName, rn, action, n, hFlag) /* [8] */ LPSTR FileName ; /* name of the screen file */ REN FAR *rn ; /* xy-coord of the screen region */ INT action ; /* where the screen to be put in file */ INT n ; /* screen identifier */ INT hFlag ; /* if action window need to be hidden */ { FD fdScreen = fdNull; /* screen file has not been opened */ INT i ; if ( action != Append && action != Replace && action != Insert ) return ErrorTrap( InValidAct) ; /* check if action is acceptable [6] [9] */ /* open file for read and write */ if ((fdScreen = M_lopen (FileName,omReadWrite)) == fdNull) { /* if file does not exist, create file and header */ if ((fdScreen = M_lcreat(FileName, 0)) == fdNull) return ErrorTrap(FileAccess) ; /* File Access Error [6] [9] */ CreateHeader() ; /* add screen to the end of file */ return ErrorTrap(( fAppendSrn(fdScreen, rn, hFlag) )); } if ( (i = ValidateFile(fdScreen, TRUE)) != 0 )/* check if the existing [3] */ { /* file is a valid screen file [2] */ M_lclose(fdScreen) ; /* it is ok eventhough programming */ return ErrorTrap(i) ; /* environment is different */ } if (fssScreen.cscr == cscrMax) if ( action != Replace || n <= 0 || n > fssScreen.cscr ) /*[5]*/ { /* file already consists of max */ M_lclose(fdScreen) ; /* number of screens, cannot add */ return ErrorTrap(SrnFileFul) ; /* any more [4] [6] [9] */ } if (fssScreen.fst.Env != EnvCur) { M_lclose(fdScreen) ; return ErrorTrap (EnvNotSame) ; } if ( (i = fReadTables(fdScreen)) != 0 ) /* read the screen and colour */ { /* tables */ M_lclose(fdScreen) ; return ErrorTrap(i) ; } if ( (action == Append) || (n > fssScreen.cscr) || (n <= 0) ) return ErrorTrap(fAppendSrn(fdScreen, rn, hFlag) ) ;/* add screen to the end */ /* of the file */ if ( (n == fssScreen.cscr) && (action == Replace) ) /* replace the last */ { /* screen == add to the end of file */ fssScreen.lfo = rgscr[n-1].lfo ; /* back up 1 screen */ fssScreen.cscr-- ; /* and add the new screen at the */ return ErrorTrap( fAppendSrn(fdScreen, rn, hFlag) ) ; /* end of the file */ } M_lclose(fdScreen) ; /* get ready to insert/replace a */ return ErrorTrap(fUpdateSrnFile(FileName, rn, action, n, hFlag)) ; /* screen */ } /****************************************************************************** * PURPOSE: This is called everytime a request to take a picture of a * * particular window * * RETURN: 0 will be returned if contents of the screen region is written * * to a file successfully * * GLOBALS: fssScreen - information of the file, will be filled * * rgscr - information of a particular screen, will be filled * * ClrTab - information about the colours used, will be filled * * CONDITIONS:FileName is in the correct format (8:3) * * hWnd is handle of a window or NULL * * action is 0, 1, or 2 * ******************************************************************************/ INT FARPUBLIC fDumpWindowActivate(FileName, OpenKeys, CloseKeys, action, n, hFlag) /* [7][8] */ LPSTR FileName ; /* name of the screen file */ LPSTR OpenKeys ; /* dokeys string to bring up window */ LPSTR CloseKeys ; /* dokeys string to remove window */ INT action ; /* where the screen to be put in file */ INT n ; /* screen identifier */ INT hFlag ; /* if action window need to be hidden */ { INT ret; HWND hWndCallingApp ; /* window of the calling application */ if ( hFlag && !(hWndCallingApp = HideApp()) ) /* application first */ return ErrorTrap(HideWin) ; if (LoadTESTEVT()) return ErrorTrap(LibLoadErr); if (OpenKeys) { DoKeys(OpenKeys); /* do some yields to allow keys to get to app and some time for it ** to respond. */ yield(); yield(); yield(); yield(); yield(); } ret = fDumpWindow(FileName,NULL, action, n, FALSE); if (CloseKeys) DoKeys(CloseKeys); if ( hFlag ) /* if window has been hidded */ RestoreApp(hWndCallingApp) ; /* restore it */ FreeTESTEVT(); return NoTrap(ret); } /****************************************************************************** * PURPOSE: This is called everytime a request to take a picture of a * * particular window * * RETURN: 0 will be returned if contents of the screen region is written * * to a file successfully * * GLOBALS: fssScreen - information of the file, will be filled * * rgscr - information of a particular screen, will be filled * * ClrTab - information about the colours used, will be filled * * CONDITIONS:FileName is in the correct format (8:3) * * hWnd is handle of a window or NULL * * action is 0, 1, or 2 * ******************************************************************************/ INT FARPUBLIC fDumpWindow(FileName, hWnd, action, n, hFlag) /* [7][8] */ LPSTR FileName ; /* name of the screen file */ HWND hWnd ; /* handle of a window */ INT action ; /* where the screen to be put in file */ INT n ; /* screen identifier */ INT hFlag ; /* if action window need to be hidden */ { REN rn ; /* store coordinates of the window */ HWND hWndCallingApp = NULL ; /* handle of the calling app's window */ INT i ; if( !FWinTrapCheckAndTrap( hWnd ) ) { /* get dimenions of the active window */ if ( (i = fGetWndDim(hWnd, &hWndCallingApp, &hFlag, (REN FAR *)&rn)) != 0 ) return ErrorTrap(i) ; i = fDumpScreen(FileName, (REN FAR *)&rn, action, n, hFlag) ; /* take picture of the screen region */ if ( hWndCallingApp ) /* need to restore the calling app's */ RestoreApp(hWndCallingApp) ; /* window if it has been hidden */ return NoTrap(i) ; // No ErrorTrap, already done in fDumpScreen } else return ErrorTrap(InValWHand); } /****************************************************************************** * PURPOSE: This is called everytime a request to delete a screen image from* * the screen file is received * * RETURN: 0 will be returned if screen is deleted successfully * * GLOBALS: None * * CONDITIONS:FileName is name of file in correct format (8.3) * * nscr is valid (> 0) * ******************************************************************************/ INT FARPUBLIC fDelScreen(FileName, nscr) LPSTR FileName ; /* name of screen file */ INT nscr ; /* screen identifier */ { FD fdScreen = fdNull ; /* handle to screen file */ LFO tLfo ; INT i = 0 , j = 0 ; OFSTRUCT of; /* prepare screen file for deletion */ if ( (i = ProcessSrnFile(FileName, &fdScreen, nscr, omReadWrite)) != 0 ) return ErrorTrap(i) ; if ( fssScreen.cscr == nscr && fssScreen.cscr == 1) /* if it is the only */ { /* screen in file, delete the file */ M_lclose(fdScreen) ; return ErrorTrap( MOpenFile(FileName, &of, OF_DELETE) ) ; } if ( nscr != fssScreen.cscr ) /* if it is not the last screen, move */ { /* the rest of the screens upward */ tLfo = fssScreen.lfo - rgscr[nscr].lfo ; /* no of bytes to be copied */ i = CpBlock(fdScreen, rgscr[nscr].lfo, fdScreen, rgscr[nscr-1].lfo, tLfo) ; if ( i != 0 ) { M_lclose(fdScreen) ; return ErrorTrap(i) ; } } fssScreen.cscr-- ; /* a screen has been deleted */ for ( i = 0 ; i < MaxCb ; i++ ) /* number of bytes reomved */ fssScreen.lfo -= (LFO)rgscr[nscr- 1].cb[i] ; /* after the deletion */ i = nscr - 1 ; /* now update the screen tables */ while ( i < fssScreen.cscr ) { tLfo = 0 ; for ( j = 0 ; j < MaxCb ; j++) tLfo += rgscr[i-1].cb[j] ;/* size of the previous screen */ rgscr[i] = rgscr[i+1] ; if ( i == 0 ) /* if it is the 1st file */ rgscr[i].lfo = sizeof(FSS) ; else rgscr[i].lfo = rgscr[i-1].lfo + tLfo ; /* offset to the current */ i++ ; /* screen = offset to the previous */ } /* screen+size of the previous screen */ if ( M_llseek(fdScreen, fssScreen.lfo, smFromBegin) != (LONG2DWORD)fssScreen.lfo ) { /* go to the end of all screens and */ M_lclose(fdScreen) ; /* get ready to rewrite all tables */ return ErrorTrap(ReadSrnFil) ; /* [6] [9] */ } i = fReWriteTables (fdScreen) ; /* rewrite all tables to file */ M_lclose(fdScreen) ; return ErrorTrap(i) ; } //--------------------------------------------------------------------- // WATTDRVR TRAP ROUTINES //--------------------------------------------------------------------- // Determine if the window is enabled and visible INT PRIVATE FBadWindow(hwnd) HWND hwnd; { return(!IsWindowEnabled(hwnd) || !IsWindowVisible(hwnd)); } /****************************************************************************** * PURPOSE: This is called by all routines which need to check the validity * * of a window, generating a trap if the window is invalid. * * RETURN: TRUE if a trap was generated, FALSE otherwise. * * GLOBALS: WINTrapCallBack and vWINTrapID and fIgnoreEvntErrTrap * ******************************************************************************/ BOOL PRIVATE FWinTrapCheckAndTrap( HWND hWnd ) { if( WINTrapCallBack != NULL ) { if( FBadWindow(hWnd) ) { WINTrapCallBack(vWINTrapID); fIgnoreEvntErrTrap = TRUE; return TRUE; } } return FALSE; } /****************************************************************************** * PURPOSE: This is called by WattDrvr when a script includes a * * WindowMissing Trap, to turn on that trapping support. * * RETURN: Nothing * * GLOBALS: WINTrapCallBack and vWINTrapID * ******************************************************************************/ VOID FARPUBLIC WSCR_WindowMissing(INT TrapID, INT Action, TrapCallBack CallBack) { if( Action == 0 ) WINTrapCallBack = NULL; else { vWINTrapID = TrapID; WINTrapCallBack = CallBack; } } /****************************************************************************** * PURPOSE: This is called by WattDrvr when a script includes * * Error Trap support, to turn on that trap. * * RETURN: Nothing * * GLOBALS: ERRTrapCallBack and vERRTrapID * ******************************************************************************/ INT PRIVATE NoTrap( INT n ) // just for cleanup purposes { fIgnoreEvntErrTrap = FALSE; return n; } /****************************************************************************** * PURPOSE: This is called by all PUBLIC routines which return values that * * could be Errors, so that the trap can be generated if required. * * If a Window trap was already generated, this one will not be. * * RETURN: The value passed in - to be passed on to the WTD script * * GLOBALS: ERRTrapCallBack and vERRTrapID and fIgnoreEvntErrTrap * ******************************************************************************/ INT PRIVATE ErrorTrap( INT n ) { if( ( ERRTrapCallBack != NULL ) && n && !fIgnoreEvntErrTrap ) if( ( n != ImageDiff ) && ( n != SrnSizeDif ) ) ERRTrapCallBack(vERRTrapID); // if( ( DIFFTrapCallBack != NULL ) && ( (n==ImageDiff)||(n==SrnSizeDif) ) ) // DIFFTrapCallBack(vERRTrapID); fIgnoreEvntErrTrap = FALSE; return n; } /****************************************************************************** * PURPOSE: This is called by WattDrvr when a script includes * * Error Trap support, to turn on that trap. * * RETURN: Nothing * * GLOBALS: ERRTrapCallBack and vERRTrapID * ******************************************************************************/ VOID FARPUBLIC WSCR_EventError(INT TrapID, INT Action, TrapCallBack CallBack) { if( Action == 0 ) ERRTrapCallBack = NULL; else { vERRTrapID = TrapID; ERRTrapCallBack = CallBack; } } INT ( APIENTRY *DoKeys)(LPSTR) = NULL; static HANDLE hTESTEVT = 0; //*----------------------------------------------------------------------- //| LoadTESTEVT //| //| PURPOSE: Load the TESTEVT DLL library and set the DoKeys pointer //| to the DoKeys routine. //| //| //*----------------------------------------------------------------------- INT FARPUBLIC LoadTESTEVT () { // Load the library, and return error if not successful //---------------------------------------------------------------- hTESTEVT = MLoadLibrary ("TESTEVNT.DLL"); if (hTESTEVT < (HANDLE) 32) return (LibLoadErr); // Set DoKeys accordingly, and return success/failure //---------------------------------------------------------------- (FARPROC) DoKeys = GetProcAddress (hTESTEVT, "DoKeys"); if (!DoKeys) return (LibLoadErr); return (NoError); } //*----------------------------------------------------------------------- //| FreeTESTEVT //| //| PURPOSE: Free the TESTEVT DLL library and set the DoKeys pointer //| to NULL. //| //| //*----------------------------------------------------------------------- VOID FARPUBLIC FreeTESTEVT () { DoKeys = NULL; FreeLibrary (hTESTEVT); } /*========================================================================== ; Purpose: ; Compress a string of bytes; count the repeating bytes; ; remember the number of repeating byte and the value of ; the byte. Stops if the resulting string is longer than ; the original one. ; Entry: ; lpIn points to a string of bytes before compression ; lpOut points to resulting string after the compression ; tb is total number of bytes to be compressed ; Exit: ; ax = number of bytes after compression or -1 if fail to compress ; ; History: 5-20-92 Babakj: Brought from Winplay port ; ==========================================================================*/ UINT PRIVATE CompressBytes (LPBYTE lpIn, LPBYTE lpOut, UINT wLen) { LPBYTE lpt1, lpt2; BYTE cCurrent; UINT wLeft, i, wNewSize; lpt1 = lpIn; lpt2 = lpOut; wLeft = wLen; wNewSize = 0; #define MaxSizeCb 0xFF while (wLeft != 0) { i = 1; cCurrent = *lpt1++; wLeft--; while ((cCurrent == *lpt1) && (wLeft)) { wLeft--; lpt1++; i++; } while (i > MaxSizeCb) /* We read over the limit of a byte. */ { *lpt2++ = MaxSizeCb; *lpt2++ = cCurrent; if ((wNewSize += 2) >= wLen) return ((UINT)-1); /* we are longer than the original. */ i -= MaxSizeCb; } *lpt2++ = (BYTE)i; *lpt2++ = cCurrent; if ((wNewSize += 2) >= wLen) return ((UINT)-1); } return (wNewSize); } /*========================================================================== ; Purpose: ; De-compress a string of bytes to its original form ; Entry: ; lpIn points to a string of bytes before de-compression ; lpOut points to resulting string after de-compression ; tb is total number of bytes to be de-compressed ; Exit: ; ax = number of bytes after decompression ; ; History: 5-20-92 Babakj: Brought from Winplay port ; ==========================================================================*/ UINT FARPUBLIC DeCompressBytes (LPBYTE lpIn, LPBYTE lpOut, UINT wLen) { LPBYTE lpt1, lpt2; register UINT wLeft, i, wNewSize; BYTE cCurrent; lpt1 = lpIn; lpt2 = lpOut; wLeft = wLen; wNewSize = 0; while (wLeft > 0) { i = (UINT) *lpt1++; cCurrent = *lpt1++; wLeft -= 2; while (i-- > 0) { *lpt2++ = cCurrent; wNewSize++; } } return (wNewSize); }