Újra itt vagyunk néhány rövidke mondanivalóval. Elôzô számunkban 'csodálatos' adatnyilvántaró Turbo Vision-ös programunkban szépen megnézhettük a már létezô személyek adatait, sôt újakat is hozhattunk létre, s mindezt kollekciókkat tároltuk a közönség bámulatba ejtése végett. (Persze nem mintha ez olyan nagy dolog lenne, csak így elegánsabb !) De a t. Olvasó joggal hiányolhat egy dolgot: "az jól van, hogy az Alma Józsi a legelsô személy a nyílvántartásban és az is, hogy a Xerox Marox meg az utolsó, de Piripócs Ödömér hányadik kliens. És egyáltalán hány személyt tartunk nyílván összesen ?" Ennek megmutatása a legszembetűnôbb helyen kell, hogy megtörténjen, pl. az ablak bal alsó sarkában a kereten !

De a bökkenô csak ott van, hogy a Turbo Vision-nek nincs ilyen alap objektuma ... Ciki ... Hát egye-fene akkor csináljunk magunk ! Ennek megoldására segítségül hívjuk a Turbo Vision példatárának Count.PAS forráskódját (Copyright (c) 1992 Borland International.), melyet itt-ott megtoldunk egy kicsivel, hogy magyarosabb legyen. Nem kívánom hasonló analógia alapján újra megírni a Count.PAS file-t, hisz hasonlóan nézne ki. (Ugyanis ezt a problémát nem lehet sok féle képen megoldani. Csak a metódus nevek, ill. a változók publicitása lenne ill. lehetne más.) Milyen lépésekbôl áll egy új view objektum létrehozása ?

Elsô nagy nagy nagy nagy lépés: (huhhh milyen bonyolult ... :-) )

Második elrettentô lépés: Utolsó szívfacsaró lépés: Aki tudta idáig tartani a lépést, és nem dôlt ki a lökött - esetleg besült poénoktól annak meghálálom az alábbiakkal: (sorry guys, de két napja gép elôtt ülök, s a vacsorám is csak mezei objektumok voltak, s gülübe állt a szemem ...)

Szóval (erôt veszek ...). Lássuk az objektum felépítését:

type
  PCountView = ^TCountView;
  TCountView = Object(TView)
    Current: Longint;
    Count  : Longint;
    constructor Init(var Bounds: Trect);
    constructor Load(var S: TStream);
    procedure Draw; virtual;
    function  GetPalette: PPalette; virtual;
    procedure SetCount(NewCount: Longint);
    procedure IncCount;
    procedure DecCount;
    procedure SetCurrent(NewCurrent: Longint);
    procedure IncCurrent;
    procedure DecCurrent;
    procedure Store(var S: TStream); virtual;
  end;
Hát igen:
constructor TCountView.Init(var Bounds:TRect);
begin
  Inherited Init(Bounds);
  SetCount(0);
  SetCurrent(1);
end;
Hát igen ez egy diplomatikus megoldás volt, csak az elôd (az örökölt) Init()-et hívtuk, meg, s beállítottuk kezdôértékre a Count és Current változókat:
procedure TCountView.SetCount(NewCount:Longint);
begin
  Count := NewCount;
  DrawView;
end;

procedure TCountView.SetCurrent(NewCurrent:Longint);
begin
  Current := NewCurrent;
  DrawView;
end;
Csak a változókat módosítjuk, de alattomos módon a modosítás után ki akarjuk írni a képernyôre az új információ(ka)t s emiatt kell meghívni a DrawView; metódust. Ehhez annyit kell tudni, hogy a DrawView; metódus a TView-tól kezdôdôen abban, s utódaiban létezik. A DrawView; a virtuális Draw; metódust hívja meg, így nekünk csak a TView Draw-ját kell átírni, hogy szépen kiírhassuk a képernyôre amit akarunk. Lássuk a lényeget:
procedure TCountView.Draw;

  function GetRag(ForRag: Longint): String;
  begin
    case ForRag mod 10 of
      0, 3, 6, 8: GetRag:='ból';
      1, 2, 4, 5, 7, 9, 10: GetRag:='bôl';
      else GetRag:='bôl';
    end;
  end;

  function  ConvertLongintToString(d: Longint): String;
  var S: String;
  begin
    Str(d,s);
    ConvertLongintToString:=S;
  end;

  function GetNevelo(ANevelo: Longint): String;
  var
    S: String;
    B, i: Byte;
    L: Longint;
  begin
    S:=ConvertLongintToString(ANevelo);
    B:=Byte(Length(S));
    L:=10;
    for i:=1 to B-1 do L:=L*10;
    B:=ANevelo mod L;
    case B of
      0, 2, 3, 4, 6, 7, 8, 9: GetNevelo:='A';
      1, 5, 10: GetNevelo:='Az';
      else GetNevelo:='A';
    end;
  end;

  function GetHanyadik(ADik: Longint): String;
  begin
    if ADik = 1 then GetHanyadik:='elsô'
                else GetHanyadik:=ConvertLongintToString(ADik)+'.';
  end;

var
  B: TDrawBuffer;
  C: Word;
  {Params : Array[0..1] of Longint;} {Remarked By R4s}
  Start  : Word;
  First  : String[10];
  Display: String[20];
begin
  C := GetColor(2);  { Uses same color as frame }
  MoveChar(B, '=', C, Size.X);

  {Params[0] := Current;
  Params[1] := Count;
  FormatStr(Display, ' ~%d~ of %d ', Params);} {Remarked By R4s}
  FormatStr(Display, ' '+GetNevelo(Current)+' '+GetHanyadik(Current)+ ' a %d-'+GetRag(Count), Count);

  { If Current is greater than Count, display Current as highlighted }
  if Current > Count then C := GetColor($0504)
  else C := GetColor($0202);

  MoveCStr(B, Display, C);
  WriteLine(0, 0, Size.X, Length(Display), B);
end;
Kezdjük az eljén, pontosabban a TCountView.Draw; begin-jénél. Persze vannak Load() és Store() metódusok meg RegisterView()-ot használunk, de azok az elôzô számok alapján nyílván egyértelműek.

Nos a TCountView így, s ilyen egyszerűen működik, de ahhoz hogy látszódjon még a TAdatnyilvDialog-ot is módosítani kell:

type
  PAdatnyilvDialog = ^TAdatnyilvDialog;
  TAdatnyilvDialog = Object(TDialog)
    Szamlalo     : PCountView;
    { ... a többi a régi}
  end;
Nyílván a TAdatnyilvDialog Init-jét modosítani kell, hogy be legyen insert-elve a számlaló view:
constructor TAdatnyilvDialog.Init;
begin
  {... a többi a régi }
  R.Assign(4, 19, 25, 20);
  New(Szamlalo, Init(R));
  Szamlalo^.SetCount(AdatColl^.Count);
  Insert(Szamlalo);
end;
Áha, így jó ! Most már minden látszik, csak az értékeket kell frissíteni a TAdatnyilvDialog.HandleEvent()-tel. Legalább is az okosak szerint kell ott, szerintem most röptében megfelel nekünk a ShowAdatRec() metódusban is:
procedure TAdatnyilvDialog.ShowAdatRec(AAdatNum: Integer);
begin
  CurrentAdat := AAdatNum;
  TempAdatok := PAdatokObj(AdatColl^.At(CurrentAdat))^.AdatRec;
  SetData(TempAdatok);
  Szamlalo^.SetCurrent(AAdatNum + 1);
  { ... a többi a régi}
end;
Hát ennyi, nézzétek meg a példa programot, úgy könnyebb megérteni. Ha végképp nem megy akkor eMail-ezzetek. Következô számunkban ha minden igaz saját Turbo Vision átírásunkkal kezdünk foglalkozni (Lásd a TVDEMO.exe-t !). Persze lehet, hogy szót ejtünk pár apróságról ami kimaradhatott: TCheckBox(), TRadioButton(), stb..
 

Bérczi László
eMail:PC-XUser@IDG.HU, Subject: "OOP rovat"
BELA@MI.STUD.PMMFK.JPTE.HU

Felhasznált forráskód: Count.PAS, Copyright (c) 1992 Borland International.
PS: Sorry, hogy kicsit rövidebb lett, de a vizsgák, a leadási határidô is közelebb lett hozva ...
Majd a következôben ! :-)