home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9302 / tvision / tvpas / xmacro.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-11-10  |  24.4 KB  |  995 lines

  1. (* ------------------------------------------------------ *)
  2. (*                     XMACRO.PAS                         *)
  3. (*                                                        *)
  4. (*  Makros, Makro-Listbox, -Statuszeile und -Applikation  *)
  5. (*        (C) 1992 by Christian Ohr & DMV-Verlag          *)
  6. (* ------------------------------------------------------ *)
  7. {$R-,S-,I-,B-,D-,L-,V-,A+,F+,O+,X+}
  8.  
  9.  
  10. UNIT XMacro;
  11.  
  12.  
  13. INTERFACE
  14.  
  15.  
  16. USES Objects, Drivers, Views, Dialogs, Menus, App,
  17.      XDialogs;
  18.  
  19. CONST
  20.   cmRecordMacro = 150;
  21.   cmMacros      = 151;
  22.   cmSaveMacros  = 152;
  23.   cmLoadMacros  = 153;
  24.  
  25.   StreamName = 'KBCONST.STM';
  26.  
  27.  
  28. TYPE
  29.   pKeyRec = ^tKeyRec;
  30.   tKeyRec = RECORD
  31.     Key: pString;
  32.     Value: WORD;
  33.   END;
  34.  
  35.  
  36.   (* in tKeyCol werden alle Tastennamen u. deren Scancode *)
  37.   (* abgespeichert. Diese Daten werden zu Beginn aus      *)
  38.   (* einem Stream (KBCONST.STM) geladen.                  *)
  39.  
  40.   pKeyCol = ^tKeyCol;
  41.   tKeyCol = OBJECT(tStringCollection)
  42.     PROCEDURE FreeItem (Item: POINTER); VIRTUAL;
  43.     FUNCTION GetItem (VAR S: TStream): POINTER; VIRTUAL;
  44.     PROCEDURE InsertKey (AKey: STRING; AValue: WORD);
  45.     FUNCTION KeyOf (Item: POINTER): POINTER; VIRTUAL;
  46.     PROCEDURE PutItem (VAR S: TStream; Item: POINTER);
  47.                           VIRTUAL;
  48.   END;
  49.  
  50.  
  51.  
  52.   (* tEvCol stellt eine Kollektion dar, in der Ereignis-  *)
  53.   (* abfolgen mit einem Namen und Aufruf-Tastencode ver-  *)
  54.   (* sehen abgespeichert werden                           *)
  55.  
  56.   pEvCol = ^tEvCol;
  57.   tEvCol = OBJECT(tCollection)
  58.     Title    : pString;
  59.     ScanIndex: INTEGER;
  60.     Delayed  : WORD;
  61.     PlayIndex: INTEGER;
  62.     EventMask: WORD;
  63.     CONSTRUCTOR Init (ATitle: TTitleStr; AScanIndex:
  64.                       INTEGER; ADelay, AEvMaskCode: WORD);
  65.     DESTRUCTOR Done; VIRTUAL;
  66.     CONSTRUCTOR Load (VAR S: tStream);
  67.     PROCEDURE FreeItem(Item: POINTER); VIRTUAL;
  68.     FUNCTION  GetItem(VAR S: TStream): POINTER; VIRTUAL;
  69.     FUNCTION  GetNextEvent (VAR Event: tEvent): BOOLEAN;
  70.     PROCEDURE InsertEvent(Event: tEvent);
  71.     PROCEDURE PutItem(VAR S: TStream; Item: POINTER);
  72.                           VIRTUAL;
  73.     PROCEDURE Store (VAR S: tStream); VIRTUAL;
  74.   END;
  75.  
  76.  
  77.   (* tMacCol nimmt alle Event-Collections auf u. sortiert *)
  78.   (* sie nach deren Macro-Namen.                          *)
  79.  
  80.   pMacCol = ^tMacCol;
  81.   tMacCol = OBJECT(tSortedCollection)
  82.     FUNCTION Compare(Key1, Key2: POINTER): INTEGER; VIRTUAL;
  83.   END;
  84.  
  85.  
  86.   (* tKeyColInputLine spezialisiert tColInputLine auf die *)
  87.   (* Verarbeitung von tKeyCol-Objekten                    *)
  88.  
  89.   pKeyColInputLine = ^tKeyColInputLine;
  90.   tKeyColInputLine = OBJECT(tColInputLine)
  91.     FUNCTION At (AValue: INTEGER): pString; VIRTUAL;
  92.     FUNCTION DataSize: WORD; VIRTUAL;
  93.     PROCEDURE GetData (VAR Rec); VIRTUAL;
  94.     FUNCTION IndexOf (P: pString): INTEGER; VIRTUAL;
  95.     PROCEDURE SetData (VAR Rec); VIRTUAL;
  96.   END;
  97.  
  98.  
  99.   (* tMacro erledigt die gesamte Macroverwaltung. tMacro  *)
  100.   (* bekommt Ereignisse von tMacroApplication.GetEvent    *)
  101.   (* zugestellt und/oder gibt vorher aufgezeichnete       *)
  102.   (* Ereignisse an die gleiche Methode ab.                *)
  103.  
  104.   pMacro = ^tMacro;
  105.   tMacro = OBJECT(tObject)
  106.     RecMacro   : pEvCol;
  107.     PlayCol    : pCollection;
  108.     MacroCol   : pMacCol;
  109.     Break      : tEvent;
  110.     CONSTRUCTOR Init;
  111.     DESTRUCTOR Done; VIRTUAL;
  112.     CONSTRUCTOR Load (VAR S: tStream);
  113.     FUNCTION  BreakEvent (VAR Event: tEvent): BOOLEAN;
  114.     FUNCTION  CurrentPlayer: pEvCol;
  115.     FUNCTION  InitMacroDialog: pDialog; VIRTUAL;
  116.     PROCEDURE MacroDialog;
  117.     PROCEDURE Recorder (VAR Event: tEvent); VIRTUAL;
  118.     PROCEDURE RecordMacro;
  119.     FUNCTION  Replay  (VAR Event: tEvent): INTEGER; VIRTUAL;
  120.     FUNCTION  ReplayHotKey(KeyCode: WORD): BOOLEAN; VIRTUAL;
  121.     PROCEDURE Store (VAR S: tStream); VIRTUAL;
  122.   END;
  123.  
  124.  
  125.   (* tMacroListBox stellt Kollektionen vom Typ tMacCol    *)
  126.   (* in einer ListBox dar.                                *)
  127.  
  128.   pMacroListBox = ^tMacroListBox;
  129.   tMacroListBox = OBJECT(tListBox)
  130.     CONSTRUCTOR Init (VAR Bounds: tRect;
  131.                     AScrollBar: pScrollBar; AList: pMacCol);
  132.     PROCEDURE GetData (VAR Rec); VIRTUAL;
  133.     FUNCTION GetText (Item, MaxLen: INTEGER): STRING; VIRTUAL;
  134.     PROCEDURE HandleEvent (VAR Event: tEvent); VIRTUAL;
  135.     PROCEDURE SetData (VAR Rec); VIRTUAL;
  136.   END;
  137.  
  138.  
  139.   (* tMacroDialog ist die Schnittstelle zur Makro-        *)
  140.   (* bearbeitung                                          *)
  141.  
  142.   pMacroDialog = ^tMacroDialog;
  143.   tMacroDialog = OBJECT(tDialog)
  144.     MacroListBox: pMacroListBox;
  145.     CONSTRUCTOR Init (AList: pMacCol);
  146.     CONSTRUCTOR Load (VAR S: tStream);
  147.     PROCEDURE HandleEvent (VAR Event: tEvent); VIRTUAL;
  148.     PROCEDURE Store (VAR S: tStream); VIRTUAL;
  149.   END;
  150.  
  151.  
  152.   (* Für Makroverarbeitung muß d. Applikation anstatt von *)
  153.   (* tApplication von diesem Objekt abgeleitet werden.    *)
  154.  
  155.   pMacroApplication = ^tMacroApplication;
  156.   tMacroApplication = OBJECT(tApplication)
  157.     MacroObj : pMacro;
  158.     Pending : tEvent;
  159.     CONSTRUCTOR Init;
  160.     FUNCTION EventAvail: BOOLEAN;
  161.     PROCEDURE GetEvent(VAR Event: tEvent); VIRTUAL;
  162.     PROCEDURE HandleEvent (VAR Event: tEvent); VIRTUAL;
  163.     PROCEDURE Idle; VIRTUAL;
  164.     PROCEDURE PutEvent(VAR Event: tEvent); VIRTUAL;
  165.   END;
  166.  
  167.  
  168. PROCEDURE LoadKeyStream;
  169. PROCEDURE RegisterXMacro;
  170.  
  171.  
  172. VAR
  173.   KeyCol: pKeyCol;
  174.  
  175.  
  176. CONST
  177.   rKeyCol: tStreamRec = (
  178.     ObjType: 1500;
  179.     VmtLink: Ofs(TypeOf(tKeyCol)^);
  180.     Load: @tKeyCol.Load;
  181.     Store: @tKeyCol.Store
  182.   );
  183.   rEvCol: tStreamRec = (
  184.     ObjType: 1501;
  185.     VmtLink: Ofs(TypeOf(tEvCol)^);
  186.     Load: @tEvCol.Load;
  187.     Store: @tEvCol.Store
  188.   );
  189.   rMacCol: tStreamRec = (
  190.     ObjType: 1502;
  191.     VmtLink: Ofs(TypeOf(tMacCol)^);
  192.     Load: @tMacCol.Load;
  193.     Store: @tMacCol.Store
  194.   );
  195.   rKeyColInputLine: tStreamRec = (
  196.     ObjType: 1503;
  197.     VmtLink: Ofs(TypeOf(tKeyColInputLine)^);
  198.     Load: @tKeyColInputLine.Load;
  199.     Store: @tKeyColInputLine.Store
  200.   );
  201.   rMacroListBox: tStreamRec = (
  202.     ObjType: 1504;
  203.     VmtLink: Ofs(TypeOf(tMacroListBox)^);
  204.     Load: @tMacroListBox.Load;
  205.     Store: @tMacroListBox.Store
  206.   );
  207.   rMacro: tStreamRec = (
  208.     ObjType: 1505;
  209.     VmtLink: Ofs(TypeOf(tMacro)^);
  210.     Load: @tMacro.Load;
  211.     Store: @tMacro.Store
  212.   );
  213.   rMacroDialog: tStreamRec = (
  214.     ObjType: 1506;
  215.     VmtLink: Ofs(TypeOf(tMacroDialog)^);
  216.     Load: @tMacroDialog.Load;
  217.     Store: @tMacroDialog.Store
  218.   );
  219.  
  220.  
  221.  
  222. IMPLEMENTATION
  223.  
  224. USES CRT, Fields, Memory, MsgBoxG;
  225.  
  226.  
  227. CONST
  228.   cmReplayMacro     = 10;
  229.   cmEditMacro       = 12;
  230.   cmNewMacro        = 13;
  231.   cmDeleteMacro     = 154;
  232.   cmDeleteAllMacros = 155;
  233.  
  234. TYPE
  235.   tRecordMacro = RECORD
  236.                    Title     : tTitleStr;
  237.                    ScanIndex : INTEGER;
  238.                    Delayed   : LONGINT;
  239.                    EventMask : WORD;
  240.                  END;
  241.  
  242. VAR
  243.   RecMacDescr : tRecordMacro;
  244.   EventAhead  : BOOLEAN;
  245.  
  246.  
  247. FUNCTION CreateRecordDialog: pDialog;
  248. VAR
  249.   D: pDialog;
  250.   C: pView;
  251.   R: tRect;
  252. BEGIN
  253.   R.Assign(0, 0, 40, 16);
  254.   D := New(pDialog, Init(R, 'Makro aufzeichnen'));
  255.   WITH D^ DO BEGIN
  256.     Options := Options OR ofCentered;
  257.  
  258.     R.Assign(3, 3, 32, 4);
  259.     C := New(pKeyInputLine, Init(R, 80));
  260.     Insert(C);
  261.     R.Assign(2, 2, 15, 3);
  262.     Insert(New(pXLabel, Init(R, 'Makro-~N~ame', C)));
  263.  
  264.     R.Assign(3, 7, 18, 8);
  265.     C := New(pScrollBar, Init(R));
  266.     Insert(C);
  267.     R.Assign(3, 6, 18, 7);
  268.     C := New(pKeyColInputLine, Init(R, 10,
  269.                    pScrollBar(C), KeyCol));
  270.     Insert(C);
  271.     R.Assign(2, 5, 20, 6);
  272.     Insert(New(pXLabel, Init(R, '~T~astenkombination', C)));
  273.  
  274.     R.Assign(3, 10, 15, 11);
  275.     C := New(pNumInputLine, Init(R, 8, 0, 65535));
  276.     Insert(C);
  277.     R.Assign(2, 9, 19, 10);
  278.     Insert(New(pXLabel, Init(R, '~V~erzögerung (ms)', C)));
  279.  
  280.     R.Assign(21, 9, 37, 11);
  281.     Insert(New(pCheckBoxes, Init(R,
  282.       NewSItem('~T~astatur',
  283.       NewSItem('~M~ausklicks', NIL)))));
  284.  
  285.     R.Assign(14, 13, 24, 15);
  286.     Insert(New(pButton, Init(R, 'O~K~', cmOk, bfDefault)));
  287.     R.Move(12, 0); Inc(R.B.X);
  288.     Insert(New(pButton, Init(R, 'Abbruch', cmCancel,
  289.                              bfNormal)));
  290.     SelectNext(FALSE);
  291.   END;
  292.   CreateRecordDialog := D;
  293. END;
  294.  
  295.  
  296.  
  297. FUNCTION CreateEditDialog: pDialog;
  298. VAR
  299.   D: pDialog;
  300.   C: pView;
  301.   R: tRect;
  302. BEGIN
  303.   R.Assign(0, 0, 38, 16);
  304.   D := New(pDialog, Init(R, 'Makro bearbeiten'));
  305.   WITH D^ DO BEGIN
  306.     Options := Options OR ofCentered;
  307.  
  308.     R.Assign(3, 3, 32, 4);
  309.     C := New(pKeyInputLine, Init(R, 80));
  310.     Insert(C);
  311.     R.Assign(2, 2, 15, 3);
  312.     Insert(New(pXLabel, Init(R, 'Makro-~N~ame', C)));
  313.  
  314.     R.Assign(3, 7, 18, 8);
  315.     C := New(pScrollBar, Init(R));
  316.     Insert(C);
  317.     R.Assign(3, 6, 18, 7);
  318.     C := New(pKeyColInputLine, Init(R, 10, pScrollBar(C),
  319.                                     KeyCol));
  320.     Insert(C);
  321.     R.Assign(2, 5, 20, 6);
  322.     Insert(New(pXLabel, Init(R, '~T~astenkombination', C)));
  323.  
  324.     R.Assign(3, 10, 15, 11);
  325.     C := New(pNumInputLine, Init(R, 8, 0, 65535));
  326.     Insert(C);
  327.     R.Assign(2, 9, 19, 10);
  328.     Insert(New(pXLabel, Init(R, '~V~erzögerung (ms)', C)));
  329.  
  330.     R.Assign(13, 13, 23, 15);
  331.     Insert(New(pButton, Init(R, 'O~K~', cmOk, bfDefault)));
  332.     R.Move(12, 0); Inc(R.B.X);
  333.     Insert(New(pButton, Init(R, 'Abbruch', cmCancel,
  334.                              bfNormal)));
  335.     SelectNext(FALSE);
  336.   END;
  337.   CreateEditDialog := D;
  338. END;
  339.  
  340.  
  341.  
  342. (* ------------------------------------------------------ *)
  343. (*                       tKeyCol                          *)
  344. (* ------------------------------------------------------ *)
  345.  
  346.  
  347. PROCEDURE tKeyCol.FreeItem(Item: POINTER);
  348. BEGIN
  349.   DisposeStr(pKeyRec(Item)^.Key);
  350.   FreeMem(Item, SizeOf(tKeyRec));
  351. END;
  352.  
  353.  
  354. FUNCTION tKeyCol.GetItem(VAR S: TStream): POINTER;
  355. VAR
  356.   P: pKeyRec;
  357. BEGIN
  358.   GetMem(P, SizeOf(tKeyRec));
  359.   S.Read(P^.Value, SizeOf(WORD));
  360.   P^.Key := S.ReadStr;
  361.   GetItem := P;
  362. END;
  363.  
  364.  
  365. PROCEDURE tKeyCol.InsertKey(AKey: STRING; AValue: WORD);
  366. VAR
  367.   P: pKeyRec;
  368. BEGIN
  369.   P := New(pKeyRec);
  370.   P^.Value := aValue;
  371.   P^.Key := NewStr(AKey);
  372.   Insert(P);
  373. END;
  374.  
  375.  
  376. FUNCTION tKeyCol.KeyOf(Item: POINTER): POINTER;
  377. BEGIN
  378.   KeyOf := pKeyRec(Item)^.Key;
  379. END;
  380.  
  381.  
  382. PROCEDURE tKeyCol.PutItem(VAR S: TStream; Item: POINTER);
  383. BEGIN
  384.   S.Write(pKeyRec(Item)^.Value, SizeOf(WORD));
  385.   S.WriteStr(pKeyRec(Item)^.Key);
  386. END;
  387.  
  388.  
  389.  
  390. (* ------------------------------------------------------ *)
  391. (*                        tEvCol                          *)
  392. (* ------------------------------------------------------ *)
  393.  
  394.  
  395. CONSTRUCTOR tEvCol.Init (ATitle: tTitleStr;
  396.                          AScanIndex: INTEGER;
  397.                          ADelay, AEvMaskCode: WORD );
  398. BEGIN
  399.   TCollection.Init(20, 10);
  400.   Title := NewStr(ATitle);
  401.   ScanIndex := AScanIndex;
  402.   Delayed := ADelay;
  403.   EventMask := evNothing;
  404.   IF AEvMaskCode AND 1 = 1 THEN
  405.     EventMask := EventMask OR evKeyDown;
  406.   IF AEvMaskCode AND 2 = 2 THEN
  407.     EventMask := EventMask OR (evMouseDown + evMouseUp);
  408.   PlayIndex := -1;
  409. END;
  410.  
  411.  
  412. DESTRUCTOR tEvCol.Done;
  413. BEGIN
  414.   DisposeStr(Title);
  415.   TCollection.Done;
  416. END;
  417.  
  418.  
  419. CONSTRUCTOR tEvCol.Load (VAR S: tStream);
  420. BEGIN
  421.   tCollection.Load(S);
  422.   Title := S.ReadStr;
  423.   S.Read(ScanIndex, SizeOf(INTEGER));
  424.   S.Read(Delayed, SizeOf(WORD));
  425.   S.Read(EventMask, SizeOf(WORD));
  426.   PlayIndex := -1;
  427. END;
  428.  
  429.  
  430. PROCEDURE tEvCol.FreeItem(Item: POINTER);
  431. BEGIN
  432.   Dispose(pEvent(Item));
  433. END;
  434.  
  435.  
  436. FUNCTION tEvCol.GetItem(VAR S: tStream): POINTER;
  437. VAR
  438.   P: pEvent;
  439. BEGIN
  440.   P := New(pEvent);
  441.   S.Read(P^, SizeOf(tEvent));
  442.   GetItem := P;
  443. END;
  444.  
  445.  
  446. FUNCTION tEvCol.GetNextEvent (VAR Event: tEvent): BOOLEAN;
  447. BEGIN
  448.   IF PlayIndex < Pred(Count) THEN BEGIN
  449.     Inc(PlayIndex);
  450.     Event := pEvent(At(PlayIndex))^;
  451.     GetNextEvent := TRUE;
  452.   END ELSE BEGIN
  453.     PlayIndex := -1;
  454.     Event.What := evNothing;
  455.     GetNextEvent := FALSE;
  456.   END;
  457. END;
  458.  
  459.  
  460. PROCEDURE tEvCol.InsertEvent(Event: tEvent);
  461. VAR
  462.   P: pEvent;
  463. BEGIN
  464.   P := New(PEvent);
  465.   P^ := Event;
  466.   Insert(P);
  467. END;
  468.  
  469.  
  470. PROCEDURE tEvCol.PutItem(VAR S: tStream; Item: POINTER);
  471. BEGIN
  472.   S.Write(pEvent(Item)^, SizeOf(tEvent));
  473. END;
  474.  
  475.  
  476. PROCEDURE tEvCol.Store (VAR S: tStream);
  477. BEGIN
  478.   tCollection.Store(S);
  479.   S.WriteStr(Title);
  480.   S.Write(ScanIndex, SizeOf(INTEGER));
  481.   S.Write(Delayed, SizeOf(WORD));
  482.   S.Write(EventMask, SizeOf(WORD));
  483. END;
  484.  
  485.  
  486.  
  487. (* ------------------------------------------------------ *)
  488. (*                      tMacCol                           *)
  489. (* ------------------------------------------------------ *)
  490.  
  491.  
  492. FUNCTION tMacCol.Compare(Key1, Key2: POINTER): INTEGER;
  493. BEGIN
  494.   IF pEvCol(Key1)^.Title^ < pEvCol(Key2)^.Title^ THEN
  495.     Compare := -1 ELSE
  496.     IF pEvCol(Key1)^.Title^ = pEvCol(Key2)^.Title^ THEN
  497.       Compare := 0 ELSE
  498.       Compare := 1;
  499. END;
  500.  
  501.  
  502.  
  503. (* ------------------------------------------------------ *)
  504. (*                  tKeyColInputLine                      *)
  505. (* ------------------------------------------------------ *)
  506.  
  507.  
  508. FUNCTION tKeyColInputLine.At (AValue: INTEGER): pString;
  509. BEGIN
  510.   IF (AValue >= Limit.X) AND (AValue <= Limit.Y) THEN
  511.     At := pKeyRec(Col^.At(AValue))^.Key;
  512. END;
  513.  
  514.  
  515. FUNCTION tKeyColInputLine.DataSize: WORD;
  516. BEGIN
  517.   DataSize := SizeOf(INTEGER);
  518. END;
  519.  
  520.  
  521. PROCEDURE tKeyColInputLine.GetData (VAR Rec);
  522. BEGIN
  523.   INTEGER(Rec) := Value;
  524. END;
  525.  
  526.  
  527. FUNCTION tKeyColInputLine.IndexOf(P: pString): INTEGER;
  528. VAR
  529.   T: tKeyRec;
  530.   Index: INTEGER;
  531. BEGIN
  532.   T.Key := P;
  533.   Index := Col^.IndexOf(@T);
  534.   IF Index = -1 THEN
  535.     IndexOf := OutOfRange ELSE
  536.     IndexOf := Index;
  537. END;
  538.  
  539.  
  540. PROCEDURE tKeyColInputLine.SetData (VAR Rec);
  541. BEGIN
  542.   Value := INTEGER(Rec);
  543.   Data^ := pKeyRec(Col^.At(Value))^.Key^;
  544. END;
  545.  
  546.  
  547.  
  548. (* ------------------------------------------------------ *)
  549. (*                       tMacro                           *)
  550. (* ------------------------------------------------------ *)
  551.  
  552.  
  553. CONSTRUCTOR tMacro.Init;
  554. BEGIN
  555.   tObject.Init;
  556.   MacroCol := New(pMacCol, Init(10, 5));
  557.   PlayCol := New(pCollection, Init(5, 1));
  558.   RecMacro := NIL;
  559.   Break.What := evKeyDown;
  560.   Break.KeyCode := kbGrayMinus;
  561.   IF LowMemory THEN BEGIN
  562.     Application^.OutOfMemory;
  563.     Application^.DisableCommands([cmRecordMacro..
  564.                                   cmLoadMacros]);
  565.     Fail;
  566.   END;
  567. END;
  568.  
  569.  
  570. DESTRUCTOR tMacro.Done;
  571. BEGIN
  572.   tObject.Done;
  573.   IF MacroCol <> NIL THEN Dispose(MacroCol, Done);
  574.   IF PlayCol <> NIL THEN Dispose(PlayCol, Done);
  575.   IF RecMacro <> NIL THEN Dispose(RecMacro, Done);
  576. END;
  577.  
  578.  
  579. CONSTRUCTOR tMacro.Load (VAR S: tStream);
  580. BEGIN
  581.   MacroCol := pMacCol(S.Get);
  582.   PlayCol := New(pCollection, Init(5, 1));
  583.   RecMacro := NIL;
  584. END;
  585.  
  586.  
  587. FUNCTION tMacro.BreakEvent (VAR Event: tEvent): BOOLEAN;
  588. BEGIN
  589.   BreakEvent := FALSE;
  590.   IF (Event.What = Break.What) AND
  591.      (Event.KeyCode = Break.KeyCode) THEN BEGIN
  592.     Sound(800);
  593.     Delay(40);
  594.     NoSound;
  595.     Event.What := evNothing;
  596.     BreakEvent := TRUE
  597.   END;
  598. END;
  599.  
  600.  
  601. FUNCTION tMacro.CurrentPlayer: pEvCol;
  602. BEGIN
  603.   IF PlayCol^.Count > 0 THEN
  604.     CurrentPlayer:= pEvCol(PlayCol^.At(
  605.                       Pred(PlayCol^.Count))) ELSE
  606.     CurrentPlayer:= NIL;
  607. END;
  608.  
  609.  
  610. FUNCTION tMacro.InitMacroDialog: pDialog;
  611. BEGIN
  612.   InitMacroDialog := New(pMacroDialog, Init(MacroCol));
  613. END;
  614.  
  615.  
  616. PROCEDURE tMacro.MacroDialog;
  617. VAR
  618.   Result  : WORD;
  619.   Index   : INTEGER;
  620.   EvColPtr: pEvCol;
  621.  
  622.   PROCEDURE EditMacro;
  623.   BEGIN
  624.     WITH RecMacDescr DO BEGIN
  625.       Title := EvColPtr^.Title^;
  626.       ScanIndex := EvColPtr^.ScanIndex;
  627.       Delayed := EvColPtr^.Delayed;
  628.       IF ExecDialog(CreateEditDialog, @RecMacDescr)
  629.          <> cmCancel THEN BEGIN
  630.         DisposeStr(EvColPtr^.Title);
  631.         EvColPtr^.Title := NewStr(Title);
  632.         EvColPtr^.ScanIndex := ScanIndex;
  633.         EvColPtr^.Delayed := Delayed;
  634.       END;
  635.     END;
  636.   END;
  637.  
  638. BEGIN
  639.   Index := 0;
  640.   Result := ExecDialog(InitMacroDialog, @EvColPtr);
  641.   IF Result <> cmCancel THEN
  642.     IF EvColPtr <> NIL THEN
  643.       CASE Result OF
  644.         cmReplayMacro: PlayCol^.Insert(EvColPtr);
  645.         cmEditMacro  : EditMacro;
  646.         cmNewMacro   : RecordMacro;
  647.       END;
  648. END;
  649.  
  650.  
  651. PROCEDURE tMacro.Recorder (VAR Event: TEvent);
  652. VAR
  653.   Index: INTEGER;
  654. BEGIN
  655.   IF RecMacro <> NIL THEN
  656.     IF NOT BreakEvent(Event) THEN BEGIN
  657.       IF (Event.What AND RecMacro^.EventMask <> 0) AND
  658.          (PlayCol^.Count = 0) THEN BEGIN
  659.         RecMacro^.InsertEvent(Event);
  660.         IF LowMemory THEN BEGIN
  661.           Application^.OutOfMemory;
  662.           Application^.PutEvent(Break);
  663.         END;
  664.       END
  665.     END ELSE BEGIN
  666.       MacroCol^.Insert(RecMacro);
  667.       RecMacro := NIL;
  668.     END;
  669. END;
  670.  
  671.  
  672. PROCEDURE tMacro.RecordMacro;
  673. VAR
  674.   Ok: BOOLEAN;
  675.   Index: INTEGER;
  676. BEGIN
  677.   FillChar(RecMacDescr, SizeOf(tRecordMacro), 0);
  678.   REPEAT
  679.     Ok := TRUE;
  680.     IF ExecDialog(CreateRecordDialog, @RecMacDescr)
  681.        <> cmCancel THEN
  682.       WITH RecMacDescr DO
  683.         IF EventMask <> 0 THEN BEGIN
  684.           RecMacro := New(pEvCol, Init(Title, ScanIndex,
  685.                           Delayed, EventMask));
  686.           IF LowMemory THEN
  687.             Application^.OutOfMemory ELSE BEGIN
  688.               Ok := NOT MacroCol^.Search(RecMacro, Index);
  689.               IF NOT Ok THEN BEGIN
  690.                 MessageBox(#13#3'Makro-Name schon belegt!',
  691.                            NIL, mfError + mfOkButton);
  692.                 Dispose(RecMacro, Done);
  693.                 RecMacro := NIL;
  694.               END;
  695.             END;
  696.         END;
  697.   UNTIL Ok;
  698. END;
  699.  
  700.  
  701. FUNCTION tMacro.Replay (VAR Event: TEvent): INTEGER;
  702. BEGIN
  703.   Replay := PlayCol^.Count;
  704.   IF PlayCol^.Count > 0 THEN
  705.     IF CurrentPlayer^.GetNextEvent(Event) THEN
  706.       Delay(CurrentPlayer^.Delayed) ELSE
  707.       PlayCol^.Delete(CurrentPlayer)
  708.   ELSE Event.What := evNothing;
  709. END;
  710.  
  711.  
  712. FUNCTION tMacro.ReplayHotKey (KeyCode: WORD): BOOLEAN;
  713. VAR
  714.   EvColPtr: pEvCol;
  715.  
  716.   FUNCTION GetIndex (P: pEvCol): BOOLEAN; FAR;
  717.   BEGIN
  718.     GetIndex := pKeyRec(KeyCol^.At(P^.ScanIndex))^.Value
  719.               = KeyCode;
  720.   END;
  721.  
  722. BEGIN
  723.   ReplayHotKey := TRUE;
  724.   EvColPtr := MacroCol^.FirstThat(@GetIndex);
  725.   IF EvColPtr <> NIL THEN
  726.     PlayCol^.Insert(EvColPtr) ELSE
  727.     ReplayHotKey := FALSE;
  728. END;
  729.  
  730.  
  731. PROCEDURE tMacro.Store (VAR S: tStream);
  732. BEGIN
  733.   S.Put(MacroCol);
  734. END;
  735.  
  736.  
  737.  
  738. (* ------------------------------------------------------ *)
  739. (*                    tMacroListBox                       *)
  740. (* ------------------------------------------------------ *)
  741.  
  742.  
  743. CONSTRUCTOR tMacroListBox.Init (VAR Bounds: tRect;
  744.                     AScrollBar: pScrollBar; AList: pMacCol);
  745. VAR
  746.   R: tRect;
  747.   C: pScrollBar;
  748. BEGIN
  749.   IF AList = NIL THEN Fail;
  750.   tListBox.Init(Bounds, 1, AScrollBar);
  751.   NewList(AList);
  752. END;
  753.  
  754.  
  755. PROCEDURE tMacroListBox.GetData (VAR Rec);
  756. BEGIN
  757.   IF List^.Count > 0 THEN
  758.     pEvCol(Rec) := pEvCol(List^.At(Focused)) ELSE
  759.     pEvCol(Rec) := NIL;
  760. END;
  761.  
  762.  
  763. FUNCTION tMacroListBox.GetText (Item, MaxLen: INTEGER)
  764.                                : STRING;
  765. VAR
  766.   Result: STRING;
  767.   Params: ARRAY[0..1] OF POINTER;
  768. BEGIN
  769.   Params[0] := pEvCol(List^.At(Item))^.Title;
  770.   Params[1] := pKeyRec(KeyCol^.At(pEvCol(
  771.                 List^.At(Item))^.ScanIndex))^.Key;
  772.   FormatStr(Result, '%-18s %-12s', Params);
  773.   GetText := Copy(Result, 1, MaxLen);
  774. END;
  775.  
  776.  
  777. PROCEDURE TMacroListBox.HandleEvent(VAR Event: TEvent);
  778. BEGIN
  779.   IF (Event.What = evMouseDown) AND (Event.DOUBLE) THEN
  780.   BEGIN
  781.     Event.What := evCommand;
  782.     Event.Command := cmOK;
  783.     PutEvent(Event);
  784.     ClearEvent(Event);
  785.   END ELSE TListBox.HandleEvent(Event);
  786. END;
  787.  
  788.  
  789. PROCEDURE tMacroListBox.SetData (VAR Rec);
  790. BEGIN
  791. END;
  792.  
  793.  
  794.  
  795. (* ------------------------------------------------------ *)
  796. (*                     tMacroDialog                       *)
  797. (* ------------------------------------------------------ *)
  798.  
  799.  
  800. CONSTRUCTOR tMacroDialog.Init (AList: pMacCol);
  801. VAR
  802.   R: tRect;
  803.   C: pView;
  804. BEGIN
  805.   R.Assign(0, 0, 57, 17);
  806.   tDialog.Init(R, 'Makros');
  807.  
  808.   Options := Options OR ofCentered;
  809.  
  810.   R.Assign( 36, 3, 37, 14);
  811.   C := New(pScrollBar, Init(R));
  812.   Insert(C);
  813.  
  814.   R.Assign( 3, 3, 36, 14);
  815.   MacroListBox := New(pMacroListBox, Init(R, pScrollBar(C),
  816.                                           AList));
  817.   Insert(MacroListBox);
  818.   R.Assign( 2, 2, 12, 3);
  819.   Insert(New(pXLabel, Init(R, '~M~akros', C)));
  820.  
  821.   R.Assign(38, 3, 55, 5);
  822.   Insert(New(pButton, Init(R, ' ~A~usführen', cmReplayMacro,
  823.                            bfDefault + bfLeftJust)));
  824.   R.Move(0, 2);
  825.   Insert(New(pButton, Init(R, ' ~B~earbeiten', cmEditMacro,
  826.                            bfNormal + bfLeftJust)));
  827.   R.Move(0, 2);
  828.   Insert(New(pButton, Init(R, ' ~N~eu', cmNewMacro,
  829.                            bfNormal + bfLeftJust)));
  830.   R.Move(0, 2);
  831.   Insert(New(pButton, Init(R, ' ~L~öschen', cmDeleteMacro,
  832.                            bfNormal + bfLeftJust)));
  833.   R.Move(0, 2);
  834.   Insert(New(pButton, Init(R, ' A~l~le löschen',
  835.         cmDeleteAllMacros, bfNormal + bfLeftJust)));
  836.   R.Move(0, 2);
  837.   Insert(New(pButton, Init(R, ' Abbruch', cmCancel,
  838.                            bfNormal + bfLeftJust)));
  839.   SelectNext(FALSE);
  840. END;
  841.  
  842.  
  843. CONSTRUCTOR tMacroDialog.Load (VAR S: tStream);
  844. BEGIN
  845.   tDialog.Load(S);
  846.   GetSubViewPtr(S, MacroListBox);
  847. END;
  848.  
  849.  
  850. PROCEDURE tMacroDialog.HandleEvent (VAR Event: tEvent);
  851. VAR
  852.   EvColPtr: pEvCol;
  853. BEGIN
  854.   tDialog.HandleEvent(Event);
  855.   IF (Event.What = evCommand) THEN
  856.     WITH MacroListBox^ DO BEGIN
  857.       CASE Event.Command OF
  858.         cmDeleteAllMacros:
  859.           List^.FreeAll;
  860.         cmDeleteMacro:
  861.           BEGIN
  862.             GetData(EvColPtr);
  863.             IF EvColPtr <> NIL THEN List^.Free(EvColPtr);
  864.           END;
  865.         ELSE
  866.           Exit;
  867.       END;
  868.       SetRange(List^.Count);     (* wird meist vergessen! *)
  869.       DrawView;
  870.       ClearEvent(Event);
  871.     END;
  872. END;
  873.  
  874.  
  875. PROCEDURE tMacroDialog.Store (VAR S: tStream);
  876. BEGIN
  877.   tDialog.Store(S);
  878.   PutSubViewPtr(S, MacroListBox);
  879. END;
  880.  
  881.  
  882.  
  883. (* ------------------------------------------------------ *)
  884. (*                  tMacroApplication                     *)
  885. (* ------------------------------------------------------ *)
  886.  
  887.  
  888. CONSTRUCTOR tMacroApplication.Init;
  889. BEGIN
  890.   tApplication.Init;
  891.   MacroObj := NIL;
  892.   Pending.What := evNothing;
  893. END;
  894.  
  895.  
  896. FUNCTION tMacroApplication.EventAvail : BOOLEAN;
  897. BEGIN
  898.   IF MacroObj <> NIL THEN
  899.     EventAvail := tApplication.EventAvail AND
  900.                   (MacroObj^.CurrentPlayer <> NIL) ELSE
  901.     EventAvail := tApplication.EventAvail;
  902. END;
  903.  
  904.  
  905. PROCEDURE tMacroApplication.GetEvent (VAR Event: tEvent);
  906.  
  907.   FUNCTION ContainsMouse (P: pView): BOOLEAN; FAR;
  908.   BEGIN
  909.     ContainsMouse := (P^.State AND sfVisible <> 0) AND
  910.                       P^.MouseInView(Event.Where);
  911.   END;
  912.  
  913. BEGIN
  914.   IF MacroObj <> NIL THEN BEGIN
  915.     IF Pending.What <> evNothing THEN BEGIN
  916.       Event := Pending;
  917.       Pending.What := evNothing;
  918.     END ELSE IF MacroObj^.Replay(Event) = 0 THEN BEGIN
  919.       GetMouseEvent(Event);
  920.       IF Event.What = evNothing THEN BEGIN
  921.         GetKeyEvent(Event);
  922.         IF Event.What = evNothing THEN Idle;
  923.       END;
  924.       MacroObj^.Recorder(Event);
  925.     END;
  926.     IF StatusLine <> NIL THEN
  927.       IF (Event.What AND evKeyDown <> 0) OR
  928.          (Event.What AND evMouseDown <> 0) AND
  929.          (FirstThat(@ContainsMouse) = pView(StatusLine))
  930.         THEN StatusLine^.HandleEvent(Event);
  931.   END ELSE tApplication.GetEvent(Event);
  932. END;
  933.  
  934.  
  935. PROCEDURE tMacroApplication.HandleEvent (VAR Event: tEvent);
  936. BEGIN
  937.   IF (MacroObj <> NIL) AND (Event.What = evKeyDown) THEN
  938.     IF MacroObj^.ReplayHotKey(Event.KeyCode) THEN
  939.       ClearEvent(Event);
  940.   tApplication.HandleEvent(Event);
  941. END;
  942.  
  943.  
  944. PROCEDURE tMacroApplication.Idle;
  945. BEGIN
  946.   tApplication.Idle;
  947.   IF MacroObj <> NIL THEN
  948.     IF MacroObj^.RecMacro <> NIL THEN
  949.       DisableCommands([cmRecordMacro, cmSaveMacros,
  950.                        cmLoadMacros]) ELSE
  951.       EnableCommands([cmRecordMacro, cmSaveMacros,
  952.                     cmLoadMacros]);
  953. END;
  954.  
  955.  
  956. PROCEDURE tMacroApplication.PutEvent (VAR Event: TEvent);
  957. BEGIN
  958.   Pending := Event;
  959. END;
  960.  
  961.  
  962.  
  963.  
  964. PROCEDURE LoadKeyStream;
  965. VAR
  966.   KeyStream: tDosStream;
  967. BEGIN
  968.   KeyStream.Init(StreamName, stOpenRead);
  969.   KeyCol := pKeyCol(KeyStream.Get);
  970.   IF KeyStream.Status <> stOk THEN BEGIN
  971.     PrintStr('KBCONST.STM nicht gefunden.');
  972.     Halt(1);
  973.   END;
  974.   KeyStream.Done;
  975. END;
  976.  
  977.  
  978. PROCEDURE RegisterXMacro;
  979. BEGIN
  980.   RegisterType(rKeyCol);
  981.   RegisterType(rEvCol);
  982.   RegisterType(rMacCol);
  983.   RegisterType(rKeyColInputLine);
  984.   RegisterType(rMacroListBox);
  985.   RegisterType(rMacro);
  986.   RegisterType(rMacroDialog);
  987. END;
  988.  
  989.  
  990. END.
  991.  
  992.  
  993. (* ------------------------------------------------------ *)
  994. (*                 Ende von XMACRO.PAS                    *)
  995.