home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi 4 Bible
/
Delphi_4_Bible_Tom_Swan_IDG_Books_1998.iso
/
source
/
CALC32
/
CALC.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-04-13
|
14KB
|
479 lines
unit Calc;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Menus, StdCtrls, Mask, Buttons, ExtCtrls,
Clipbrd, About;
type
TCalcForm = class(TForm)
MemButton: TSpeedButton;
DecButton: TSpeedButton;
HexButton: TSpeedButton;
BinButton: TSpeedButton;
Button7: TSpeedButton;
Button8: TSpeedButton;
Button9: TSpeedButton;
Button4: TSpeedButton;
Button5: TSpeedButton;
Button6: TSpeedButton;
Button1: TSpeedButton;
Button2: TSpeedButton;
Button3: TSpeedButton;
Button0: TSpeedButton;
PlusMinusButton: TSpeedButton;
EqualButton: TSpeedButton;
ButtonA: TSpeedButton;
ButtonB: TSpeedButton;
ButtonC: TSpeedButton;
ButtonD: TSpeedButton;
ButtonE: TSpeedButton;
ButtonF: TSpeedButton;
DivButton: TSpeedButton;
TimesButton: TSpeedButton;
MinusButton: TSpeedButton;
PlusButton: TSpeedButton;
ANDButton: TSpeedButton;
ORButton: TSpeedButton;
XORButton: TSpeedButton;
NOTButton: TSpeedButton;
CalcMainMenu: TMainMenu;
CalcMenuItem: TMenuItem;
CalcExitMenuItem: TMenuItem;
MemBevel: TBevel;
MemLabel: TLabel;
DecBevel: TBevel;
DecLabel: TLabel;
HexBevel: TBevel;
HexLabel: TLabel;
BinBevel: TBevel;
BinLabel: TLabel;
LineBevel: TBevel;
ClearButton: TSpeedButton;
ClearEntryButton: TSpeedButton;
BackButton: TSpeedButton;
Help1: TMenuItem;
About1: TMenuItem;
Edit1: TMenuItem;
Paste1: TMenuItem;
Copy1: TMenuItem;
BitBtn1: TBitBtn;
procedure CalcExitMenuItemClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ButtonDigitClick(Sender: TObject);
procedure DecHexBinButtonClick(Sender: TObject);
procedure ClearEntryButtonClick(Sender: TObject);
procedure ClearButtonClick(Sender: TObject);
procedure BackButtonClick(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure OpButtonClick(Sender: TObject);
procedure EqualButtonClick(Sender: TObject);
procedure PlusMinusButtonClick(Sender: TObject);
procedure NOTButtonClick(Sender: TObject);
procedure Copy1Click(Sender: TObject);
procedure Paste1Click(Sender: TObject);
procedure About1Click(Sender: TObject);
private
{- Entry-radix switches. Only one can be true! }
DecEntry, HexEntry, BinEntry: Boolean;
{- Enable and disable buttons depending on Entry radix }
procedure EnableButtons;
{- Update Dec, Hex, and Bin Labels from Accumulator }
procedure UpdateDigitLabels;
{- Update Accumulator value from current entry string }
procedure UpdateAccumulator;
{- Assign value to memory (intermediate) accumulator }
procedure SetMemAcc(V: Longint);
{- Display error message }
procedure ShowError(const Msg: String);
public
{ Public declarations }
end;
var
CalcForm: TCalcForm;
implementation
{$R *.DFM}
const
{ -2147483648 }
maxDecDigits = 11; { Maximum number of decimal digits }
{ 7FFFFFFF }
maxHexDigits = 8; { Maximum number of hex digits }
{ 00000000000000000000000000000000 }
maxBinDigits = 32; { Maximum number of binary digits }
opNo = 0; { Operators = button Tag properties }
opMultiply = -1;
opDivide = -2;
opAdd = -3;
opSubtract = -4;
opAnd = -5;
opOr = -6;
opXor = -7;
asciiEsc = #27; { Ascii escape control code }
asciiEnter = #13; { Ascii enter control code }
var
Accumulator: Longint; { Current result }
MemAcc: Longint; { Memory result }
Operator: Integer; { opX constant }
DecString: String[maxDecDigits]; { Result in decimal }
HexString: String[maxHexDigits]; { Result in hex }
BinString: String[maxBinDigits]; { Result in binary }
{- Global procedures -- for Xtrastuff??? }
{ Convert integer Value to binary string limited to Digits }
function IntToBin(Value: Longint; Digits: Integer): String;
var
S: String;
begin
S := ''; { Initialize string to null }
while Digits > 0 do
begin
if Odd(Value) then S := '1' + S else S := '0' + S;
Value := Value shr 1;
Dec(Digits);
end;
Result := S; { Return S as function result }
end;
{ Convert string S in decimal to Longint value }
function StringToInt(const S: String): Longint;
begin
if Length(S) = 0 then
Result := 0
else try
Result := StrToInt(S);
except
on E: Exception do
begin
CalcForm.ShowError(E.Message);
Result := 0;
end;
end;
end;
{ Convert string S in hexadecimal to Longint value }
function StringToHex(const S: String): Longint;
var
ErrorCode: Integer;
V: Longint;
begin
Val('$' + S, V, ErrorCode); { Append Pascal's HEX char to S }
Result := V; { Return V as function result }
end;
{ Convert string S in binary to Longint value }
function StringToBin(const S: String): Longint;
var
V, Q: Longint; { Function result value and temporary }
I, J: Integer; { For-loop controls }
begin
V := 0; { Initialize result to 0 }
J := Length(S) - 1;
for I := 0 to J do { Shift in each digit in string }
if S[I + 1] = '1' then
begin
Q := 1; { Shift in a 1 }
V := V or (Q shl (J - I)); { Using a logical OR }
end;
Result := V; { Return V as function result }
end;
{- Private methods }
{ Enable and disable buttons depending on entry radix }
procedure TCalcForm.EnableButtons;
begin
{- Assume binary radix }
Button0.Enabled := True;
Button1.Enabled := True;
Button2.Enabled := False;
Button3.Enabled := False;
Button4.Enabled := False;
Button5.Enabled := False;
Button6.Enabled := False;
Button7.Enabled := False;
Button8.Enabled := False;
Button9.Enabled := False;
ButtonA.Enabled := False;
ButtonB.Enabled := False;
ButtonC.Enabled := False;
ButtonD.Enabled := False;
ButtonE.Enabled := False;
ButtonF.Enabled := False;
{- Add decimal buttons }
if (DecEntry or HexEntry) then
begin
Button2.Enabled := True;
Button3.Enabled := True;
Button4.Enabled := True;
Button5.Enabled := True;
Button6.Enabled := True;
Button7.Enabled := True;
Button8.Enabled := True;
Button9.Enabled := True;
end;
{- Add hex buttons }
if HexEntry then
begin
ButtonA.Enabled := True;
ButtonB.Enabled := True;
ButtonC.Enabled := True;
ButtonD.Enabled := True;
ButtonE.Enabled := True;
ButtonF.Enabled := True;
end;
{- Enable / disable radix selector button D, H, or B }
DecButton.Down := False;
HexButton.Down := False;
BinButton.Down := False;
if DecEntry then
DecButton.Down := True else
if HexEntry then HexButton.Down := True else
BinButton.Down := True;
end;
{ Update global strings and Label captions from Accumulator }
procedure TCalcForm.UpdateDigitLabels;
begin
{- Convert accumulator value to strings }
DecString := IntToStr(Accumulator);
HexString := IntToHex(Accumulator, maxHexDigits);
BinString := IntToBin(Accumulator, maxBinDigits);
{- Assign strings to Label object Captions }
DecLabel.Caption := DecString;
HexLabel.Caption := HexString;
BinLabel.Caption := BinString;
end;
{- Update Accumulator value from current entry string }
procedure TCalcForm.UpdateAccumulator;
begin
try
if DecEntry then
Accumulator := StringToInt(DecString)
else if HexEntry then
Accumulator := StringToHex(HexString)
else if BinEntry then
Accumulator := StringToBin(BinString);
except
on E: EIntError do
ShowError(E.Message);
end;
end;
{- Assign V to MemAcc and update Memory display line }
procedure TCalcForm.SetMemAcc(V: Longint);
begin
MemAcc := V;
MemLabel.Caption := IntToStr(MemAcc);
end;
{- Display error message string }
procedure TCalcForm.ShowError(const Msg: String