cxcalc.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,899 行 · 第 1/4 页
PAS
1,899 行
Color := clBtnFace;
ParentColor := False;
TabStop := True;
FAutoFontSize := True;
FBorderStyle := bsNone;
FBeepOnError := True;
FDownButton := cbNone;
FActiveButton := cbNone;
FPressedButton := cbNone;
FFocusRectVisible := True;
FOperator := cbEqual;
FPrecision := cxDefCalcPrecision;
Keys := [kAll, kArrows, kChars, kTab];
CreateLayout;
end;
function TcxCustomCalculator.GetButtonKindAt(X, Y : Integer) : TcxCalcButtonKind;
var i : TcxCalcButtonKind;
begin
Result := cbNone;
for i := cbBack to cbEqual do
if PtInRect(FButtons[i].BtnRect, Point(X, Y)) then
begin
Result := i;
Exit;
end;
end;
function TcxCustomCalculator.GetPainter: TcxCustomLookAndFeelPainterClass;
begin
Result := TcxStandardLookAndFeelPainter;
end;
procedure TcxCustomCalculator.Paint;
var
i : TcxCalcButtonKind;
State: TcxButtonState;
begin
if not HandleAllocated then Exit;
with Canvas do
begin
{Fill Background}
Brush.Color := Self.Color;
if IsPopupControl then
GetPainter.DrawWindowContent(Self.Canvas, ClientRect)
else
GetPainter.DrawWindowContent(Self.Canvas, BoundsRect);
{Draw buttons}
Font := Self.Font;
if AutoFontSize then
begin
Font.Size := FCalcFontSize;
if Font.Size >= cxCalcMinBoldFontSize then
Font.Style := [fsBold]
else
Font.Style := [];
end;
Brush.Color := Self.Color;
end;
for i := cbBack to cbEqual do
with FButtons[i] do
if RectVisible(Canvas.Handle, BtnRect) then
begin
if Grayed or not Enabled then State := cxbsDisabled
else if Down then State := cxbsPressed
else if (FActiveButton = i) and (FDownButton <> i) then State := cxbsHot
else if IsFocused and (i = cbEqual) then State := cxbsDefault
else State := cxbsNormal;
with GetPainter, Canvas do
begin
DrawButton(Self.Canvas, BtnRect, '', State);
Font.Color := FontColor;
Brush.Style := bsClear;
if State = cxbsPressed then
begin
OffsetRect(BtnRect, ButtonTextShift, ButtonTextShift);
DrawText(Text, BtnRect, cxAlignHCenter or cxAlignVCenter or cxSingleLine or
cxShowPrefix, State <> cxbsDisabled);
OffsetRect(BtnRect, -ButtonTextShift, -ButtonTextShift);
end
else
DrawText(Text, BtnRect, cxAlignHCenter or cxAlignVCenter or cxSingleLine or
cxShowPrefix, State <> cxbsDisabled);
Brush.Style := bsSolid;
end;
if FFocusRectVisible and IsFocused and (i = cbEqual) then
begin
InflateRect(BtnRect, -3, -3);
Canvas.DrawFocusRect(BtnRect);
InflateRect(BtnRect, 3, 3);
end;
end;
end;
procedure TcxCustomCalculator.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_TABSTOP or WS_CLIPCHILDREN;
WindowClass.Style := WindowClass.Style and not CS_DBLCLKS;
if IsPopupControl then
Style := Style and not WS_BORDER
else
if FBorderStyle = bsSingle then
if NewStyleControls and Ctl3D then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end
else
Style := Style or WS_BORDER;
end;
end;
procedure TcxCustomCalculator.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var ButtonKind : TcxCalcButtonkind;
begin
if not (csDesigning in ComponentState) and
(CanFocus or (GetParentForm(Self) = nil)) and not IsPopupControl then
SetFocus;
ButtonKind := GetButtonKindAt(X, Y);
if (Button = mbLeft) and (ButtonKind <> cbNone) and not FButtons[ButtonKind].Grayed then
begin
MouseCapture := True;
FTracking := True;
FDownButton := ButtonKind;
TrackButton(X, Y);
end;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TcxCustomCalculator.MouseMove(Shift: TShiftState; X, Y: Integer);
var OldButton : TcxCalcButtonKind;
begin
if FTracking then
TrackButton(X, Y)
else
if GetPainter.IsButtonHotTrack and Enabled and not Dragging then
begin
OldButton := FActiveButton;
FActiveButton := GetButtonKindAt(X, Y);
if FActiveButton <> OldButton then
begin
if not FButtons[OldButton].Grayed then
InvalidateButton(OldButton);
if not FButtons[FActiveButton].Grayed then
InvalidateButton(FActiveButton);
end;
end;
inherited MouseMove(Shift, X, Y);
end;
procedure TcxCustomCalculator.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
WasPressed: Boolean;
begin
WasPressed := (FDownButton <> cbNone) and FButtons[FDownButton].Down;
StopTracking;
if (Button = mbLeft) and WasPressed then
ButtonClick(FDownButton);
FDownButton := cbNone;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TcxCustomCalculator.KeyDown(var Key: Word; Shift: TShiftState);
var
NewButton, OldButton : TcxCalcButtonKind;
begin
inherited KeyDown(Key, Shift);
OldButton := FPressedButton;
NewButton := GetButtonKindKey(Key, Shift);
if (NewButton <> cbNone) and (OldButton <> NewButton) then
begin
DoButtonUp(OldButton);
FPressedButton := NewButton;
DoButtonDown(FPressedButton);
end;
end;
procedure TcxCustomCalculator.KeyPress(var Key: Char);
var
NewButton, OldButton : TcxCalcButtonKind;
begin
inherited KeyPress(Key);
if (Key = ^V) then
PasteFromClipboard
else
if (Key = ^C) then CopyToClipboard;
OldButton := FPressedButton;
NewButton := GetButtonKindChar(Key);
if (NewButton <> cbNone) and (OldButton <> NewButton) then
begin
DoButtonUp(OldButton);
FPressedButton := NewButton;
DoButtonDown(FPressedButton);
end;
if FPressedButton in RepeatButtons {cbBack} then ButtonClick(FPressedButton);
end;
procedure TcxCustomCalculator.KeyUp(var Key: Word; Shift: TShiftState);
begin
inherited KeyUp(Key, Shift);
DoButtonUp(FPressedButton);
end;
procedure TcxCustomCalculator.Resize;
begin
CalcSize(ClientWidth, ClientHeight);
ClientWidth := FCalcWidth;
ClientHeight := FCalcHeight;
inherited;
end;
procedure TcxCustomCalculator.DoButtonDown(ButtonKind : TcxCalcButtonKind);
begin
if ButtonKind <> cbNone then
begin
FButtons[ButtonKind].Down := True;
InvalidateButton(ButtonKind);
Update;
if not (ButtonKind in RepeatButtons) {cbBack} then ButtonClick(ButtonKind);
end;
end;
procedure TcxCustomCalculator.DoButtonUp(ButtonKind : TcxCalcButtonKind);
begin
if ButtonKind <> cbNone then
begin
FButtons[ButtonKind].Down := False;
InvalidateButton(ButtonKind);
FPressedButton := cbNone;
Update;
end;
end;
function TcxCustomCalculator.GetEditorValue: String;
begin
Result := '';
end;
procedure TcxCustomCalculator.SetEditorValue(const Value: String);
begin
end;
procedure TcxCustomCalculator.CreateLayout;
const
BtnColors : array [cbBack..cbEqual] of TColor = (clMaroon, clMaroon, clMaroon,
clRed, clRed, clRed, clRed,
clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue,
clBlue, clBlue,
clRed, clRed, clRed, clRed,
clNavy, clNavy, clNavy, clRed);
var i : TcxCalcButtonKind;
X : Integer;
begin
for i := cbBack to cbEqual do
begin
FButtons[i].Kind := i;
FButtons[i].Text := BtnCaptions[i];
if i = cbDecimal then FButtons[i].Text := SysUtils.DecimalSeparator
else FButtons[i].Text := BtnCaptions[i];
FButtons[i].FontColor := BtnColors[i];
FButtons[i].BtnRect := cxEmptyRect;
FButtons[i].Down := False;
FButtons[i].Grayed := False;
end;
{coord buttons}
FButtons[cbMC].BtnRect := Rect(FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*2);
FButtons[cbMR].BtnRect := Rect(FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*3);
FButtons[cbMS].BtnRect := Rect(FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*4);
FButtons[cbMP].BtnRect := Rect(FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*5);
X := FCalcXOfs+FCalcBtnWidth + FCalcXOfs + 4;
{7, 8, 9, /, sqrt}
FButtons[cbNum7].BtnRect := Rect(X+FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
X+FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*2);
FButtons[cbNum8].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*2);
FButtons[cbNum9].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*2);
FButtons[cbDiv].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*2);
FButtons[cbSqrt].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*5,
(FCalcYOfs+FCalcBtnHeight)*2);
{4, 5, 6, *, %}
FButtons[cbNum4].BtnRect := Rect(X+FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
X+FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*3);
FButtons[cbNum5].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*3);
FButtons[cbNum6].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*3);
FButtons[cbMul].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*3);
FButtons[cbPercent].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*5,
(FCalcYOfs+FCalcBtnHeight)*3);
{1, 2, 3, -, 1/x}
FButtons[cbNum1].BtnRect := Rect(X+FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
X+FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*4);
FButtons[cbNum2].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*4);
FButtons[cbNum3].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*4);
FButtons[cbSub].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*4);
FButtons[cbRev].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*5,
(FCalcYOfs+FCalcBtnHeight)*4);
{0, +/-, ., +, =}
FButtons[cbNum0].BtnRect := Rect(X+FCalcXOfs,
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
X+FCalcXOfs+FCalcBtnWidth,
(FCalcYOfs+FCalcBtnHeight)*5);
FButtons[cbSign].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*5);
FButtons[cbDecimal].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*5);
FButtons[cbAdd].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*5);
FButtons[cbEqual].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
(FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
X+(FCalcXOfs+FCalcBtnWidth)*5,
(FCalcYOfs+FCalcBtnHeight)*5);
{C}
FButtons[cbClear].BtnRect := FButtons[cbEqual].BtnRect;
FButtons[cbClear].BtnRect.Left := FButtons[cbClear].BtnRect.Right - FCalcLargeBtnWidth;
FButtons[cbClear].BtnRect.Top := FCalcYOfs;
FButtons[cbClear].BtnRect.Bottom := FCalcYOfs + FCalcBtnHeight;
{CE}
FButtons[cbCancel].BtnRect := FButtons[cbClear].BtnRect;
FButtons[cbCancel].BtnRect.Right := FButtons[cbClear].BtnRect.Left - FCalcYOfs;
FButtons[cbCancel].BtnRect.Left := FButtons[cbCancel].BtnRect.Right - FCalcLargeBtnWidth;
{Back}
FButtons[cbBack].BtnRect := FButtons[cbCancel].BtnRect;
FButtons[cbBack].BtnRect.Right := FButtons[cbBack].BtnRect.Left - FCalcYOfs;
FButtons[cbBack].BtnRect.Left := FButtons[cbBack].BtnRect.Right - FCalcLargeBtnWidth;
// ResetOperands;
ResetOperands;
// Update Memory display
UpdateMemoryButtons;
end;
procedure TcxCustomCalculator.ResetOperands;
begin
FOperator := cbEqual;
FStatus := csFirst;
FMemory := 0.0;
end;
procedure TcxCustomCalculator.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
RecreateWnd;
end;
end;
procedure TcxCustomCalculator.SetFocusRectVisible(Value : Boolean);
begin
if FFocusRectVisible <> Value then
begin
FFocusRectVisible := Value;
Invalidate;
end;
end;
procedure TcxCustomCalculator.CalcSize(AWidth, AHeight : Integer);
var
h, NearHeight, d, dMin : Integer;
function CalcHeight(ABtnHeight:Integer):Integer;
var FYOfs : Integer;
begin
FYOfs := MulDiv(ABtnHeight, cxMinCalcYOfs, cxMinCalcBtnHeight);
Result := (FYOfs + ABtnHeight) * 5 + FYOfs;
end;
begin
if AutoFontSize then
begin
h := MulDiv(AWidth, cxMinCalcHeight, cxMinCalcWidth);
if AHeight > h then AHeight := h;
{Calculate nearest FCalcHeight }
h := cxMinCalcBtnHeight;
NearHeight := h;
dMin := AHeight;
while True do
begin
d := abs(CalcHeight(h) - AHeight);
if d < dMin then
begin
dMin := d;
NearHeight := h;
end
else
Break;
inc(h);
end;
end
else
NearHeight := Canvas.FontHeight(Font) * 2;
FCalcBtnHeight := NearHeight;
FCalcBtnWidth := MulDiv(FCalcBtnHeight, cxMinCalcBtnWidth, cxMinCalcBtnHeight);
FCalcYOfs := MulDiv(FCalcBtnHeight, cxMinCalcYOfs, cxMinCalcBtnHeight);
FCalcXOfs := FCalcYOfs;
FCalcLargeBtnWidth := MulDiv(FCalcBtnWidth, 17, 10);
FCalcFontSize := MulDiv(FCalcBtnHeight, cxMinCalcFontSize, cxMinCalcBtnHeight);
FCalcHeight := (FCalcYOfs+FCalcBtnHeight)*5+FCalcYOfs;
FCalcWidth := (FCalcXOfs+FCalcBtnWidth)*6+FCalcXOfs*2+4;
// reCalc rect buttons
CreateLayout;
end;
procedure TcxCustomCalculator.FontChanged;
begin
if not (csLoading in ComponentState) then ParentFont := False;
inherited FontChanged;
end;
procedure TcxCustomCalculator.FocusChanged;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?