home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / ve2tv103.zip / TMACRO.CPP < prev    next >
C/C++ Source or Header  |  1994-07-31  |  7KB  |  201 lines

  1. // File    : TMACRO.CPP
  2. // Author  : Eric Woodruff,  CIS ID: 72134,1150
  3. // Updated : Sun 07/31/94 15:56:28
  4. // Note    : Copyright 1994, Eric Woodruff, All rights reserved
  5. // Compiler: Borland C++ 3.1 to 4.02
  6. //
  7. // This is a replacement TApplication::getEvent() member function that will
  8. // allow the implementation of simple macro recording and playback.  It
  9. // isn't perfect, but works fairly well.  It is best to use ALT+R to start
  10. // and stop recording instead of ALT+O, and Enter (when Record is the
  11. // default menu item).  The final Enter sometimes causes the wrong thing to
  12. // display after the macro has finished.  Ah well, this is only a demo.
  13. //
  14. // NOTE:  This expects to have the static data members MacroFile and
  15. //        MacroStatus defined in the TApplication class.
  16. //
  17.  
  18. #include <dir.h>
  19. #include <dos.h>
  20. #include <io.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #define Uses_MsgBox
  25. #define Uses_TApplication
  26. #define Uses_TEvent
  27. #define Uses_TEventQueue
  28. #define Uses_TFileDialog
  29. #define Uses_TKeys
  30. #include <tv.h>
  31.  
  32. // NOTE: For each application, these will have to change.  #include the
  33. //       header that defines your application class.  You will also need
  34. //       to change all "TxxxxApp::" references to name your application
  35. //       class.
  36. #define Uses_TVMEditorApp
  37. #include "tvedit.h"
  38.  
  39. FILE * _NEAR TVMEditorApp::MacroFile = NULL;     // Macro function is off
  40. ushort _NEAR TVMEditorApp::MacroStatus = 0;      // to start with.
  41.  
  42. // A version string was added to the macro file because there are
  43. // significant differences between the TV 1.03 and TV 2.0 TEvent structures.
  44. #if _TV_VERSION == 0x0103
  45. char VersionString[] = "TVMEditor Macro File\x1A\x01\x03";
  46. #else
  47. char VersionString[] = "TVMEditor Macro File\x1A\x02\x00";
  48. #endif
  49.  
  50. void TVMEditorApp::getEvent(TEvent &event)
  51. {
  52.     static char macroName[MAXPATH] = "*.MAC";
  53.     char verCheck[30];
  54.  
  55. //
  56. // In TV 2.0, the control key states *are* in the TEvent structure.
  57. //
  58. #if _TV_VERSION == 0x0103
  59.     // Ideally the shift state would be in the TEvent structure.  However, it
  60.     // isn't, I don't want to modify it and all classes that may need it, and
  61.     // the following method works well.  If not accounted for, stuff like
  62.     // sizing the window with the keyboard or selecting text in an editor
  63.     // won't work.
  64.     unsigned char *kbFlagsPtr = (uchar *)MK_FP(0x40, 0x17);
  65. #endif
  66.  
  67.     // Get the next event from the file if playing a macro.
  68.     if(MacroStatus == cmPlay && MacroFile)
  69.     {
  70.         char keyState;
  71.  
  72.         if(fread(&event, sizeof(event), 1, MacroFile) != 1 ||
  73.            fread(&keyState, sizeof(char), 1, MacroFile) != 1)
  74.         {
  75.             fclose(MacroFile);      // End of file or error.
  76.             MacroFile = NULL;
  77.             MacroStatus = 0;
  78.  
  79. #if _TV_VERSION == 0x0103
  80.             *kbFlagsPtr &= 0xF0;    // Reset Shift/Alt/Ctrl status bits.
  81. #endif
  82.  
  83.             // If that was the end of the file, chances are that the
  84.             // last event was a keyboard or mouse event that will now
  85.             // generate another cmRecord event.  If so, get rid of it.
  86.             TApplication::getEvent(event);
  87.  
  88.             // Put it back if it is not.
  89.             if(event.what != evCommand || (event.message.command != cmRecord &&
  90.               event.message.command != cmPlay))
  91.                 putEvent(event);
  92.         }
  93.         else
  94.         {
  95.             delay(100);
  96.             putEvent(event);
  97.  
  98. #if _TV_VERSION == 0x0103
  99.             // Set keyboard flags for the event.  It's okay to do this because
  100.             // it is the keyboard interrupt that adjusts it.  The only thing
  101.             // to remember is that before returning control to the user, turn
  102.             // off the Shift/Alt/Ctrl bits incase they were left on by the
  103.             // last event.
  104.             *kbFlagsPtr = keyState;
  105. #endif
  106.         }
  107.  
  108.         clearEvent(event);
  109.     }
  110.  
  111.     TApplication::getEvent(event);
  112.  
  113.     // Save all but evNothing, cmRecord, and cmPlay events.
  114.     //
  115.     // NOTE:  Using the mouse will cause hundreds of events to be recorded
  116.     //        and the macro file will be very large!
  117.     //        If possible, avoid using the mouse when recording macros.
  118.     //        Another problem with the mouse in macros is that objects
  119.     //        (such as editors) might not be in the proper place and
  120.     //        a mouse event might miss its intended target.
  121.     //        Optionally, you could suspend the mouse handler when
  122.     //        recording starts and resume it when recording is finished.
  123.  
  124.     if(MacroStatus == cmRecord && event.what != evNothing)
  125.         if(event.what != evCommand || (event.message.command != cmRecord
  126.           && event.message.command != cmPlay))
  127. #if _TV_VERSION == 0x0103
  128.         {
  129.             fwrite(&event, sizeof(TEvent), 1, MacroFile);
  130.             fwrite(kbFlagsPtr, sizeof(char), 1, MacroFile);
  131.         }
  132. #else
  133.             fwrite(&event, sizeof(TEvent), 1, MacroFile);
  134. #endif
  135.  
  136.     if(event.what == evCommand)
  137.     {
  138.         if(!MacroStatus && event.message.command == cmPlay)
  139.         {
  140.             clearEvent(event);
  141.  
  142.             if(executeDialog(new TFileDialog(macroName, "Play Macro",
  143.                 "~N~ame", fdOpenButton, 100), macroName) != cmCancel)
  144.             {
  145.                 MacroFile = fopen(macroName, "rb");
  146.  
  147.                 if(MacroFile)
  148.                 {
  149.                     fread(verCheck, sizeof(VersionString), 1, MacroFile);
  150.                     if(strncmp(verCheck, VersionString, sizeof(VersionString)))
  151.                         messageBox("Incompatible macro file",
  152.                             mfError | mfCancelButton);
  153.                     else
  154.                         MacroStatus = cmPlay;
  155.                 }
  156.             }
  157.         }
  158.         else
  159.             if(event.message.command == cmRecord)
  160.             {
  161.                 clearEvent(event);
  162.                 if(!MacroStatus && !MacroFile)
  163.                 {
  164.                     if(executeDialog(new TFileDialog(macroName, "Record Macro",
  165.                         "~N~ame", fdOpenButton, 100), macroName) != cmCancel)
  166.                     {
  167.                         // Start event recording.
  168.                         ushort result = cmYes;
  169.  
  170.                         if(!access(macroName, 0))
  171.                             result = messageBox("File exists. OVERWRITE?",
  172.                                 mfConfirmation | mfYesNoCancel);
  173.  
  174.                         // Create a new file.
  175.                         if(result == cmYes)
  176.                             MacroFile = fopen(macroName, "wb");
  177.  
  178.                         // Append commands to an existing file.
  179.                         if(result == cmNo)
  180.                             MacroFile = fopen(macroName, "ab");
  181.  
  182.                         if(MacroFile)
  183. //                        {
  184. //                            TEventQueue::suspend();    // Suspend mouse.
  185.                             MacroStatus = cmRecord;
  186. //                        }
  187.                     }
  188.                 }
  189.                 else
  190.                 {
  191.                     // End event recording.
  192.                     fclose(MacroFile);
  193.                     MacroFile = NULL;
  194.                     MacroStatus = 0;
  195.  
  196. //                    TEventQueue::resume();        // Resume mouse.
  197.                 }
  198.             }
  199.     }
  200. }
  201.