cxcalc.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,899 行 · 第 1/4 页
PAS
1,899 行
end;
procedure TcxCustomCalcEditProperties.SetPrecision(Value: Byte);
begin
if AssignedValues.Precision and (Value = FPrecision) then
Exit;
AssignedValues.FPrecision := True;
FPrecision := Value;
Changed;
end;
procedure TcxCustomCalcEditProperties.SetQuickClose(Value: Boolean);
begin
if Value <> FQuickClose then
begin
FQuickClose := Value;
Changed;
end;
end;
procedure TcxCustomCalcEditProperties.SetScientificFormat(Value: Boolean);
begin
if Value <> FScientificFormat then
begin
FScientificFormat := Value;
Changed;
end;
end;
procedure TcxCustomCalcEditProperties.SetUseThousandSeparator(Value: Boolean);
begin
if Value <> FUseThousandSeparator then
begin
FUseThousandSeparator := Value;
Changed;
end;
end;
function TcxCustomCalcEditProperties.GetAlwaysPostEditValue: Boolean;
begin
Result := True;
end;
class function TcxCustomCalcEditProperties.GetAssignedValuesClass: TcxCustomEditPropertiesValuesClass;
begin
Result := TcxCalcEditPropertiesValues;
end;
function TcxCustomCalcEditProperties.HasDigitGrouping(
AIsDisplayValueSynchronizing: Boolean): Boolean;
begin
Result := not ScientificFormat and UseThousandSeparator;
end;
function TcxCustomCalcEditProperties.PopupWindowAcceptsAnySize: Boolean;
begin
Result := False;
end;
function TcxCustomCalcEditProperties.StrToFloatEx(S: string;
var Value: Extended): Boolean;
var
E: Extended;
I: Integer;
begin
// Ignore Thousand Separators
for I := Length(S) downto 1 do
if S[I] = ThousandSeparator then
Delete(S, I, 1);
if not TextToFloat(PChar(S), E, fvExtended) or
((E <> 0) and ((Abs(E) < MinDouble) or (Abs(E) > MaxDouble))) then
begin
Value := 0;
Result := False;
end
else
begin
Value := E;
Result := True;
end;
end;
procedure TcxCustomCalcEditProperties.Assign(Source: TPersistent);
begin
if Source is TcxCustomCalcEditProperties then
begin
BeginUpdate;
try
inherited Assign(Source);
with TcxCustomCalcEditProperties(Source) do
begin
Self.BeepOnError := BeepOnError;
Self.AssignedValues.Precision := False;
if AssignedValues.Precision then
Self.Precision := Precision;
Self.QuickClose := QuickClose;
Self.ScientificFormat := ScientificFormat;
Self.UseThousandSeparator := UseThousandSeparator;
end;
finally
EndUpdate
end
end
else
inherited Assign(Source);
end;
class function TcxCustomCalcEditProperties.GetContainerClass: TcxContainerClass;
begin
Result := TcxCalcEdit;
end;
function TcxCustomCalcEditProperties.GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource;
begin
if not AEditFocused and not AssignedValues.DisplayFormat and
(IDefaultValuesProvider <> nil) and
IDefaultValuesProvider.IsDisplayFormatDefined(True) then
Result := evsText
else
Result := evsValue;
end;
function TcxCustomCalcEditProperties.IsDisplayValueValid(
var DisplayValue: TcxEditValue; AEditFocused: Boolean): Boolean;
begin
// if AEditFocused
Result := True;
end;
function TcxCustomCalcEditProperties.IsEditValueValid(var EditValue: TcxEditValue;
AEditFocused: Boolean): Boolean;
var
AValue: Extended;
begin
Result := VarIsNumericEx(EditValue) or VarIsSoftNull(EditValue);
if not Result then
Result := VarIsStr(EditValue) and
TextToFloat(PChar(VarToStr(EditValue)), AValue, fvExtended);
end;
procedure TcxCustomCalcEditProperties.PrepareDisplayValue(
const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue;
AEditFocused: Boolean);
procedure RemoveInsignificantZeros(var S: string);
var
AExponentialPart: string;
I: Integer;
begin
if Pos(DecimalSeparator, S) = 0 then
Exit;
AExponentialPart := RemoveExponentialPart(S);
I := Length(S);
while S[I] = '0' do
Dec(I);
Delete(S, I + 1, Length(S) - I);
if S[Length(S)] = DecimalSeparator then
Delete(S, Length(S), 1);
S := S + AExponentialPart;
end;
var
AFormat: TFloatFormat;
APrecision: Byte;
S: string;
begin
if VarIsSoftNull(AEditValue) then
S := ''
else
if not AEditFocused and AssignedValues.DisplayFormat then
S := FormatFloat(DisplayFormat, AEditValue)
else
begin
if ScientificFormat then
AFormat := ffExponent
else
AFormat := ffGeneral;
APrecision := Precision;
if APrecision = 0 then
APrecision := cxDefCalcPrecision;
S := FloatToStrF(AEditValue, AFormat, APrecision, 0);
if UseThousandSeparator and not ScientificFormat then
InsertThousandSeparator(S);
if ScientificFormat then
RemoveInsignificantZeros(S);
end;
DisplayValue := S;
end;
procedure TcxCustomCalcEditProperties.ValidateDisplayValue(
var ADisplayValue: TcxEditValue; var AErrorText: TCaption;
var Error: Boolean; AEdit: TcxCustomEdit);
begin
Error := False;
inherited ValidateDisplayValue(ADisplayValue, AErrorText, Error, AEdit);
end;
{ TcxCustomCalcEdit }
destructor TcxCustomCalcEdit.Destroy;
begin
FreeAndNil(FCalculator);
inherited Destroy;
end;
function TcxCustomCalcEdit.GetProperties: TcxCustomCalcEditProperties;
begin
Result := TcxCustomCalcEditProperties(FProperties);
end;
function TcxCustomCalcEdit.GetActiveProperties: TcxCustomCalcEditProperties;
begin
Result := TcxCustomCalcEditProperties(InternalGetActiveProperties);
end;
function TcxCustomCalcEdit.GetValue: Extended;
begin
if VarIsNull(EditValue) or (VarIsStr(EditValue) and (EditValue = '')) then
Result := 0
else
Result := EditValue;
end;
procedure TcxCustomCalcEdit.SetProperties(Value: TcxCustomCalcEditProperties);
begin
FProperties.Assign(Value);
end;
procedure TcxCustomCalcEdit.SetValue(const Value: Extended);
begin
InternalEditValue := Value;
end;
procedure TcxCustomCalcEdit.FormatChanged;
begin
DataBinding.UpdateDisplayValue;
end;
function TcxCustomCalcEdit.CanDropDown: Boolean;
begin
Result := (not ActiveProperties.ReadOnly) and DataBinding.IsDataAvailable;
end;
procedure TcxCustomCalcEdit.CreatePopupWindow;
begin
inherited CreatePopupWindow;
PopupWindow.ModalMode := False;
end;
procedure TcxCustomCalcEdit.DoEnter;
begin
SynchronizeDisplayValue;
inherited;
end;
procedure TcxCustomCalcEdit.DoExit;
begin
inherited;
DataBinding.UpdateDisplayValue;
end;
procedure TcxCustomCalcEdit.DoInitPopup;
begin
inherited DoInitPopup;
ActiveProperties.PopupControl := FCalculator;
end;
procedure TcxCustomCalcEdit.Initialize;
begin
inherited Initialize;
Value := 0;
FCalculator := TcxPopupCalculator.Create(Self);
FCalculator.Parent := PopupWindow;
FCalculator.Edit := Self;
FCalculator.AutoFontSize := False;
FCalculator.OnHidePopup := HidePopup;
ActiveProperties.PopupControl := FCalculator;
end;
procedure TcxCustomCalcEdit.InitializePopupWindow;
begin
inherited InitializePopupWindow;
with Calculator do
begin
HandleNeeded;
Font.Assign(Self.ActiveStyle.GetVisibleFont);
FontChanged;
Resize;
end;
end;
function TcxCustomCalcEdit.InternalGetEditingValue: TcxEditValue;
begin
PrepareEditValue(Text, Result, True);
end;
function TcxCustomCalcEdit.IsValidChar(Key: Char): Boolean;
function NumDigits(const S: string): Byte;
var
I: Integer;
begin
Result := 0;
for I := 1 to Length(S) do
if (S[I] = 'e') or (S[I] = 'E') then
Break
else
if S[I] in ['0'..'9'] then
Inc(Result);
end;
var
S: string;
V: Extended;
StartPos, StopPos: Integer;
begin
Result := False;
if not IsNumericChar(Key, ntExponent) then
Exit;
S := Text;
StartPos := SelStart;
StopPos := SelStart + SelLength;
Delete(S, SelStart + 1, StopPos - StartPos);
if (Key = '-') and (S = '') then
begin
Result := True;
Exit;
end;
Insert(Key, S, StartPos + 1);
Result := ActiveProperties.StrToFloatEx(S, V);
end;
procedure TcxCustomCalcEdit.KeyPress(var Key: Char);
begin
if (Key = '.') or (Key = ',') then
Key := DecimalSeparator;
if IsTextChar(Key) and not IsValidChar(Key) then
begin
Key := #0;
if ActiveProperties.BeepOnError then Beep;
end;
inherited KeyPress(Key);
end;
procedure TcxCustomCalcEdit.PopupWindowClosed(Sender: TObject);
begin
if Text = cxGetResourceString(@scxSCalcError) then InternalEditValue := 0;
if ActiveProperties.AutoSelect then SelectAll else SelStart := Length(Text);
inherited PopupWindowClosed(Sender);
end;
procedure TcxCustomCalcEdit.PopupWindowShowed(Sender: TObject);
begin
inherited PopupWindowShowed(Sender);
FCalculator.Init;
end;
procedure TcxCustomCalcEdit.PropertiesChanged(Sender: TObject);
begin
if (Sender <> nil) and ActiveProperties.FormatChanging then
Exit;
inherited PropertiesChanged(Sender);
if not PropertiesChangeLocked then
begin
FCalculator.BeepOnError := ActiveProperties.BeepOnError;
FCalculator.Precision := ActiveProperties.Precision;
ActiveProperties.FChangedLocked := True;
ActiveProperties.PopupControl := FCalculator;
ActiveProperties.FChangedLocked := False;
end;
end;
function TcxCustomCalcEdit.InternalPrepareEditValue(const ADisplayValue: string;
out EditValue: TcxEditValue): Boolean;
var
AValue: Extended;
S: string;
begin
Result := True;
S := VarToStr(ADisplayValue);
if not ActiveProperties.ScientificFormat and ActiveProperties.UseThousandSeparator then
RemoveThousandSeparator(S);
if Trim(S) = '' then
EditValue := Null
else
begin
Result := TextToFloat(PChar(S), AValue, fvExtended);
if Result then
EditValue := AValue
else
EditValue := Null;
end;
end;
class function TcxCustomCalcEdit.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCustomCalcEditProperties;
end;
procedure TcxCustomCalcEdit.PasteFromClipboard;
begin
if DoEditing then
Calculator.PasteFromClipboard;
end;
procedure TcxCustomCalcEdit.PrepareEditValue(
const ADisplayValue: TcxEditValue; out EditValue: TcxEditValue;
AEditFocused: Boolean);
begin
InternalPrepareEditValue(ADisplayValue, EditValue);
end;
{ TcxCalcEdit }
class function TcxCalcEdit.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCalcEditProperties;
end;
function TcxCalcEdit.GetActiveProperties: TcxCalcEditProperties;
begin
Result := TcxCalcEditProperties(InternalGetActiveProperties);
end;
function TcxCalcEdit.GetProperties: TcxCalcEditProperties;
begin
Result := TcxCalcEditProperties(FProperties);
end;
procedure TcxCalcEdit.SetProperties(Value: TcxCalcEditProperties);
begin
FProperties.Assign(Value);
end;
{ TcxFilterCalcEditHelper }
class function TcxFilterCalcEditHelper.GetFilterEditClass: TcxCustomEditClass;
begin
Result := TcxCalcEdit;
end;
class function TcxFilterCalcEditHelper.GetSupportedFilterOperators(
AProperties: TcxCustomEditProperties;
AValueTypeClass: TcxValueTypeClass;
AExtendedSet: Boolean = False): TcxFilterControlOperators;
begin
Result := [fcoEqual, fcoNotEqual, fcoLess, fcoLessEqual, fcoGreater,
fcoGreaterEqual, fcoBlanks, fcoNonBlanks];
if AExtendedSet then
Result := Result + [fcoBetween, fcoNotBetween, fcoInList, fcoNotInList];
end;
class procedure TcxFilterCalcEditHelper.InitializeProperties(AProperties,
AEditProperties: TcxCustomEditProperties; AHasButtons: Boolean);
begin
inherited InitializeProperties(AProperties, AEditProperties, AHasButtons);
with TcxCustomCalcEditProperties(AProperties) do
QuickClose := True;
end;
initialization
GetRegisteredEditProperties.Register(TcxCalcEditProperties, scxSEditRepositoryCalcItem);
FilterEditsController.Register(TcxCalcEditProperties, TcxFilterCalcEditHelper);
finalization
FilterEditsController.Unregister(TcxCalcEditProperties, TcxFilterCalcEditHelper);
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?