unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, GIFImg, ExtCtrls, jpeg;
type
TfMain = class(TForm)
imgBack: TImage;
lcdMem, lcdTotal, lcdOp, lcd, bMp, bMr, bMc, bOff, bSqr, bSqrt, bSign,
bAC, bDiv, bMulti, bMinus, bPlus, bTotal, bDot, b0, b1, b2, b3, b4,
b5, b6, b7, b8, b9, lblSimpleCalc, lblSimpleCalcShadow: TLabel;
procedure KeyClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure AC;
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest;
public
{ Public declarations }
end;
var
fMain: TfMain;
mem:extended=0;
implementation
{$R *.dfm}
procedure TfMain.WMNCHitTest(var Msg: TWMNCHitTest) ;
// Permite arrastar a janela sem que ela tenha uma camption board
// Faz isso caso o rato esteja nos primeiros 200 pixeis de altura ou nos últimos
// 30, indicando ao windows que o rato ainda está na barra de Caption
var
P: TPoint; // Variável que irá recolher a localização do rato
begin
inherited;
if Msg.Result = htClient then begin
GetCursorPos(P); // Guarda em P a localização do rato
// Testa a localização do rato e aje em conformidade
if (P.Y<fmain.Top+200) or (P.Y>fmain.Top+fMain.Height-30) then Msg.Result := htCaption;
end;
end;
procedure TfMain.AC;
// Limpa todos os dados inseridos, excepto a memória
begin
lcd.Caption:='0';
lcdOp.Caption:='';
lcdTotal.Caption:='';
end;
procedure TfMain.FormCreate(Sender: TObject);
begin
AC; // Limpa o "LCD" para começar
end;
procedure TfMain.FormKeyPress(Sender: TObject; var Key: Char);
// Testa as teclas pressionadas na form fMain. Caso seja uma das teclas conhecidas, chama o botão correspondente
begin
case key of
#27:if (lcd.Caption='0') and (lcdOp.Caption='') and (lcdTotal.Caption='') then application.Terminate // Se o ecrã estiver limpo, a tecla ESC chama o botão OFF
else KeyClick(bAc); // Se existirem dados, limpa-os
#13:KeyClick(bTotal); // A tecla ENTER chama o botão =
'+':KeyClick(bPlus); // Chama o botão +
'-':KeyClick(bMinus); // Chama o botão -
'*','x','X':KeyClick(bMulti); // Chama o botão x
'/':KeyClick(bDiv); // Chama o botão ÷
'.':KeyClick(bDot); // Chama o botão .
' ':KeyClick(bSign); // Chama o botão ±
'R','r':KeyClick(bSqrt); // Chama o botão √
'Q','q':KeyClick(bSqr); // Chama o botão x²
'A','a':KeyClick(bMp); // Chama o Botão M+
'V','v':KeyClick(bMr); // Chama o botão Mr
'C','c':KeyClick(bMc); // Chama o botão Mc
else if CharInSet(Key,['0'..'9']) then KeyClick(FindComponent('b'+Key));
end;
end;
procedure TfMain.KeyClick(Sender: TObject);
// Executa uma acção, concoante a tecla carregada
var
Disp:string; // Guarda temporariamente o valor do LCD
Sign:Boolean; // Guarda temporariamente o valor do sinal do valor em LCD
begin
Disp:=lcd.Caption; // Guarda em Disp o valor do LCD
if Sender=bOff then application.Terminate; // Se a tecla for a OFF, termina o programa
if Sender=bAC then if Disp<>'0' then Disp:='0' // Se a tecla for AC e houver um valor no LCD, limpa-o
else AC; // Se a tecla for AC e o valor em LCD for 0, limpa todos os dados
if Sender=bSign then if Disp[1]='-' then Delete(Disp,1,1) // Se a tecla for ±, remove o sinal negativo caso exista...
else Disp:='-'+Disp; // ... ou insere-o caso não exista
if Sender=bSqrt then Disp:=FloatToStrF(Sqrt(StrToFloat(Disp)),ffGeneral,9,2); // Se a tecla for √, troca o valor de LCD pelo da sua raíz quadrada
if Sender=bSqr then Disp:=FloatToStrF(Sqr(StrToFloat(Disp)),ffGeneral,9,2); // Se a tecla for x², troca o valor de LCD pelo do seu quadrado
if Sender=bMp then Mem:=Mem+StrToFloat(lcdTotal.Caption); // Se a tecla for M+, adiciona o valor de LCD Total ao existente na memória
if Sender=bMr then Disp:=FloatToStrF(Mem,ffGeneral,9,2); // Se a tecla for Mr, atribui ao LCD o valor presentemente em memória
if Sender=bMc then Mem:=0; // Se a tecla for Mc, limpa a memória
lcdMem.Visible:=Mem<>0; // Liga ou desliga o ícone M caso o valor da memória seja diferente de 0
if (CharInSet((Sender as TLabel).Caption[1],['+','-','x','÷','='])) and ((Sender as TLabel).Caption<>'x²') // Se a tecla for uma operação ou o sinal = ...
then begin
if lcdTotal.Caption<>'' then case lcdOp.Caption[1] of // Testa a última operação antes desta, e efectua-a
'+':lcdTotal.Caption:=FloatToStrF(StrToFloat(lcdTotal.Caption)+StrToFloat(Disp),ffGeneral,7,2); // Efectua a operação Soma
'-':lcdTotal.Caption:=FloatToStrF(StrToFloat(lcdTotal.Caption)-StrToFloat(Disp),ffGeneral,7,2); // Efectua a operação Subtracção
'x':lcdTotal.Caption:=FloatToStrF(StrToFloat(lcdTotal.Caption)*StrToFloat(Disp),ffGeneral,7,2); // Efectua a operação Multiplicação
'÷':if lcd.Caption<>'0' then lcdTotal.Caption:=FloatToStrF(StrToFloat(lcdTotal.Caption)/StrToFloat(Disp),ffGeneral,7,2); // Efectua a operação Divisão
'=':if disp<>'0' then lcdTotal.Caption:=Disp; // Se a última operação foi = (mostrar resultado), e caso não haja um valor novo no LCD, assume o total da última operação como parcela
end
else lcdTotal.Caption:=Disp; // Se lcdTotal for '' então este é o primeiro valor da operação
lcdOp.Caption:=(Sender as TLabel).Caption[1]; // Mostra qual a operação a executar
Disp:='0'; // Limpa o LCD de entrada
end;
if (Sender as TLabel).Caption[1]='.' then Disp:=Disp+DecimalSeparator; // Se a tecla for um ponto decimal
if CharInSet((Sender as TLabel).Caption[1],['0'..'9']) then begin // Se a tecla for um algarismo
Sign:=Disp[1]='-'; // Memoriza se é um valor negativo
if Sign then Delete(Disp,1,1); // Apaga o sinal caso haja (valor negativo)
if Disp='0' then Disp:=(Sender as TLabel).Caption[1] // Se o LCD tiver o valor 0, subsitui pelo valor da tecla pressionada
else Disp:=Disp+(Sender as TLabel).Caption[1]; // Adiciona ao LCD o valor da tecla
if Sign then Disp:='-'+Disp; // Repõe o sinal negativo ao valor, caso fosse esse o sinal inicial
end;
lcd.Caption:=Disp; // Mostra no LCD o valor encontrado pela operação efectuada
end;
end.