e-mail    Debatní kniha    Mapa stránek    Hlavní  
 perličky 
 

Makra -- sousto pro váš program

Zbyšek Hlinka

Základní vytvoření maker je poměrně jednoduché, zejména při použití v knihovnách Turbo Vision. Podstata makra -- tedy zapamatování si definované sekvence kláves a její pozdější volání na povel -- si říká o to, aby ovladač klávesnice byl v programu na jednom místě a veškerá obsluha procesů probíhala právě přes něj. Tuto podmínku splňuje Turbo Vision v jednotce APP.PAS v metodě TProgram.GetEvent.

Níže uvedená jednotka obsluhuje proces vytváření a volání maker. Zde je uveden pouze základní nástin, jednotku lze doplnit ještě o uložení a načítání maker ze souboru. Použitím dynamických proměnných (zde jsou jen statické) lze docílit delších maker, v takovém případě je však nutno hlídat volnou paměť při rozšiřování makra.

Vzhledem k definici různých funkcí v Turbo Vision směsí všemožných kláves jsem volil pro volání maker neobsazenou kombinaci Ctrl-Alt-Fn.

Nemáte-li k dispozici zdrojový text jednotky APP, můžete zařadit práci s TMakro do vlastní aplikace do GetEvent, potom však musíte evidovat i Event.What, protože TProgram.GetEvent převádí klávesy definované ve StatusLine na událost Command. Hlídání Event.What platí i v případě, že chcete mít možnost ovládat makro zároveň pomocí myši.

S případnými dotazy se obracejte na adresu: Zbyšek Hlinka, Kryštofova 1016, 149 00 Praha 4, tel. (02) 795 29 56.

{$O+,F+,X+,I-,V-,S-}
unit Makra;

interface
uses Objects,Views,Drivers,Dialogs;

type
  MakroRecord=record  {struktura makra}
    Jmeno:string[14]; {jméno makra}
    Num:byte;         {počet hodnot uložených do makra}
    Mac:array[0..255] of word;  {makro řetězec}
  end;

  PMakro=^TMakro;
  TMakro=object(TObject)
    constructor Init;
    procedure GetEvent(var Event:TEvent);
    procedure Select;   {vybere a spustí předdef. makro}
    procedure SetMakro; {zapne/vypne pořizování makra}
  private
    MakraRec:boolean;    {je makro pořizováno?}
    Mak:array[0..9] of MakroRecord; {pole uložených maker}
    MacPrac:MakroRecord; {pracovní makro struktura}
    StartMac:byte;       {které makro z Mak je voláno}
    CurMac:word;         {která položka z volaného makra
                          se má provést}
    WasMac:boolean;      {indikátor ukončení běhu makra}
    WhereMac:word;       
    LastWhat:word;       {poslední akce při ukončení
                          pořizování makra}
    function EditDialog(Jaky:byte):PDialog;
    procedure MakroDialog;
  end;

var
  Makro:PMakro;

implementation
uses App,MsgBox;

const
  mkDef=1;
  mkSel=2;

constructor TMakro.Init;
begin
  inherited Init;
  StartMac:=$FF;
end;

procedure TMakro.GetEvent(var Event:TEvent);
var
  ShiftState:byte;
begin
  if Event.What and (evKeyDown+evMouseDown)<>0
     then LastWhat:=Event.What;
  ShiftState:=Mem[Seg0040:$17];
  if WasMac then {jestliže bylo ukončeno
                  pořizování makra}
  begin
    WasMac:=MenuBar^.State and sfSelected<>0;
    if WasMac then {ukončení bylo pomocí menu}
    begin {zruš menu}
      Event.What:=evKeyDown;
      Event.KeyCode:=kbEsc;
      Event.InfoPtr:=nil;
      WasMac:=false;
    end;
  end;
  if MakraRec then {nahrávání makra}
  if Event.What=evKeyDown then {stisk klávesy,
                                myš ignorována}
  if MacPrac.Num<255 then {povolená délka makra}
  begin
    Inc(MacPrac.Num);
    MacPrac.Mac[Pred(MacPrac.Num)]:=Event.KeyCode;
  end;
  if ShiftState and (kbCtrlShift+kbAltShift)
     =kbCtrlShift+kbAltShift then
  with Event do
  if What=evKeyDown then {jestliže Ctrl-Alt-Fn}
  if (KeyCode>=kbAltF1) and (KeyCode<=kbAltF10) then
  if Mak[ScanCode-$68].Num>0 then StartMac:=ScanCode-$68;
  if StartMac<$FF then {jestliže je vybrané některé makro}
  begin
    Inc(CurMac);
    Event.What:=evKeyDown; {naplň Event}
    Event.KeyCode:=Mak[StartMac].Mac[Pred(CurMac)];
    Event.InfoPtr:=nil;
    if CurMac=Mak[StartMac].Num then
    begin {jestliže je provádění makra u konce}
      StartMac:=$FF;
      CurMac:=0;
      WasMac:=true;
    end;
  end;
end;

function TMakro.EditDialog(Jaky:byte):PDialog;
var
  D:PDialog;
  R:TRect;
begin
  R.Assign(0,0,38,15);
  D:=New(PDialog,Init(R,'Makra'));
  with D^ do begin
    Options:=Options or ofCentered;
    R.Assign(2,1,36,11);
    Insert(New(PRadioButtons,Init(R,
      NewSItem('Ctrl-Alt-F1 : '+Mak[0].Jmeno,
      NewSItem('Ctrl-Alt-F2 : '+Mak[1].Jmeno,
      NewSItem('Ctrl-Alt-F3 : '+Mak[2].Jmeno,
      NewSItem('Ctrl-Alt-F4 : '+Mak[3].Jmeno,
      NewSItem('Ctrl-Alt-F5 : '+Mak[4].Jmeno,
      NewSItem('Ctrl-Alt-F6 : '+Mak[5].Jmeno,
      NewSItem('Ctrl-Alt-F7 : '+Mak[6].Jmeno,
      NewSItem('Ctrl-Alt-F8 : '+Mak[7].Jmeno,
      NewSItem('Ctrl-Alt-F9 : '+Mak[8].Jmeno,
      NewSItem('Ctrl-Alt-F10: '+Mak[9].Jmeno,
    nil)))))))))))));
    R.Assign(3,12,15,14);
    if Jaky and mkDef<>0 then
      Insert(New(PButton,Init(R,'~P~ojmenuj',
                              cmOk,bfDefault)));
    if Jaky and mkSel<>0 then
      Insert(New(PButton,Init(R,'~O~K',
                              cmOk,bfDefault)));
    R.Assign(18,12,30,14);
    Insert(New(PButton,Init(R,'Odvolej',
                            cmCancel,bfNormal)));
    SelectNext(false);
  end;
  EditDialog:=D;
end;

procedure TMakro.MakroDialog;
var
  R:TRect;
  Name:string[14];
begin
  R.Assign(26,(Desktop^.Size.Y div 2)-4,26+28,
              (Desktop^.Size.Y div 2)+3);
  repeat
    if Application^.ExecuteDialog(EditDialog(mkDef),
       @WhereMac)=cmOk then
    begin {uloží nadefinované makro pod
           nějakou položku pole}
      Name:=Mak[WhereMac].Jmeno;
      if InputBoxRect(R,'Jméno makra',
                     '~J~méno',Name,14)=cmOk then
      begin
        Move(MacPrac,Mak[WhereMac],SizeOf(MacPrac));
        Mak[WhereMac].Jmeno:=Name;
        Break;
      end;
    end else Break;
  until false;
  FillChar(MacPrac,SizeOf(MacPrac),0);
end;

procedure TMakro.Select;
begin 
  if Application^.ExecuteDialog(EditDialog(mkSel),
     @WhereMac)=cmOk then
  if Mak[WhereMac].Num>0 then
  StartMac:=WhereMac;
end;

procedure TMakro.SetMakro;
begin
  MakraRec:=not MakraRec;
  if not MakraRec then
  begin
    if LastWhat=evKeyDown then Dec(MacPrac.Num);
    MakroDialog;
  end;
end;

end.
Vlastní jednotku je ovšem nutno začlenit do programu. Nejvhodnějším místem je jednotka APP.PAS. Jednotlivé klíčové metody lze zařadit do jednotky APP takto (označeno !!!!):
procedure TProgram.GetEvent(var Event: TEvent);
begin
  ...
  begin
    GetMouseEvent(Event);
    if Event.What = evNothing then
    begin
      GetKeyEvent(Event);
      if Event.What = evNothing then Idle;
    end;
    Makro^.GetEvent(Event);   {!!!!}
  end;
  ...
end;

constructor TApplication.Init;
begin
  ...
  TProgram.Init;
  Makro:=New(PMakro,Init);   {!!!!}
end;

destructor TApplication.Done;
begin
  if Makro<>nil then Dispose(Makro,Done);   {!!!!}
  TProgram.Done;
  ...
end;

procedure TApplication.HandleEvent(var Event: TEvent);
begin  {při volání pomocí menu}
  inherited HandleEvent(Event);
  case Event.What of
    evCommand:
      begin
        case Event.Command of
          ...
          cmMakra:Makro^.SetMakro;       {!!!!}
          cmSelectMakra:Makro^.Select;   {!!!!}
        else
        ...
end;



Pascal - hlavní
Překladače
Vlastní články
Převzaté články
Věci na stáhnutí
Odkazy k tématu
BP7 buglist
Chyba Run-time 200

BASIC