Unit KonsoleUnit;
{
   Eine Unit, um damit eine Art Konsole zu erstellen.

   Aufruf mittels
      KonsoleFormCreate()   in zwei Fassungen   (mit/ohne Angabe der captions)
}

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
ComCtrls, StdCtrls, Buttons;

TYPE
  TKonsoleButtonStr = array[0..8] of string;

type TKonsole=class(TForm)
 private
  KonsoleWrapButton: TButton;
  KonsoleWritePermitButton: TButton;
  KonsoleClearButton: TSpeedButton;
  Memo: TMemo;

  procedure KonsoleWrapButtonClick(Sender: TObject); // Zeilenumbruch?
  procedure KonsoleWritePermitButtonClick(Sender: TObject); // in Memo schreiben?
  procedure KonsoleClearButtonClick(Sender: TObject); // Memo löschen

  procedure KonsoleFormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  procedure KonsoleFormResize(Sender: TObject);

  procedure KonsoleFormDestroy(Sender:TObject);
  procedure MainFormClose(Sender: TObject; var CloseAction: TCloseAction);

public
  constructor createNew(TheOwner: TComponent);
  procedure KonsoleFormCreate(f:Tform; Open_, Show_: TControl; Sender: TObject);
  procedure KonsoleFormCreate(f:Tform; Open_, Show_: TControl; TB:TKonsoleButtonStr; Sender: TObject);
  procedure ShowControls;
  end;


var Konsole:TKonsole;

const
   ButtonStr : TKonsoleButtonStr =
      ('Close Konsole', 'Open Konsole', 'Hide Konsole', 'Show Konsole',
       'Wrap', 'No Wrap', 'Writing', 'No Writing', 'Clear');
   maxEvent:integer = 500; // maximale Zeilenanzahl in der Memo

procedure Eventln(s:string);


implementation

{ $R *.lfm}

const
  KonsoleRect:TRect = (left:20; top:20; right:300; bottom:500);
            // zum Speichern der Konsole-Größe und -Position

  WritePermit:boolean = true;
          { damit kann man in die Memo auch schreiben, Text auswählen, löschen,
            verschieben etc. }
var
  alt_OpenCaption, alt_ShowCaption:string;
  Alt_Close: TCloseEvent;
  HauptForm:TCustomform;
  ShowCtl, OpenCtl: TControl;

   { TKonsole }

   constructor TKonsole.createNew(TheOwner: TComponent);
    begin
        inherited createNew(TheOwner);
    end;
   procedure TKonsole.KonsoleFormCreate(f:Tform; Open_, Show_: TControl; TB: TKonsoleButtonStr; Sender: TObject);
      begin
        ButtonStr:= TB;
        KonsoleFormCreate(f, Open_, Show_, Sender);
      end;

   procedure TKonsole.KonsoleFormCreate(f:Tform; Open_, Show_: TControl; Sender: TObject);
      var cf: TCustomForm;
    begin
         Hauptform:=f; OpenCtl:=open_; showCtl:= show_;
         alt_OpenCaption:=open_.caption; alt_ShowCaption:=show_.caption;

         Konsole:=TKonsole.CreateNew(nil);
              // createnew, weil in der lpr-Datei angegeben ist
              //   RequireDerivedFormResource := True;
       with Konsole do
         begin
           alt_Close:=Hauptform.OnClose;
           HauptForm.Onclose:=@MainFormClose;

           BoundsRect:=KonsoleRect;
           borderstyle := bsSizeable; Caption:='Konsole';
           show;
           onResize:=@KonsoleFormResize;
           onDestroy := @KonsoleFormDestroy;
       Memo:=TMemo.create(self);
         with Memo do
           begin
             Parent:=Konsole;
             Align:=albottom;
             ScrollBars:=ssAutoBoth;
             height:=Konsole.height-50;
             OnKeyDown := @KonsoleFormKeyDown; // um evtl. Texteingaben zu unterbinden
             show;
           end;
       KonsoleWrapButton:=TButton.Create(Konsole);
         with KonsoleWrapButton do
           begin
                parent:=Konsole;
                setbounds(10,10,75, 30);
                caption := ButtonStr[4+byte(Memo.wordwrap)];
                onclick:=@KonsoleWrapButtonclick;
                 show;
           end;
       KonsoleWritePermitButton:=TButton.Create(Konsole);
         with KonsoleWritePermitButton do
           begin
                parent:=Konsole;
                setbounds(90,10,75, 30);
                caption := ButtonStr[6+byte(WritePermit)];
                onclick:=@KonsoleWritePermitButtonclick;
                 show;
           end;
       KonsoleClearButton :=TSpeedButton.Create(self);
         with KonsoleClearButton do
           begin
             parent:=Konsole;
             setbounds(170,10,75,30);
             caption := ButtonStr[8];
             onclick:=@KonsoleClearButtonClick;
             show;
           end;
           cf:= GetParentForm(konsole);
           eventln( 'ParentForm = '+ cf.Name);
         end;
     end;

   procedure TKonsole.KonsoleFormDestroy(Sender: TObject);
     begin
        HauptForm.onclose:= Alt_Close;
       KonsoleRect:= BoundsRect; // Formsize speichern
       KonsoleWritePermitButton.free;
       KonsoleClearButton.free;
       KonsoleWrapButton.free;
       inherited;
       Konsole:=nil;
       ShowControls;
       openCtl.caption:= alt_OpenCaption;
       ShowCtl.caption:=alt_ShowCaption;
     end;
   procedure TKonsole.MainFormClose(Sender: TObject; var CloseAction: TCloseAction);
     begin
        if konsole <> nil
              then Konsole.free;
        HauptForm.close;
     end;


procedure TKonsole.KonsoleWrapButtonClick(Sender: TObject);
  begin with Memo do
    begin wordwrap:= not wordwrap;
       KonsoleWrapButton.caption:=ButtonStr[4+byte(wordwrap)];
    end;
  end;
procedure TKonsole.KonsoleWritePermitButtonClick(Sender: TObject);
  begin WritePermit := not WritePermit;
    KonsoleWritePermitButton.caption := ButtonStr[6+byte(WritePermit)];
  end;
procedure TKonsole.KonsoleClearButtonClick(Sender: TObject);
  begin
    Memo.lines.clear;
  end;

procedure TKonsole.KonsoleFormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if not WritePermit then key:=0; // => keine Tastatureingaben in der Memo!
end;
procedure TKonsole.KonsoleFormResize(Sender: TObject);
  begin
     Memo.Height:=height-50;
  end;

procedure TKonsole.ShowControls;
var
  show_, open_: boolean;
begin
  open_ := Konsole <> nil;
  show_ := False;
  if open_ then
    show_ := Konsole.Visible;
  ShowCtl.Caption:= ButtonStr[2+ byte(not show_)];
  OpenCtl.Caption := ButtonStr[byte(not open_)];
end;
procedure EventLn(s:string);
  begin
    if Konsole=nil then exit;
     with Konsole.Memo.lines do
            begin Add(s); if count > maxEvent then delete(0); end
  end;


end.

