home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l040 / 8.ddi / TVDEMO.ZIP / CALC.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-27  |  5.7 KB  |  267 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Vision Demo                            }
  4. {   Copyright (c) 1990 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. unit Calc;
  9.  
  10. {$F+,O+,S-}
  11.  
  12. { Calculator object. See TVDEMO.PAS for an example
  13.   program that uses this unit.
  14. }
  15.  
  16. interface
  17.  
  18. uses Drivers, Objects, Views, Dialogs;
  19.  
  20. type
  21.  
  22.   TCalcState = (csFirst, csValid, csError);
  23.  
  24.   PCalcDisplay = ^TCalcDisplay;
  25.   TCalcDisplay = object(TView)
  26.     Status: TCalcState;
  27.     Number: string[15];
  28.     Sign: Char;
  29.     Operator: Char;
  30.     Operand: Real;
  31.     constructor Init(var Bounds: TRect);
  32.     constructor Load(var S: TStream);
  33.     procedure CalcKey(Key: Char);
  34.     procedure Clear;
  35.     procedure Draw; virtual;
  36.     function GetPalette: PPalette; virtual;
  37.     procedure HandleEvent(var Event: TEvent); virtual;
  38.     procedure Store(var S: TStream);
  39.   end;
  40.  
  41.   PCalculator = ^TCalculator;
  42.   TCalculator = object(TDialog)
  43.     constructor Init;
  44.   end;
  45.  
  46. const
  47.   RCalcDisplay: TStreamRec = (
  48.      ObjType: 10040;
  49.      VmtLink: Ofs(TypeOf(TCalcDisplay)^);
  50.      Load:    @TCalcDisplay.Load;
  51.      Store:   @TCalcDisplay.Store
  52.   );
  53.   RCalculator: TStreamRec = (
  54.      ObjType: 10041;
  55.      VmtLink: Ofs(TypeOf(TCalculator)^);
  56.      Load:    @TCalculator.Load;
  57.      Store:   @TCalculator.Store
  58.   );
  59.  
  60. procedure RegisterCalc;
  61.  
  62. implementation
  63.  
  64. const
  65.   cmCalcButton = 100;
  66.  
  67. constructor TCalcDisplay.Init(var Bounds: TRect);
  68. begin
  69.   inherited Init(Bounds);
  70.   Options := Options or ofSelectable;
  71.   EventMask := evKeyDown + evBroadcast;
  72.   Clear;
  73. end;
  74.  
  75. constructor TCalcDisplay.Load(var S: TStream);
  76. begin
  77.   inherited Load(S);
  78.   S.Read(Status, SizeOf(Status) + SizeOf(Number) + SizeOf(Sign) +
  79.     SizeOf(Operator) + SizeOf(Operand));
  80. end;
  81.  
  82. procedure TCalcDisplay.CalcKey(Key: Char);
  83. var
  84.   R: Real;
  85.  
  86. procedure Error;
  87. begin
  88.   Status := csError;
  89.   Number := 'Error';
  90.   Sign := ' ';
  91. end;
  92.  
  93. procedure SetDisplay(R: Real);
  94. var
  95.   S: string[63];
  96. begin
  97.   Str(R: 0: 10, S);
  98.   if S[1] <> '-' then Sign := ' ' else
  99.   begin
  100.     Delete(S, 1, 1);
  101.     Sign := '-';
  102.   end;
  103.   if Length(S) > 15 + 1 + 10 then Error
  104.   else
  105.   begin
  106.     while S[Length(S)] = '0' do Dec(S[0]);
  107.     if S[Length(S)] = '.' then Dec(S[0]);
  108.     Number := S;
  109.   end;
  110. end;
  111.  
  112. procedure GetDisplay(var R: Real);
  113. var
  114.   E: Integer;
  115. begin
  116.   Val(Sign + Number, R, E);
  117. end;
  118.  
  119. procedure CheckFirst;
  120. begin
  121.   if Status = csFirst then
  122.   begin
  123.     Status := csValid;
  124.     Number := '0';
  125.     Sign := ' ';
  126.   end;
  127. end;
  128.  
  129. begin
  130.   Key := UpCase(Key);
  131.   if (Status = csError) and (Key <> 'C') then Key := ' ';
  132.   case Key of
  133.     '0'..'9':
  134.       begin
  135.         CheckFirst;
  136.         if Number = '0' then Number := '';
  137.         Number := Number + Key;
  138.       end;
  139.     '.':
  140.       begin
  141.         CheckFirst;
  142.         if Pos('.', Number) = 0 then Number := Number + '.';
  143.       end;
  144.     #8, #27:
  145.       begin
  146.         CheckFirst;
  147.         if Length(Number) = 1 then Number := '0' else Dec(Number[0]);
  148.       end;
  149.     '_', #241:
  150.       if Sign = ' ' then Sign := '-' else Sign := ' ';
  151.     '+', '-', '*', '/', '=', '%', #13:
  152.       begin
  153.         if Status = csValid then
  154.         begin
  155.           Status := csFirst;
  156.           GetDisplay(R);
  157.           if Key = '%' then
  158.             case Operator of
  159.               '+', '-': R := Operand * R / 100;
  160.               '*', '/': R := R / 100;
  161.             end;
  162.           case Operator of
  163.             '+': SetDisplay(Operand + R);
  164.             '-': SetDisplay(Operand - R);
  165.             '*': SetDisplay(Operand * R);
  166.             '/': if R = 0 then Error else SetDisplay(Operand / R);
  167.           end;
  168.         end;
  169.         Operator := Key;
  170.         GetDisplay(Operand);
  171.       end;
  172.     'C':
  173.       Clear;
  174.   end;
  175.   DrawView;
  176. end;
  177.  
  178. procedure TCalcDisplay.Clear;
  179. begin
  180.   Status := csFirst;
  181.   Number := '0';
  182.   Sign := ' ';
  183.   Operator := '=';
  184. end;
  185.  
  186. procedure TCalcDisplay.Draw;
  187. var
  188.   Color: Byte;
  189.   I: Integer;
  190.   B: TDrawBuffer;
  191. begin
  192.   Color := GetColor(1);
  193.   I := Size.X - Length(Number) - 2;
  194.   MoveChar(B, ' ', Color, Size.X);
  195.   MoveChar(B[I], Sign, Color, 1);
  196.   MoveStr(B[I + 1], Number, Color);
  197.   WriteBuf(0, 0, Size.X, 1, B);
  198. end;
  199.  
  200. function TCalcDisplay.GetPalette: PPalette;
  201. const
  202.   P: string[1] = #19;
  203. begin
  204.   GetPalette := @P;
  205. end;
  206.  
  207. procedure TCalcDisplay.HandleEvent(var Event: TEvent);
  208. begin
  209.   inherited HandleEvent(Event);
  210.   case Event.What of
  211.     evKeyDown:
  212.       begin
  213.         CalcKey(Event.CharCode);
  214.         ClearEvent(Event);
  215.       end;
  216.     evBroadcast:
  217.       if Event.Command = cmCalcButton then
  218.       begin
  219.         CalcKey(PButton(Event.InfoPtr)^.Title^[1]);
  220.         ClearEvent(Event);
  221.       end;
  222.   end;
  223. end;
  224.  
  225. procedure TCalcDisplay.Store(var S: TStream);
  226. begin
  227.   TView.Store(S);
  228.   S.Write(Status, SizeOf(Status) + SizeOf(Number) + SizeOf(Sign) +
  229.     SizeOf(Operator) + SizeOf(Operand));
  230. end;
  231.  
  232. { TCalculator }
  233.  
  234. constructor TCalculator.Init;
  235. const
  236.   KeyChar: array[0..19] of Char = 'C'#27'%'#241'789/456*123-0.=+';
  237. var
  238.   I: Integer;
  239.   P: PView;
  240.   R: TRect;
  241. begin
  242.   R.Assign(5, 3, 29, 18);
  243.   inherited Init(R, 'Calculator');
  244.   Options := Options or ofFirstClick;
  245.   for I := 0 to 19 do
  246.   begin
  247.     R.A.X := (I mod 4) * 5 + 2;
  248.     R.A.Y := (I div 4) * 2 + 4;
  249.     R.B.X := R.A.X + 5;
  250.     R.B.Y := R.A.Y + 2;
  251.     P := New(PButton, Init(R, KeyChar[I], cmCalcButton,
  252.       bfNormal + bfBroadcast));
  253.     P^.Options := P^.Options and not ofSelectable;
  254.     Insert(P);
  255.   end;
  256.   R.Assign(3, 2, 21, 3);
  257.   Insert(New(PCalcDisplay, Init(R)));
  258. end;
  259.  
  260. procedure RegisterCalc;
  261. begin
  262.   RegisterType(RCalcDisplay);
  263.   RegisterType(RCalculator);
  264. end;
  265.  
  266. end.
  267.