📄 wwcalculator.pas
字号:
FCurrentValue := 0;
FLastValue := 0;
Caption := '';
FMargin := 3;
FOptions := [];
// BorderStyle := bsRaisedPanel;
FPanelColor := clBtnFace;
FPaintBitmap:= TBitmap.create;
FBackgroundBitmap:= TPicture.create;
F3D := False;
end;
destructor TwwCalculator.Destroy;
begin
inherited Destroy;
FPaintBitmap.Free;
FBackGroundBitmap.Free;
end;
procedure TwwCalculator.Loaded;
var i:integer;
begin
inherited;
CalcButtons;
if BackGroundBitmap.Graphic.empty then begin
for i:= 0 to ControlCount-1 do begin
if COntrols[i] is TwwCalcButton then
TwwCalcButton(controls[i]).FTransparent := False;
end;
end
else begin
for i:= 0 to ControlCount-1 do begin
if COntrols[i] is TwwCalcButton then
TwwCalcButton(controls[i]).FTransparent := True;
end;
InitBitmapsFlag := True;
end;
end;
function TwwCalculator.CharToOp(c:Char;Ctrl:Boolean):TwwCalcButtonType;
begin
Result := btNone;
case c of
'0':Result :=bt0;
'1':Result :=bt1;
'2':Result :=bt2;
'3':Result :=bt3;
'4':Result :=bt4;
'5':Result :=bt5;
'6':Result :=bt6;
'7':Result :=bt7;
'8':Result :=bt8;
'9':Result :=bt9;
',','.':Result:=btDecimal;
'_':Result := btPlusMinus;
'*':Result := btMultiply;
'/':Result := btDivide;
'+':Result := btAdd;
'-':Result := btSubtract;
'=':Result := btEquals;
'@':Result := btSqrt;
'%':Result := btPercent;
'r','R': if not Ctrl then Result := btInverse
else Result := btMRecall;
'c','C': if not Ctrl then Result := btClear
else Result := btMClear;
'e','E': Result := btClearAll;
'm','M': if Ctrl then Result := btMStore;
'p','P': if Ctrl then Result := btMAdd;
'b','B': Result := btBackSpace;
end;
end;
procedure TwwCalculator.ResultKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var c:Char;
code:Integer;
KeyState: TKeyboardState;
s:String;
begin
if Key=16 then begin
inherited;
exit;
end;
if Key=vk_Return then c:='='
else if Key=vk_Delete then c:='c'
else if Key=vk_Back then c:='b'
else if Key=vk_Escape then c:='e'
else begin
Code := MapVirtualKey(Key, 2);
c:=char(code);
if (ssShift in Shift) then begin
case c of
'=':c:='+';
'5':c:='%';
'8':c:='*';
end;
end;
end;
DoCalc(CharToOp(c,(ssCtrl in Shift)));
inherited;
FResultEdit.SelStart := Length(FResultEdit.Text);
end;
function TwwCalculator.OpToChar(aOp:TwwCalcButtonType):Char;
begin
Result := ' ';
case aOP of
btNone : Result := ' ';
bt0 : Result := '0';
bt1 : Result := '1';
bt2 : Result := '2';
bt3 : Result := '3';
bt4 : Result := '4';
bt5 : Result := '5';
bt6 : Result := '6';
bt7 : Result := '7';
bt8 : Result := '8';
bt9 : Result := '9';
btDecimal : Result := DecimalSeparator;
btPlusMinus : Result := '_';
btMultiply: Result := '*';
btDivide: Result := '/';
btAdd: Result := '+';
btSubtract: Result := '-';
btEquals:Result :='=';
btSqrt:Result := '@';
btPercent:Result :='%';
btInverse:Result := 'i';
btBackspace:Result := 'b';
btClear :Result := 'd';
btClearAll: Result := 'e';
btMRecall: Result := 'r';
btMStore: Result := 'm';
btMClear: Result := 'c';
btMAdd: Result := 'a';
end;
end;
procedure TwwCalculator.WMSize(var Message: TWMSize);
var NewBoundsRect: TRect;
function sameRect(rect1, rect2: TRect): boolean;
begin
result:=
(rect1.left = rect2.left) and
(rect1.right = rect2.right) and
(rect1.top = rect2.top) and
(rect1.bottom = rect2.bottom);
end;
begin
inherited;
NewboundsRect:= Rect(0, 0, BoundsRect.right-BoundsRect.left, BoundsRect.bottom-BoundsRect.top);
if SameRect(OldBoundsRect, NewBoundsRect) then exit;
OldboundsRect:= NewBoundsRect;
InitBitmapsFlag:= True;
if csLoading in COmponentState then exit;
CalcButtons;
end;
procedure TwwCalculator.Paint;
const
Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
var NewboundsRect: TRect;
ARect: TRect;
TopColor, BottomColor: TColor;
i,j:integer;
BtnShadow,BtnLight:TColor;
procedure AdjustColors(Bevel: TPanelBevel);
begin
TopColor := clBtnHighlight;
if Bevel = bvLowered then TopColor := clBtnShadow;
BottomColor := clBtnShadow;
if Bevel = bvLowered then BottomColor := clBtnHighlight;
end;
begin
if InitBitmapsFlag and ((not BackGroundBitmap.Bitmap.Empty) or (not BackGroundBitmap.Graphic.Empty)) then begin
NewboundsRect:= Rect(0, 0, BoundsRect.right-BoundsRect.left, BoundsRect.bottom-BoundsRect.top);
PaintBitmap.Width := NewBoundsRect.right;
PaintBitmap.Height:= NewBoundsRect.Bottom;
PaintBitmap.TransparentMode := tmFixed;
PaintBitmap.TransparentColor := clNone;
case BackgroundBitmapDrawStyle of
cbdTile:
begin
with BackgroundBitmap do begin
i := 0;
while i < Self.Width do begin
j := 0;
while j < Self.Height do begin
PaintBitmap.Canvas.Draw(i,j,Graphic);
// r:=rect(i,j,i+Bitmap.width,j+Bitmap.height);
// PaintBitmap.canvas.CopyRect(r,backgroundbitmap.bitmap.canvas,r);
inc(j, Bitmap.Height);
end;
inc(i, Bitmap.Width);
end;
end
end;
cbdTopLeft:
begin
with BackgroundBitmap do
PaintBitmap.Canvas.Draw(0, 0, Graphic);
end;
cbdCenter:
begin
with BackgroundBitmap do
PaintBitmap.Canvas.Draw((self.width-Width)div 2,
(self.Height-Height) div 2, Graphic);
end;
cbdStretch:
begin
with BackgroundBitmap do
PaintBitmap.Canvas.StretchDraw(Rect(0, 0, newBoundsRect.right, NewBoundsRect.bottom), Graphic);
end;
end;
InitBitmapsFlag:= False;
end;
ARect := GetClientRect;
if ((not BackGroundBitmap.Bitmap.Empty) or (not BackGroundBitmap.Graphic.Empty)) then
Canvas.CopyRect(ARect,PaintBitmap.Canvas,Rect(0,0,Width,Height))
else
begin
with Canvas do
begin
Brush.Color := PanelColor;
FillRect(ARect);
end;
end;
if cboHideBorder in Options then exit;
if Border3D then begin
BtnShadow:= changeColor(Color,False);
BtnLight := changeColor(Color,True);
Frame3D(Canvas, ARect, BtnLight, clBlack, 1);
Frame3D(Canvas, ARect, clWhite, BtnShadow, 1);
end
else begin
Frame3D(Canvas, ARect, clWhite, clBlack, 1);
end;
end;
procedure TwwCalculator.CalcButtons;
var
j: integer;
i,bt:TwwCalcButtonType;
calccolor:TCOlor;
BtnWidth,BtnHeight :integer;
clrbtnw,clrbtnh:integer;
numbuttonsx,numbuttonsy:integer;
row,col:integer;
x,y:integer;
startoffset:integer;
pad:integer;
flag:boolean;
begin
numbuttonsx:=6;
numbuttonsy:=5;
if not (cboHideEditor in Options) then inc(numbuttonsy);
if (cboShowStatus in Options) then inc(numbuttonsy);
x:= Width-ButtonMargin*(numbuttonsx-1)-(5+5+5);
y:= Height-ButtonMargin*(numbuttonsy-1)-10;
btnwidth := x div numbuttonsx;
btnHeight := y div numbuttonsy;
if cboHideEditor in Options then row := 1
else row := 2;
Btns[btMClear] := ButtonRecord(btMClear,5+row*(btnheight+ButtonMargin), 5, BtnWidth, btnHeight, 'MC',clRed,'Clears any number stored in memory.'+#13#10+#13#10+'Keyboard equivalent = CTRL + L');
inc(row);
Btns[btMRecall] := ButtonRecord(btMRecall,5+row*(btnheight+ButtonMargin), 5, btnwidth, btnHeight, 'MR',clRed,'Recalls the number stored in memory.');
inc(row);
Btns[btMStore] := ButtonRecord(btMStore,5+row*(btnheight+ButtonMargin), 5, btnwidth, btnHeight, 'MS',clRed,'Stores the displayed number in memory.');
inc(row);
Btns[btMAdd] := ButtonRecord(btMAdd,5+row*(btnheight+ButtonMargin), 5, btnwidth, btnHeight, 'M+',clRed,'Adds displayed number to number in memory.');
clrbtnw := (width - 15-btnwidth-ButtonMargin*3) div 3;
if cboHideEditor in Options then clrbtnh:=5
else clrbtnh:=5+btnheight+ButtonMargin;
Btns[btBackspace] := ButtonRecord(btBackSpace,clrbtnh,Width-5-clrbtnw-2*(clrbtnw+ButtonMargin), clrbtnw, btnHeight, 'Back',clRed,'Deletes last digit of displayed number.');
Btns[btClear] := ButtonRecord(btClear,clrbtnh, Width-5-(clrbtnw+ButtonMargin)-clrbtnw, clrbtnw, btnHeight, 'CE', clRed,'Clears displayed number.');
Btns[btClearAll] := ButtonRecord(btClearAll,clrbtnh, Width-5-clrbtnw, clrbtnw, btnHeight, 'C', clRed,'Clears the current calculation.');
pad := ((Width-5-BtnWidth)-4*(BtnWidth+ButtonMargin)) - (Width-5-clrbtnw-2*(clrbtnw+ButtonMargin));
if pad <= 0 then pad := 0;
if cboHideEditor in Options then row := 1
else row := 2;
Btns[bt7] := ButtonRecord(bt7,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-4*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '7',clBlue,'Puts this number in display.');
inc(row);
Btns[bt4] := ButtonRecord(bt4,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-4*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '4',clBlue,'Puts this number in display.');
inc(row);
Btns[bt1] := ButtonRecord(bt1,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-4*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '1',clBlue,'Puts this number in display.');
inc(row);
Btns[bt0] := ButtonRecord(bt0,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-4*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '0',clBlue,'Puts this number in display.');
if cboHideEditor in Options then row := 1
else row := 2;
Btns[bt8] := ButtonRecord(bt8,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-3*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '8',clBlue,'Puts this number in display.');
inc(row);
Btns[bt5] := ButtonRecord(bt5,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-3*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '5',clBlue,'Puts this number in display.');
inc(row);
Btns[bt2] := ButtonRecord(bt2,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-3*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '2',clBlue,'Puts this number in display.');
inc(row);
Btns[btPlusMinus] := ButtonRecord(btPlusMinus,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-3*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '+/-',clBlue,'Changes sign of displayed number.');
if cboHideEditor in Options then row := 1
else row := 2;
Btns[bt9] := ButtonRecord(bt9,5+row*(btnheight+ButtonMargin),-pad+(Width-5-BtnWidth)-2*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '9',clBlue,'Puts this number in display.');
inc(row);
Btns[bt6] := ButtonRecord(bt6,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-2*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '6',clBlue,'Puts this number in display.');
inc(row);
Btns[bt3] := ButtonRecord(bt3,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-2*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '3',clBlue,'Puts this number in display.');
inc(row);
Btns[btDecimal] := ButtonRecord(btDecimal,5+row*(btnheight+ButtonMargin),-pad+ (Width-5-BtnWidth)-2*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '.',clBlue,'Inserts a decimal point.');
if cboHideEditor in Options then row := 1
else row := 2;
Btns[btDivide] := ButtonRecord(btDivide,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-1*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '/',clRed,'Divides.');
inc(row);
Btns[btMultiply] := ButtonRecord(btMultiply,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-1*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '*',clRed,'Multiplies.');
inc(row);
Btns[btSubtract] := ButtonRecord(btSubtract,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-1*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '-',clRed,'Subtracts.');
inc(row);
Btns[btAdd] := ButtonRecord(btAdd,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-1*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '+',clRed,'Adds.');
if cboHideEditor in Options then row := 1
else row := 2;
Btns[btsqrt] := ButtonRecord(btsqrt,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-0*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, 'sqrt',clBlue,'Calculates squareroot of number.');
inc(row);
Btns[btPercent] := ButtonRecord(btPercent,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-0*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '%',clBlue,'Displays result of multiplication as percentage.');
inc(row);
Btns[btInverse] := ButtonRecord(btInverse,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-0*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '1/x',clBlue,'Calculates the reciprocal.');
inc(row);
Btns[btEquals] := ButtonRecord(btEquals,5+row*(btnheight+ButtonMargin), (Width-5-BtnWidth)-0*(BtnWidth+ButtonMargin), BtnWidth, btnHeight, '=',clRed,'Performs any operation on previous numbers.');
flag := False;
for j:= 0 to ControlCount-1 do
if COntrols[j] is TwwCalcButton then flag := True;
if flag then begin
for j:= 0 to ControlCount-1 do
if COntrols[j] is TwwCalcButton then
with TwwCalcButton(Controls[j]) do begin
SetBounds(Btns[fbtntype].Left, Btns[fbtntype].Top, Btns[fbtntype].Width,Btns[fbtntype].Height);
ButtonFontColor := Btns[fbtntype].Color;
ButtonColor := PanelColor;
Hint := Btns[fbtnType].Hint;
FOptions := Options;
Font.Height := self.Font.Height;
Font.Name := self.Font.Name;
Font.Style := self.Font.Style;
if (FBackGroundBitmap <> nil) and (FBackGroundBitmap.Graphic <> nil) and not FBackgroundbitmap.Graphic.empty then
FTransparent := True
else FTransparent := False;
end;
end
else begin
for i := Low(TwwCalcButtonType) to High(TwwCalcButtonType) do
with TwwCalcButton.Create(Self) do begin
Parent := Self;
SetBounds(Btns[i].Left, Btns[i].Top, Btns[i].Width,Btns[i].Height);
fBtnType:=Btns[i].BtnType;
Hint := Btns[i].Hint;
Caption := Btns[i].Caption;
ButtonFontColor := Btns[i].Color;
ButtonColor := PanelColor;
OnClick := Compute;
FOptions := Options;
Font.Height := self.Font.Height;
Font.Name := self.Font.Name;
Font.Style := self.Font.Style;
if (FBackGroundBitmap <> nil) and (FBackGroundBitmap.Graphic <> nil) and not FBackgroundbitmap.Graphic.empty then
FTransparent := True
else FTransparent := False;
Tag := Ord(i);
end;
end;
if FMemoryBevel = nil then begin
FMemoryBevel := TwwCalcBevel.Create(Self);
FMemoryBevel.Parent := Self;
end;
with FMemoryBevel do begin
Parent := Self;
SetBounds(5,clrBtnh+1,BtnWidth,BtnHeight-1);
FColor := PanelColor;
end;
if FMemoryStatus = nil then begin
FMemoryStatus := TwwCalcLabel.Create(Self);
with FMemoryStatus do begin
Parent := Self;
Autosize := False;
Transparent := True;
Alignment := taCenter;
end;
end;
j := clrbtnh;
with FMemoryStatus do begin
Font.Height := self.Font.Height;
Font.Name := self.Font.Name;
Font.Style := self.Font.Style;
SetBounds(5,j+((BtnHeight-FMemoryStatus.Canvas.textheight('M'))div 2),BtnWidth,BtnHeight);
end;
if FResultEdit = nil then begin
FResultEdit := TwwDBEdit.Create(Self);
with FResultEdit do begin
Parent := Self;
Visible := not (cboHideEditor in Options);
AutoSize := False;
EditAlignment := eaRightAlignEditing;
TLabel(FResultEdit).Alignment := taRightJustify;
Font.Height := -13;
Font.Name := 'Arial';
Font.Style := [];
Text := '0';
ReadOnly := True;
OnKeyDown := ResultKeyDown;
end;
end;
if (cboHideEditor in Options) then FResultEdit.Visible := False
else if (csDesigning in ComponentState) then FResultEdit.Visible := True;
if not FResultEdit.Visible and (csDesigning in ComponentState) then
FResultEdit.SetBounds(5, 5, 0, 0)
else FResultEdit.SetBounds(5, 5, Width-10, btnHeight);
if (cboShowStatus in Options) then begin
if (FStatusBevel = nil) then begin
FStatusBevel := TwwCalcBevel.Create(Self);
FStatusBevel.Parent := Self;
end;
if (FStatusLabel = nil) then begin
FStatusLabel := TLabel.Create(Self);
with FStatusLabel do begin
Parent := Self;
Autosize := False;
Transparent := True;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -