home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 07 / floyd.lst < prev    next >
File List  |  1989-06-01  |  13KB  |  664 lines

  1. _TURBO PASCAL WITH OBJECTS_
  2. by Michael Floyd
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. program FDemo;
  8.  
  9. uses Crt, Forms, Sliders;
  10.  
  11. type
  12.  
  13.   Person = record
  14.     Firstname: string[30];
  15.     Lastname: string[30];
  16.     Address: string[32];
  17.     City: string[16];
  18.     State: string[2];
  19.     Zipcode: Longint;
  20.     Counter: array[1..3] of Longint;
  21.     Slider: array[1..2] of Integer;
  22.   end;
  23.  
  24. const
  25.  
  26.   Frank: Person = (
  27.     Firstname: 'Frank';
  28.     Lastname: 'Borland';
  29.     Address: '1800 Green Hills Road';
  30.     City: 'Scotts Valley';
  31.     State: 'CA';
  32.     Zipcode: 95066;
  33.     Counter: (10, 1000, 65536);
  34.     Slider: (85, 25));
  35.  
  36. var
  37.   F: Form;
  38.   P: Person;
  39.  
  40. begin
  41.   Color(BackColor);
  42.   ClrScr;
  43.   Color(ForeColor);
  44.   GotoXY(1, 1); ClrEol;
  45.   Write(' Turbo Pascal 5.5 Object Oriented Forms Editor');
  46.   GotoXY(1, 25); ClrEol;
  47.   Write(' F2-Save  Esc-Quit');
  48.   F.Init(10, 5, 54, 16);
  49.   F.Add(New(FStrPtr, Init(3, 2, ' Firstname ', 30)));
  50.   F.Add(New(FStrPtr, Init(3, 3, ' Lastname  ', 30)));
  51.   F.Add(New(FStrPtr, Init(3, 5, ' Address ', 32)));
  52.   F.Add(New(FStrPtr, Init(3, 6, ' City ', 16)));
  53.   F.Add(New(FStrPtr, Init(25, 6, ' State ', 2)));
  54.   F.Add(New(FZipPtr, Init(34, 6, ' Zip ')));
  55.   F.Add(New(FIntPtr, Init(3, 8, ' Counter 1 ', 0, 99999999)));
  56.   F.Add(New(FIntPtr, Init(22, 8, ' 2 ', 0, 99999999)));
  57.   F.Add(New(FIntPtr, Init(33, 8, ' 3 ', 0, 99999999)));
  58.   F.Add(New(FSliderPtr, Init(3, 10, ' Slider One ', 0, 100, 5)));
  59.   F.Add(New(FSliderPtr, Init(3, 11, ' Slider Two ', 0, 100, 5)));
  60.   P := Frank;
  61.   F.Put(P);
  62.   F.Show;
  63.   if F.Edit = CSave then F.Get(P);
  64.   F.Done;
  65.   NormVideo;
  66.   ClrScr;
  67.   WriteLn('Resulting Person record:');
  68.   WriteLn;
  69.   with P do
  70.   begin
  71.     WriteLn('Firstname: ', Firstname);
  72.     WriteLn(' Lastname: ', Lastname);
  73.     WriteLn('  Address: ', Address);
  74.     WriteLn('     City: ', City);
  75.     WriteLn('    State: ', State);
  76.     WriteLn('  Zipcode: ', Zipcode);
  77.     WriteLn(' Counters: ', Counter[1], ' ', Counter[2], ' ', Counter[3]);
  78.     WriteLn('  Sliders: ', Slider[1], ' ', Slider[2]);
  79.   end;
  80. end.
  81.  
  82.  
  83. [LISTING TWO]
  84.  
  85. unit Forms;
  86.  
  87. {$S-}
  88.  
  89. interface
  90.  
  91. uses Crt;
  92.  
  93. const
  94.  
  95.   CSkip  = ^@;
  96.   CHome  = ^A;
  97.   CRight = ^D;
  98.   CPrev  = ^E;
  99.   CEnd   = ^F;
  100.   CDel   = ^G;
  101.   CBack  = ^H;
  102.   CSave  = ^J;
  103.   CUndo  = ^R;
  104.   CLeft  = ^S;
  105.   CClear = ^Y;
  106.   CNext  = ^X;
  107.   CQuit  = ^[;
  108.  
  109. type
  110.  
  111.   FStringPtr = ^FString;
  112.   FString = string[79];
  113.  
  114.   FieldPtr = ^Field;
  115.   Field = object
  116.     Next: FieldPtr;
  117.     X, Y, Size: Integer;
  118.     Title: FStringPtr;
  119.     Value: Pointer;
  120.     constructor Init(PX, PY, PSize: Integer; PTitle: FString);
  121.     destructor Done; virtual;
  122.     procedure Beep; virtual;
  123.     function Edit: Char; virtual;
  124.     function ReadChar: Char; virtual;
  125.     procedure Show; virtual;
  126.     function Prev: FieldPtr;
  127.   end;
  128.  
  129.   FTextPtr = ^FText;
  130.   FText = object(Field)
  131.     Len: Integer;
  132.     constructor Init(PX, PY, PSize: Integer; PTitle: FString;
  133.       PLen: Integer);
  134.     function Edit: Char; virtual;
  135.     procedure GetStr(var S: FString); virtual;
  136.     function PutStr(var S: FString): Boolean; virtual;
  137.     procedure Show; virtual;
  138.     procedure Display(var S: FString);
  139.   end;
  140.  
  141.   FStrPtr = ^FStr;
  142.   FStr = object(FText)
  143.     constructor Init(PX, PY: Integer; PTitle: FString; PLen: Integer);
  144.     procedure GetStr(var S: FString); virtual;
  145.     function PutStr(var S: FString): Boolean; virtual;
  146.   end;
  147.  
  148.   FIntPtr = ^FInt;
  149.   FInt = object(FText)
  150.     Min, Max: Longint;
  151.     constructor Init(PX, PY: Integer; PTitle: FString;
  152.       PMin, PMax: Longint);
  153.     procedure GetStr(var S: FString); virtual;
  154.     function PutStr(var S: FString): Boolean; virtual;
  155.   end;
  156.  
  157.   FZipPtr = ^FZip;
  158.   FZip = object(FInt)
  159.     constructor Init(PX, PY: Integer; PTitle: FString);
  160.     procedure GetStr(var S: FString); virtual;
  161.     function PutStr(var S: FString): Boolean; virtual;
  162.   end;
  163.  
  164.   FormPtr = ^Form;
  165.   Form = object
  166.     X1, Y1, X2, Y2: Integer;
  167.     Last: FieldPtr;
  168.     constructor Init(PX1, PY1, PX2, PY2: Integer);
  169.     destructor Done; virtual;
  170.     function Edit: Char; virtual;
  171.     procedure Show; virtual;
  172.     procedure Add(P: FieldPtr);
  173.     function First: FieldPtr;
  174.     procedure Get(var FormBuf);
  175.     procedure Put(var FormBuf);
  176.   end;
  177.  
  178.   ColorIndex = (BackColor, ForeColor, TitleColor, ValueColor);
  179.  
  180. procedure Color(C: ColorIndex);
  181.  
  182. implementation
  183.  
  184. type
  185.  
  186.   Bytes = array[0..32767] of Byte;
  187.  
  188. procedure Abstract(Method: String);
  189. begin
  190.   WriteLn('Error: Call to abstract method ', Method);
  191.   Halt(1);
  192. end;
  193.  
  194. { Field }
  195.  
  196. constructor Field.Init(PX, PY, PSize: Integer; PTitle: FString);
  197. begin
  198.   X := PX;
  199.   Y := PY;
  200.   Size := PSize;
  201.   GetMem(Title, Length(PTitle) + 1);
  202.   Title^ := PTitle;
  203.   GetMem(Value, Size);
  204.   FillChar(Value^, Size, 0);
  205. end;
  206.  
  207. destructor Field.Done;
  208. begin
  209.   FreeMem(Value, Size);
  210.   FreeMem(Title, Length(Title^) + 1);
  211. end;
  212.  
  213. procedure Field.Beep;
  214. begin
  215.   Sound(500); Delay(25); NoSound;
  216. end;
  217.  
  218. function Field.Edit: Char;
  219. begin
  220.   Abstract('Field.Edit');
  221. end;
  222.  
  223. function Field.ReadChar: Char;
  224. var
  225.   Ch: Char;
  226. begin
  227.   Ch := ReadKey;
  228.   case Ch of
  229.     #0:
  230.       case ReadKey of
  231.         #15, #72: Ch := CPrev;    { Shift-Tab, Up }
  232.         #60: Ch := CSave;         { F2 }
  233.         #71: Ch := CHome;         { Home }
  234.         #75: Ch := CLeft;         { Left }
  235.         #77: Ch := CRight;        { Right }
  236.         #79: Ch := CEnd;          { End }
  237.         #80: Ch := CNext;         { Down }
  238.         #83: Ch := CDel;          { Del }
  239.       else
  240.         Ch := CSkip;
  241.       end;
  242.     #9, #13: Ch := CNext;         { Tab, Enter }
  243.   end;
  244.   ReadChar := Ch;
  245. end;
  246.  
  247. procedure Field.Show;
  248. begin
  249.   Abstract('Field.Show');
  250. end;
  251.  
  252. function Field.Prev: FieldPtr;
  253. var
  254.   P: FieldPtr;
  255. begin
  256.   P := @Self;
  257.   while P^.Next <> @Self do P := P^.Next;
  258.   Prev := P;
  259. end;
  260.  
  261. { FText }
  262.  
  263. constructor FText.Init(PX, PY, PSize: Integer; PTitle: FString;
  264.   PLen: Integer);
  265. begin
  266.   Field.Init(PX, PY, PSize, PTitle);
  267.   Len := PLen;
  268. end;
  269.  
  270. function FText.Edit: Char;
  271. var
  272.   P: Integer;
  273.   Ch: Char;
  274.   Start, Stop: Boolean;
  275.   S: FString;
  276. begin
  277.   P := 0;
  278.   Start := True;
  279.   Stop := False;
  280.   GetStr(S);
  281.   repeat
  282.     Display(S);
  283.     GotoXY(X + Length(Title^) + P, Y);
  284.     Ch := ReadChar;
  285.     case Ch of
  286.       #32..#255:
  287.         begin
  288.           if Start then S := '';
  289.           if Length(S) < Len then
  290.           begin
  291.             Inc(P);
  292.             Insert(Ch, S, P);
  293.           end;
  294.         end;
  295.       CLeft: if P > 0 then Dec(P);
  296.       CRight: if P < Length(S) then Inc(P) else;
  297.       CHome: P := 0;
  298.       CEnd: P := Length(S);
  299.       CDel: Delete(S, P + 1, 1);
  300.       CBack:
  301.         if P > 0 then
  302.         begin
  303.           Delete(S, P, 1);
  304.           Dec(P);
  305.         end;
  306.       CClear:
  307.         begin
  308.           S := '';
  309.           P := 0;
  310.         end;
  311.       CUndo:
  312.         begin
  313.           GetStr(S);
  314.           P := 0;
  315.         end;
  316.       CSave, CNext, CPrev:
  317.         if PutStr(S) then
  318.         begin
  319.           Show;
  320.           Stop := True;
  321.         end else
  322.         begin
  323.           Beep;
  324.           P := 0;
  325.         end;
  326.       CQuit: Stop := True;
  327.     else
  328.       Beep;
  329.     end;
  330.     Start := False;
  331.   until Stop;
  332.   Edit := Ch;
  333. end;
  334.  
  335. procedure FText.GetStr(var S: FString);
  336. begin
  337.   Abstract('FText.GetStr');
  338. end;
  339.  
  340. function FText.PutStr(var S: FString): Boolean;
  341. begin
  342.   Abstract('FText.PutStr');
  343. end;
  344.  
  345. procedure FText.Show;
  346. var
  347.   S: FString;
  348. begin
  349.   GetStr(S);
  350.   Display(S);
  351. end;
  352.  
  353. procedure FText.Display(var S: FString);
  354. begin
  355.   GotoXY(X, Y);
  356.   Color(TitleColor);
  357.   Write(Title^);
  358.   Color(ValueColor);
  359.   Write(S, '': Len - Length(S));
  360. end;
  361.  
  362. { FStr }
  363.  
  364. constructor FStr.Init(PX, PY: Integer; PTitle: FString; PLen: Integer);
  365. begin
  366.   FText.Init(PX, PY, PLen + 1, PTitle, PLen);
  367. end;
  368.  
  369. procedure FStr.GetStr(var S: FString);
  370. begin
  371.   S := FString(Value^);
  372. end;
  373.  
  374. function FStr.PutStr(var S: FString): Boolean;
  375. begin
  376.   FString(Value^) := S;
  377.   PutStr := True;
  378. end;
  379.  
  380. { FInt }
  381.  
  382. constructor FInt.Init(PX, PY: Integer; PTitle: FString;
  383.   PMin, PMax: Longint);
  384. var
  385.   L: Integer;
  386.   S: string[15];
  387. begin
  388.   Str(PMin, S); L := Length(S);
  389.   Str(PMax, S); if L < Length(S) then L := Length(S);
  390.   FText.Init(PX, PY, 4, PTitle, L);
  391.   Min := PMin;
  392.   Max := PMax;
  393. end;
  394.  
  395. procedure FInt.GetStr(var S: FString);
  396. begin
  397.   Str(Longint(Value^), S);
  398. end;
  399.  
  400. function FInt.PutStr(var S: FString): Boolean;
  401. var
  402.   N: Longint;
  403.   E: Integer;
  404. begin
  405.   Val(S, N, E);
  406.   if (E = 0) and (N >= Min) and (N <= Max) then
  407.   begin
  408.     Longint(Value^) := N;
  409.     PutStr := True;
  410.   end else PutStr := False;
  411. end;
  412.  
  413. { FZip }
  414.  
  415. constructor FZip.Init(PX, PY: Integer; PTitle: FString);
  416. begin
  417.   FInt.Init(PX, PY, PTitle, 0, 99999);
  418. end;
  419.  
  420. procedure FZip.GetStr(var S: FString);
  421. begin
  422.   FInt.GetStr(S);
  423.   Insert(Copy('0000', 1, 5 - Length(S)), S, 1);
  424. end;
  425.  
  426. function FZip.PutStr(var S: FString): Boolean;
  427. begin
  428.   PutStr := (Length(S) = 5) and FInt.PutStr(S);
  429. end;
  430.  
  431. { Form }
  432.  
  433. constructor Form.Init(PX1, PY1, PX2, PY2: Integer);
  434. begin
  435.   X1 := PX1;
  436.   Y1 := PY1;
  437.   X2 := PX2;
  438.   Y2 := PY2;
  439.   Last := nil;
  440. end;
  441.  
  442. destructor Form.Done;
  443. var
  444.   P: FieldPtr;
  445. begin
  446.   while Last <> nil do
  447.   begin
  448.     P := Last^.Next;
  449.     if Last = P then Last := nil else Last^.Next := P^.Next;
  450.     Dispose(P, Done);
  451.   end;
  452. end;
  453.  
  454. function Form.Edit: Char;
  455. var
  456.   P: FieldPtr;
  457.   Ch: Char;
  458. begin
  459.   Window(X1, Y1, X2, Y2);
  460.   P := First;
  461.   repeat
  462.     Ch := P^.Edit;
  463.     case Ch of
  464.       CNext: P := P^.Next;
  465.       CPrev: P := P^.Prev;
  466.     end;
  467.   until (Ch = CSave) or (Ch = CQuit);
  468.   Edit := Ch;
  469.   Window(1, 1, 80, 25);
  470. end;
  471.  
  472. procedure Form.Show;
  473. var
  474.   P: FieldPtr;
  475. begin
  476.   Window(X1, Y1, X2, Y2);
  477.   Color(ForeColor);
  478.   ClrScr;
  479.   P := First;
  480.   repeat
  481.     P^.Show;
  482.     P := P^.Next;
  483.   until P = First;
  484.   Window(1, 1, 80, 25);
  485. end;
  486.  
  487. procedure Form.Add(P: FieldPtr);
  488. begin
  489.   if Last = nil then Last := P else P^.Next := Last^.Next;
  490.   Last^.Next := P;
  491.   Last := P;
  492. end;
  493.  
  494. function Form.First: FieldPtr;
  495. begin
  496.   First := Last^.Next;
  497. end;
  498.  
  499. procedure Form.Get(var FormBuf);
  500. var
  501.   I: Integer;
  502.   P: FieldPtr;
  503. begin
  504.   I := 0;
  505.   P := First;
  506.   repeat
  507.     Move(P^.Value^, Bytes(FormBuf)[I], P^.Size);
  508.     Inc(I, P^.Size);
  509.     P := P^.Next;
  510.   until P = First;
  511. end;
  512.  
  513. procedure Form.Put(var FormBuf);
  514. var
  515.   I: Integer;
  516.   P: FieldPtr;
  517. begin
  518.   I := 0;
  519.   P := First;
  520.   repeat
  521.     Move(Bytes(FormBuf)[I], P^.Value^, P^.Size);
  522.     Inc(I, P^.Size);
  523.     P := P^.Next;
  524.   until P = First;
  525. end;
  526.  
  527. procedure Color(C: ColorIndex);
  528. type
  529.   Palette = array[ColorIndex] of Byte;
  530. const
  531.   CP: Palette = ($17, $70, $30, $5E);
  532.   MP: Palette = ($07, $70, $70, $07);
  533. begin
  534.   if LastMode = CO80 then TextAttr := CP[C] else TextAttr := MP[C];
  535. end;
  536.  
  537. end.
  538.  
  539.  
  540. [LISTING THREE]
  541.  
  542. unit Sliders;
  543.  
  544. {$S-}
  545.  
  546. interface
  547.  
  548. uses Crt, Forms;
  549.  
  550. type
  551.  
  552.   FSliderPtr = ^FSlider;
  553.   FSlider = object(Field)
  554.     Min, Max, Delta: Integer;
  555.     constructor Init(PX, PY: Integer; PTitle: FString;
  556.       PMin, PMax, PDelta: Integer);
  557.     function Edit: Char; virtual;
  558.     procedure Show; virtual;
  559.     procedure Display(I: Integer);
  560.   end;
  561.  
  562. implementation
  563.  
  564. constructor FSlider.Init(PX, PY: Integer; PTitle: FString;
  565.   PMin, PMax, PDelta: Integer);
  566. begin
  567.   Field.Init(PX, PY, 2, PTitle);
  568.   Min := PMin;
  569.   Max := PMax;
  570.   Delta := PDelta;
  571. end;
  572.  
  573. function FSlider.Edit: Char;
  574. var
  575.   I: Integer;
  576.   Ch: Char;
  577.   Stop: Boolean;
  578. begin
  579.   I := Integer(Value^);
  580.   Stop := False;
  581.   repeat
  582.     Display(I);
  583.     GotoXY(X + Length(Title^) + 1, Y);
  584.     Ch := ReadChar;
  585.     case Ch of
  586.       CLeft: if I > Min then Dec(I, Delta);
  587.       CRight: if I < Max then Inc(I, Delta);
  588.       CHome: I := Min;
  589.       CEnd: I := Max;
  590.       CUndo: I := Integer(Value^);
  591.       CSave, CQuit, CNext, CPrev: Stop := True;
  592.     else
  593.       Beep;
  594.     end;
  595.   until Stop;
  596.   if Ch <> CQuit then Integer(Value^) := I;
  597.   Edit := Ch;
  598. end;
  599.  
  600. procedure FSlider.Show;
  601. begin
  602.   Display(Integer(Value^));
  603. end;
  604.  
  605. procedure FSlider.Display(I: Integer);
  606. var
  607.   Steps: Integer;
  608.   S: FString;
  609. begin
  610.   Steps := (Max - Min) div Delta + 1;
  611.   S[0] := Chr(Steps);
  612.   FillChar(S[1], Steps, #176);
  613.   S[(I - Min) div Delta + 1] := #219;
  614.   GotoXY(X, Y);
  615.   Color(TitleColor);
  616.   Write(Title^);
  617.   Color(ValueColor);
  618.   Write(' ', Min, ' ', S, ' ', Max, ' ');
  619. end;
  620.  
  621. end.
  622.  
  623.  
  624.  
  625. Example 1. An object definition
  626.  
  627. type
  628.    ObjectName = object(Ancestor)
  629.       variable definitions;
  630.       method definitions; {virtual}
  631.    end;
  632.  
  633.  
  634.  
  635. Example 2. Code for a basic window
  636.  
  637. type
  638.  
  639.   Window = object
  640.     WindowNo : Integer;
  641.  
  642.     procedure DrawWindow(RowX, ColY, WHeight, WLen : Integer);
  643.     procedure RemoveWindow(WindoNo);
  644.   end;
  645.  
  646.  
  647.  
  648. Example 3. Code to create specialized windows.
  649.  
  650.   MenuList = string;
  651.   MenuBar = object(Window)
  652.  
  653.     procedureDrawWindow(RowX,ColY,WHeight,WLen:Integer;
  654.                         List:MenuList);
  655.      procedure Highlight(Item : Integer);
  656.      procedure MenuSelect(Item : Integer);
  657.      { etc... }
  658.   end;
  659.  
  660.    Pulldown = object(Window)
  661.      { pulldown methods }
  662.    end;
  663.  
  664.