📄 scurredit.pas
字号:
unit sCurrEdit;
{$I sDefs.inc}
interface
uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Menus, Forms,
StdCtrls, Mask, Buttons, sCustomComboEdit, acntUtils, sCalcUnit, sConst;
type
{ TsCustomNumEdit }
{$IFNDEF NOTFORHELP}
TsCustomNumEdit = class(TsCustomComboEdit)
private
FCanvas: TControlCanvas;
FAlignment: TAlignment;
FFocused: Boolean;
FValue: Extended;
FMinValue, FMaxValue: Extended;
FDecimalPlaces: Cardinal;
FBeepOnError: Boolean;
FCheckOnExit: Boolean;
FFormatOnEditing: Boolean;
FFormatting: Boolean;
FDisplayFormat: PString;
procedure SetFocused(Value: Boolean);
procedure SetAlignment(Value: TAlignment);
procedure SetBeepOnError(Value: Boolean);
procedure SetDisplayFormat(const Value: string);
function GetDisplayFormat: string;
procedure SetDecimalPlaces(Value: Cardinal);
function GetValue: Extended;
procedure SetValue(AValue: Extended);
function GetAsInteger: Longint;
procedure SetMaxValue(AValue: Extended);
procedure SetMinValue(AValue: Extended);
function GetText: string;
procedure SetText(const AValue: string);
function TextToValText(const AValue: string): string;
function CheckValue(NewValue: Extended; RaiseOnError: Boolean): Extended;
function IsFormatStored: Boolean;
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
procedure WMPaste(var Message: TMessage); message WM_PASTE;
// procedure WMPaint (var Message: TWMPaint); message WM_PAINT; // v407
procedure CalcWindowClose(Sender: TObject; var Action: TCloseAction); //KJS
protected
procedure Change; override;
procedure ReformatEditText; dynamic;
procedure DataChanged; virtual;
function DefFormat: string; virtual;
procedure KeyPress(var Key: Char); override;
function IsValidChar(Key: Char): Boolean; virtual;
function FormatDisplayText(Value: Extended): string;
function GetDisplayText: string; virtual;
procedure Reset; override;
procedure CheckRange;
procedure UpdateData;
property Formatting: Boolean read FFormatting;
property Alignment: TAlignment read FAlignment write SetAlignment default taRightJustify;
property BeepOnError: Boolean read FBeepOnError write SetBeepOnError default True;
property CheckOnExit: Boolean read FCheckOnExit write FCheckOnExit default False;
property DecimalPlaces: Cardinal read FDecimalPlaces write SetDecimalPlaces default 2;
property DisplayFormat: string read GetDisplayFormat write SetDisplayFormat stored IsFormatStored;
property MaxValue: Extended read FMaxValue write SetMaxValue;
property MinValue: Extended read FMinValue write SetMinValue;
property Text: string read GetText write SetText stored False;
property MaxLength default 0;
procedure PopupWindowShow; override;
property ClickKey;
procedure PaintText; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Clear; override;
property AsInteger: Longint read GetAsInteger;
property DisplayText: string read GetDisplayText;
property DroppedDown;
property Value: Extended read GetValue write SetValue;
end;
{$ENDIF} // NOTFORHELP
{ TsCalcEdit }
TsCalcEdit = class(TsCustomNumEdit)
public
property AsInteger;
{$IFNDEF NOTFORHELP}
constructor Create(AOwner: TComponent); override;
published
property ClickKey;
property AutoSelect;
property BeepOnError;
property DirectInput;
property DragCursor;
property Enabled;
property Font;
property HideSelection;
property ImeMode;
property ImeName;
property MaxLength;
property ParentFont;
property ParentShowHint;
property PopupAlign;
property PopupMenu;
property ReadOnly;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnButtonClick;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
{$ENDIF} // NOTFORHELP
property Alignment;
property CheckOnExit;
property DecimalPlaces;
property DisplayFormat;
property MaxValue;
property MinValue;
property Text;
property Value;
end;
implementation
uses Consts, sVclUtils, sStyleSimply, sMessages, sMaskData, sGraphUtils, sCommonData;
{ TsCustomNumEdit }
constructor TsCustomNumEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// ControlStyle := ControlStyle - [csSetCaption];
FAlignment := taRightJustify;
FDisplayFormat := NewStr(DefFormat);
MaxLength := 0;
FDecimalPlaces := 2;
FBeepOnError := True;
inherited Text := '';
inherited Alignment := taLeftJustify;
DataChanged;
PopupWidth := 213;
end;
destructor TsCustomNumEdit.Destroy;
begin
FPopupWindow := nil;
if Assigned(FCanvas) then FreeAndNil(FCanvas);
DisposeStr(FDisplayFormat);
inherited Destroy;
end;
function TsCustomNumEdit.DefFormat: string;
begin
Result := '### ### ##0.00;-### ### ##0.00;0';
end;
function TsCustomNumEdit.IsFormatStored: Boolean;
begin
Result := (DisplayFormat <> DefFormat);
end;
function TsCustomNumEdit.IsValidChar(Key: Char): Boolean;
var
S: string;
SelStart, SelStop, DecPos: Integer;
RetValue: Extended;
begin
Result := False;
S := EditText;
GetSel(SelStart, SelStop);
System.Delete(S, SelStart + 1, SelStop - SelStart);
System.Insert(Key, S, SelStart + 1);
S := TextToValText(S);
DecPos := Pos(DecimalSeparator, S);
if (DecPos > 0) then begin
SelStart := Pos('E', UpperCase(S));
if (SelStart > DecPos) then DecPos := SelStart - DecPos else DecPos := Length(S) - DecPos;
if DecPos > Integer(FDecimalPlaces) then Exit;
end;
Result := IsValidFloat(S, RetValue);
if Result and (FMinValue >= 0) and (FMaxValue > 0) and (RetValue < 0) then Result := False;
end;
procedure TsCustomNumEdit.KeyPress(var Key: Char);
begin
if Key in ['.', ','] - [ThousandSeparator] then Key := DecimalSeparator;
inherited KeyPress(Key);
if (Key in [#32..#255]) and not IsValidChar(Key) then begin
if BeepOnError then MessageBeep(0);
Key := #0;
end
else if Key = #27 then begin
Reset;
Key := #0;
end;
end;
procedure TsCustomNumEdit.Reset;
begin
DataChanged;
SelectAll;
end;
procedure TsCustomNumEdit.SetBeepOnError(Value: Boolean);
begin
if FBeepOnError <> Value then begin
FBeepOnError := Value;
end;
end;
procedure TsCustomNumEdit.SetAlignment(Value: TAlignment);
begin
if FAlignment <> Value then begin
FAlignment := Value;
SkinData.Invalidate;
end;
end;
procedure TsCustomNumEdit.SetDisplayFormat(const Value: string);
begin
if DisplayFormat <> Value then begin
AssignStr(FDisplayFormat, Value);
SkinData.Invalidate;
DataChanged;
end;
end;
function TsCustomNumEdit.GetDisplayFormat: string;
begin
Result := FDisplayFormat^;
end;
procedure TsCustomNumEdit.SetFocused(Value: Boolean);
begin
if FFocused <> Value then begin
FFocused := Value;
if not Focused or not AutoSelect then
SkinData.Invalidate; //v4.50
FFormatting := True;
try
DataChanged;
finally
FFormatting := False;
end;
end;
end;
procedure TsCustomNumEdit.SetDecimalPlaces(Value: Cardinal);
begin
if FDecimalPlaces <> Value then begin
FDecimalPlaces := Value;
DataChanged;
SkinData.Invalidate;
end;
end;
function TsCustomNumEdit.FormatDisplayText(Value: Extended): string;
begin
if DisplayFormat <> '' then begin
Result := FormatFloat(DisplayFormat, Value)
end
else begin
Result := FloatToStr(Value);
end;
end;
function TsCustomNumEdit.GetDisplayText: string;
begin
if not Focused then Result := FormatDisplayText(StrToFloat(TextToValText({Edit}Text))) else Result := EditText; // v4.52
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -