{----------------------------------------------------------------------------- The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/MPL-1.1.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: JvCurrEdit.PAS, released on 2002-07-04. The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev Copyright (c) 2001,2002 SGB Software All Rights Reserved. Contributor(s): Polaris Software Andreas Hausladen You may retrieve the latest version of this file at the Project JEDI's JVCL home page, located at http://jvcl.sourceforge.net Known Issues: (rb) Compare property names with those of TJvSpinEdit, JvValidateEdit, for example DecimalPlaces/Decimal, CheckMinValue (name indicates action? maybe better: TJvValidateEdit's HasMinValue) etc. -----------------------------------------------------------------------------} // $Id: JvBaseEdits.pas 10902 2006-08-22 12:51:55Z obones $ unit JvBaseEdits; {$I jvcl.inc} interface uses {$IFDEF UNITVERSIONING} JclUnitVersioning, {$ENDIF UNITVERSIONING} {$IFDEF CLR} WinUtils, Variants, {$ENDIF CLR} Windows, Messages, Classes, Controls, ImgList, JvToolEdit; type TJvCustomNumEdit = class(TJvCustomComboEdit) private FCanvas: TControlCanvas; // asn: never created FAlignment: TAlignment; FFocused: Boolean; FValue: Extended; FMinValue: Extended; FMaxValue: Extended; FDecimalPlaces: Cardinal; FDecimalPlacesAlwaysShown: Boolean; // WAP Added. True means Use 0 instead of # in FormatFloat picture (ie 0.000 versus 0.####). NEW. FCheckOnExit: Boolean; FZeroEmpty: Boolean; FFormatOnEditing: Boolean; FFormatting: Boolean; FDisplayFormat: string; // Polaris FDecimalPlaceRound: Boolean; function GetEditFormat: string; // WAP added. procedure SetDecimalPlaceRound(Value: Boolean); procedure SetFocused(Value: Boolean); procedure SetAlignment(Value: TAlignment); procedure SetDisplayFormat(const Value: string); function GetDisplayFormat: string; procedure SetDecimalPlaces(Value: Cardinal); procedure SetDecimalPlacesAlwaysShown( Value:Boolean ); function GetValue: Extended; procedure SetValue(AValue: Extended); function GetAsInteger: Longint; procedure SetAsInteger(AValue: Longint); procedure SetMaxValue(AValue: Extended); procedure SetMinValue(AValue: Extended); procedure SetZeroEmpty(Value: Boolean); procedure SetFormatOnEditing(Value: Boolean); function GetText: string; {$IFDEF VisualCLX} reintroduce; {$ENDIF} // function TextToValText(const AValue: string): string; //Polaris function CheckValue(NewValue: Extended; RaiseOnError: Boolean): Extended; function IsFormatStored: Boolean; {$IFDEF VCL} procedure WMPaint(var Msg: TWMPaint); message WM_PAINT; {$ENDIF VCL} protected {$IFDEF VisualCLX} procedure Paint; override; {$ENDIF VisualCLX} procedure WMPaste(var Msg: TMessage); message WM_PASTE; procedure SetBeepOnError(Value: Boolean); override; procedure SetText(const AValue: string); {$IFDEF VisualCLX} reintroduce; {$ENDIF} virtual; procedure EnabledChanged; override; procedure DoEnter; override; procedure DoExit; override; procedure FontChanged; override; //Polaris up to protected function CheckValue(NewValue: Extended; RaiseOnError: Boolean): Extended; procedure AcceptValue(const Value: Variant); override; procedure Change; override; procedure ReformatEditText; dynamic; procedure DataChanged; virtual; function DefaultDisplayFormat: 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; procedure UpdatePopup; virtual; property Formatting: Boolean read FFormatting; property Alignment: TAlignment read FAlignment write SetAlignment default taRightJustify; property CheckOnExit: Boolean read FCheckOnExit write FCheckOnExit default False; property ImageKind default ikDefault; property ButtonWidth default 21; //Polaris 20; property DecimalPlaces: Cardinal read FDecimalPlaces write SetDecimalPlaces default 2; // WAP Added. True means Use 0 instead of # in FormatFloat picture (ie 0.000 versus 0.####). NEW. property DecimalPlacesAlwaysShown: Boolean read FDecimalPlacesAlwaysShown write SetDecimalPlacesAlwaysShown; property DisplayFormat: string read GetDisplayFormat write SetDisplayFormat stored IsFormatStored; property MaxValue: Extended read FMaxValue write SetMaxValue; property MinValue: Extended read FMinValue write SetMinValue; property FormatOnEditing: Boolean read FFormatOnEditing write SetFormatOnEditing default False; property Text: string read GetText write SetText stored False; property MaxLength default 0; property ZeroEmpty: Boolean read FZeroEmpty write SetZeroEmpty default True; //Polaris property DecimalPlaceRound: Boolean read FDecimalPlaceRound write SetDecimalPlaceRound default False; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; class function DefaultImageIndex: TImageIndex; override; procedure Clear; override; property AsInteger: Longint read GetAsInteger write SetAsInteger; property DisplayText: string read GetDisplayText; property PopupVisible; property Value: Extended read GetValue write SetValue; end; TJvxCurrencyEdit = class(TJvCustomNumEdit) protected function DefaultDisplayFormat: string; override; public constructor Create(AOwner: TComponent); override; published {$IFDEF VCL} property BiDiMode; property DragCursor; property DragKind; property Flat; property ImeMode; property ImeName; property ParentBiDiMode; property ParentCtl3D; property OnEndDock; property OnStartDock; {$ENDIF VCL} property Align; //Polaris property Alignment; property Anchors; property AutoSelect; property AutoSize; property BeepOnError; property BorderStyle; property CheckOnExit; property ClipboardCommands; // RDB property Color; property Constraints; property DecimalPlaceRound; //Polaris property DecimalPlaces; property DisabledColor; // RDB property DisabledTextColor; // RDB property DisplayFormat; property DragMode; property Enabled; property Font; property FormatOnEditing; property HideSelection; property MaxLength; property MaxValue; property MinValue; property ParentColor; property ParentFont; property ParentShowHint; property PopupMenu; property ReadOnly; property ShowHint; property TabOrder; property TabStop; property Text; property Value; property Visible; property ZeroEmpty; property OnChange; property OnClick; property OnContextPopup; 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; end; TJvCustomCalcEdit = class(TJvCustomNumEdit) private FEnablePopupChange: Boolean; protected procedure PopupChange; override; property EnablePopupChange: Boolean read FEnablePopupChange write FEnablePopupChange default False; public constructor Create(AOwner: TComponent); override; end; TJvCalcEdit = class(TJvCustomCalcEdit) published {$IFDEF VCL} {$IFDEF COMPILER6_UP} property BevelEdges; property BevelInner; property BevelKind default bkNone; property BevelOuter; {$ENDIF COMPILER6_UP} property BiDiMode; property DragCursor; property DragKind; property Flat; property ParentBiDiMode; property ParentFlat; property ImeMode; property ImeName; property OnEndDock; property OnStartDock; {$ENDIF VCL} property Action; property Align; //Polaris property Alignment; property AutoSelect; property AutoSize; property BeepOnError; property BorderStyle; property ButtonFlat; property ButtonHint; property CheckOnExit; property ClickKey; property Color; property DecimalPlaceRound; //Polaris property DecimalPlaces; property DirectInput; property DisplayFormat; property DragMode; property Enabled; property EnablePopupChange; property Font; property FormatOnEditing; property Glyph; property ImageIndex; property Images; property ImageKind; property ButtonWidth; property HideSelection; property Anchors; property Constraints; property MaxLength; property MaxValue; property MinValue; property NumGlyphs; property ParentColor; property ParentFont; property ParentShowHint; property PopupAlign; property PopupMenu; property ReadOnly; property ShowButton; property ShowHint; property TabOrder; property TabStop; property Text; property Value; property Visible; property ZeroEmpty; (* ++ RDB ++ *) property ClipboardCommands; property DisabledTextColor; property DisabledColor; (* -- RDB -- *) property DecimalPlacesAlwaysShown; {WAP Added.} 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 OnContextPopup; property OnStartDrag; end; {$IFDEF UNITVERSIONING} const UnitVersioning: TUnitVersionInfo = ( RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_32/run/JvBaseEdits.pas $'; Revision: '$Revision: 10902 $'; Date: '$Date: 2006-08-22 14:51:55 +0200 (mar., 22 août 2006) $'; LogPath: 'JVCL\run' ); {$ENDIF UNITVERSIONING} implementation uses SysUtils, Math, Consts, Graphics, // JclLogic, JvVCL5Utils, JvJCLUtils, JvCalc, JvConsts, JvResources; {$R JvBaseEdits.Res} const sCalcBmp = 'JvCustomNumEditBUTTONGLYPH'; { Numeric editor button glyph } var GCalcImageIndex: TImageIndex = -1; type TJvPopupWindowAccessProtected = class(TJvPopupWindow); {$IFDEF CLR} function DecimalSeparator: AnsiChar; begin Result := AnsiChar(SysUtils.DecimalSeparator[1]); end; function ThousandSeparator: Char; begin Result := SysUtils.ThousandSeparator[1]; end; {$ENDIF CLR} function IsValidFloat(const Value: string; var RetValue: Extended): Boolean; var I: Integer; {$IFDEF CLR} d: Double; {$ENDIF CLR} begin Result := False; for I := 1 to Length(Value) do if not (Value[I] in [DecimalSeparator, '-', '+', '0'..'9', 'e', 'E']) then Exit; {$IFDEF CLR} Result := TryStrToFloat(Value, d); RetValue := d; {$ELSE} Result := TextToFloat(PChar(Value), RetValue, fvExtended); {$ENDIF CLR} end; function FormatFloatStr(const S: string; Thousands: Boolean): string; var I, MaxSym, MinSym, Group: Integer; IsSign: Boolean; begin Result := ''; MaxSym := Length(S); IsSign := (MaxSym > 0) and (S[1] in SignSymbols); if IsSign then MinSym := 2 else MinSym := 1; I := Pos(DecimalSeparator, S); if I > 0 then MaxSym := I - 1; {$IFDEF CLR} I := Pos('E', UpperCase(S)); {$ELSE} I := Pos('E', AnsiUpperCase(S)); {$ENDIF CLR} if I > 0 then MaxSym := Min(I - 1, MaxSym); Result := Copy(S, MaxSym + 1, MaxInt); Group := 0; for I := MaxSym downto MinSym do begin Result := S[I] + Result; Inc(Group); if (Group = 3) and Thousands and (I > MinSym) then begin Group := 0; Result := ThousandSeparator + Result; end; end; if IsSign then Result := S[1] + Result; end; //=== { TJvCustomNumEdit } =================================================== constructor TJvCustomNumEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle - [csSetCaption]; FDecimalPlaceRound := False; // Polaris MaxLength := 0; FAlignment := taRightJustify; FDisplayFormat := DefaultDisplayFormat; FDecimalPlaces := 2; FZeroEmpty := True; inherited Text := ''; inherited Alignment := taLeftJustify; { forces update } DataChanged; ControlState := ControlState + [csCreating]; try { TODO : Check } ImageKind := ikDefault; //Polaris ButtonWidth := 20; ButtonWidth := 21; finally ControlState := ControlState - [csCreating]; end; end; destructor TJvCustomNumEdit.Destroy; begin FCanvas.Free; if FPopup <> nil then begin TJvPopupWindow(FPopup).OnCloseUp := nil; FPopup.Parent := nil; end; FreeAndNil(FPopup); inherited Destroy; end; //Polaris procedure TJvCustomNumEdit.SetDecimalPlaceRound(Value: Boolean); begin if FDecimalPlaceRound <> Value then begin FDecimalPlaceRound := Value; SetValue(CheckValue(FValue, False)); Invalidate; ReformatEditText; end; end; function TJvCustomNumEdit.DefaultDisplayFormat: string; begin Result := ',0.##'; end; function TJvCustomNumEdit.IsFormatStored: Boolean; begin Result := (DisplayFormat <> DefaultDisplayFormat); end; { (rb) This function works NOT the same as JvJCLUtils.TextToValText; for example it does NOT remove 'a'..'z' chars. Couldn't come up with a good name, so feel free to change it } function xTextToValText(const AValue: string): string; begin Result := DelRSpace(AValue); if DecimalSeparator <> AnsiChar(ThousandSeparator) then Result := DelChars(Result, ThousandSeparator); if (DecimalSeparator <> '.') and (ThousandSeparator <> '.') then Result := ReplaceStr(Result, '.', DecimalSeparator); if (DecimalSeparator <> ',') and (ThousandSeparator <> ',') then Result := ReplaceStr(Result, ',', DecimalSeparator); if Result = '' then Result := '0' else if Result = '-' then Result := '-0'; end; function TJvCustomNumEdit.IsValidChar(Key: Char): Boolean; var S: string; SelStart, SelStop, DecPos: Integer; RetValue: Extended; begin Result := False; S := EditText; GetSel(SelStart, SelStop); Delete(S, SelStart + 1, SelStop - SelStart); Insert(Key, S, SelStart + 1); S := xTextToValText(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 TJvCustomNumEdit.KeyPress(var Key: Char); begin if PopupVisible and (UpCase(Key) in DigitSymbols + [DecimalSeparator, '.', ',', '+', '-', '*', '/', '_', '=', 'C', 'R', 'Q', '%', Backspace, Cr] - [AnsiChar(ThousandSeparator)]) then begin TJvPopupWindowAccessProtected(FPopup).KeyPress(Key); Key := #0; end; if Key in ['.', ','] - [AnsiChar(ThousandSeparator)] then Key := Char(DecimalSeparator); inherited KeyPress(Key); if (Key in [#32..#255]) and not IsValidChar(Key) then begin DoBeepOnError; Key := #0; end else if Key = Esc then begin Reset; Key := #0; end; end; procedure TJvCustomNumEdit.Reset; begin DataChanged; SelectAll; end; procedure TJvCustomNumEdit.SetZeroEmpty(Value: Boolean); begin if FZeroEmpty <> Value then begin FZeroEmpty := Value; DataChanged; end; end; procedure TJvCustomNumEdit.SetBeepOnError(Value: Boolean); begin if BeepOnError <> Value then begin inherited SetBeepOnError(Value); UpdatePopup; end; end; procedure TJvCustomNumEdit.SetAlignment(Value: TAlignment); begin if FAlignment <> Value then begin FAlignment := Value; Invalidate; end; end; procedure TJvCustomNumEdit.SetDisplayFormat(const Value: string); begin if DisplayFormat <> Value then begin FDisplayFormat := Value; Invalidate; DataChanged; end; end; function TJvCustomNumEdit.GetDisplayFormat: string; begin Result := FDisplayFormat; end; procedure TJvCustomNumEdit.SetFocused(Value: Boolean); begin if FFocused <> Value then begin FFocused := Value; Invalidate; FFormatting := True; try DataChanged; finally FFormatting := False; end; end; end; procedure TJvCustomNumEdit.SetFormatOnEditing(Value: Boolean); begin if FFormatOnEditing <> Value then begin FFormatOnEditing := Value; if FFormatOnEditing then inherited Alignment := Alignment else inherited Alignment := taLeftJustify; if FFormatOnEditing and FFocused then ReformatEditText else if FFocused then begin UpdateData; DataChanged; end; end; end; procedure TJvCustomNumEdit.SetDecimalPlaces(Value: Cardinal); begin if FDecimalPlaces <> Value then begin FDecimalPlaces := Value; // WAP Added. Changes to decimal places formerly did not change // FDisplayFormat, which causes both designtime and runtime problems! SetDisplayFormat(GetEditFormat); SetValue(CheckValue(FValue, False)); // Polaris (?) DataChanged; Invalidate; end; end; {WAP added this new property: Switches between using 0.000 and 0.### as a FormatFloat picture. } procedure TJvCustomNumEdit.SetDecimalPlacesAlwaysShown( Value:Boolean ); begin if FDecimalPlacesAlwaysShown <> Value then begin FDecimalPlacesAlwaysShown := Value; SetDisplayFormat(GetEditFormat); // Redo format picture SetValue(CheckValue(FValue, False)); // Polaris (?) DataChanged; Invalidate; end; end; function TJvCustomNumEdit.FormatDisplayText(Value: Extended): string; begin if DisplayFormat <> '' then Result := FormatFloat(DisplayFormat, Value) else Result := FloatToStr(Value); end; function TJvCustomNumEdit.GetDisplayText: string; begin Result := FormatDisplayText(FValue); end; procedure TJvCustomNumEdit.Clear; begin Text := ''; end; {WAP added GetEditFormat, this code used to be ininline inside DataChanged.} function TJvCustomNumEdit.GetEditFormat:String; begin Result := '0'; if FDecimalPlaces > 0 then if FDecimalPlacesAlwaysShown then Result := Result + '.' + MakeStr('0', FDecimalPlaces) else Result := Result + '.' + MakeStr('#', FDecimalPlaces); end; procedure TJvCustomNumEdit.DataChanged; var EditFormat: string; WasModified: Boolean; begin EditFormat := GetEditFormat; { Changing EditText sets Modified to false } WasModified := Modified; try if (FValue = 0.0) and FZeroEmpty then EditText := '' else EditText := FormatFloat(EditFormat, CheckValue(FValue, False)); finally Modified := WasModified; end; end; function TJvCustomNumEdit.CheckValue(NewValue: Extended; RaiseOnError: Boolean): Extended; var DP: Integer; begin if FDecimalPlaceRound then begin //Polaris DP := FDecimalPlaces; { (rb) Probably: Round to the nearest, and if two are equally near, away from zero Ln, Exp are slow; make more generic (why only this one?), see http://www.merlyn.demon.co.uk/pas-chop.htm } NewValue := Int(NewValue * Exp(DP * Ln(10)) + Sign(NewValue) * 0.50000001) * Exp(-DP * Ln(10)); end; Result := NewValue; if FMaxValue <> FMinValue then begin if FMaxValue > FMinValue then begin if NewValue < FMinValue then Result := FMinValue else if NewValue > FMaxValue then Result := FMaxValue; end else begin if FMaxValue = 0 then begin if NewValue < FMinValue then Result := FMinValue; end else if FMinValue = 0 then begin if NewValue > FMaxValue then Result := FMaxValue; end; end; if RaiseOnError and (Result <> NewValue) then {$IFDEF CLR} raise ERangeError.CreateFmt(RsEOutOfRangeXFloat, {$ELSE} raise ERangeError.CreateResFmt(@RsEOutOfRangeXFloat, {$ENDIF CLR} [DecimalPlaces, FMinValue, DecimalPlaces, FMaxValue]); end; end; procedure TJvCustomNumEdit.CheckRange; begin if not (csDesigning in ComponentState) and CheckOnExit then CheckValue(StrToFloat(TextToValText(EditText)), True); end; procedure TJvCustomNumEdit.UpdateData; begin ValidateEdit; FValue := CheckValue(StrToFloat(TextToValText(EditText)), False); end; procedure TJvCustomNumEdit.UpdatePopup; begin if FPopup <> nil then SetupPopupCalculator(FPopup, DefCalcPrecision, BeepOnError); end; function TJvCustomNumEdit.GetValue: Extended; begin if not (csDesigning in ComponentState) then try UpdateData; except FValue := FMinValue; end; Result := FValue; end; procedure TJvCustomNumEdit.SetValue(AValue: Extended); begin FValue := CheckValue(AValue, False); DataChanged; Invalidate; end; function TJvCustomNumEdit.GetAsInteger: Longint; begin Result := trunc(Value); end; procedure TJvCustomNumEdit.SetAsInteger(AValue: Longint); begin SetValue(AValue); end; procedure TJvCustomNumEdit.SetMinValue(AValue: Extended); begin if FMinValue <> AValue then begin FMinValue := AValue; Value := FValue; end; end; procedure TJvCustomNumEdit.SetMaxValue(AValue: Extended); begin if FMaxValue <> AValue then begin FMaxValue := AValue; Value := FValue; end; end; function TJvCustomNumEdit.GetText: string; begin Result := inherited Text; end; (* function TJvCustomNumEdit.TextToValText(const AValue: string): string; var I: Integer; X: Char; begin Result := DelRSpace(AValue); if DecimalSeparator <> ThousandSeparator then Result := DelChars(Result, ThousandSeparator); if (DecimalSeparator <> '.') and (ThousandSeparator <> '.') then Result := ReplaceStr(Result, '.', DecimalSeparator); if (DecimalSeparator <> ',') and (ThousandSeparator <> ',') then Result := ReplaceStr(Result, ',', DecimalSeparator); // Aquarius I := 1; while I <= Length(Result) do begin X := Result[I]; if (X = DecimalSeparator) or (X = '-') or (X in DigitSymbols) then begin I := I + 1; Continue; end else Result := Copy(Result, 1, I - 1) + Copy(Result, I + 1, Length(Result) - 1); end; if Result = '' then Result := '0' else if Result = '-' then Result := '-0'; end; *) procedure TJvCustomNumEdit.SetText(const AValue: string); begin if not (csReading in ComponentState) then begin FValue := CheckValue(StrToFloat(TextToValText(AValue)), False); DataChanged; Invalidate; end; end; procedure TJvCustomNumEdit.ReformatEditText; var S: string; IsEmpty: Boolean; OldLen, SelStart, SelStop: Integer; WasModified: Boolean; begin FFormatting := True; { Changing Text sets Modified to false } WasModified := Modified; try S := inherited Text; OldLen := Length(S); IsEmpty := (OldLen = 0) or (S = '-'); if HandleAllocated then GetSel(SelStart, SelStop); if not IsEmpty then S := TextToValText(S); S := FormatFloatStr(S, Pos(',', DisplayFormat) > 0); inherited Text := S; if HandleAllocated and (GetFocus = Handle) and not (csDesigning in ComponentState) then begin Inc(SelStart, Length(S) - OldLen); SetCursor(SelStart); end; finally FFormatting := False; Modified := WasModified; end; end; procedure TJvCustomNumEdit.Change; begin if not FFormatting then begin if FFormatOnEditing and FFocused then ReformatEditText; inherited Change; end; end; procedure TJvCustomNumEdit.AcceptValue(const Value: Variant); begin inherited AcceptValue(Value); Self.Value := CheckValue(Value, False); //Polaris end; procedure TJvCustomNumEdit.WMPaste(var Msg: TMessage); var S: string; WasModified: Boolean; begin WasModified := Modified; S := EditText; try inherited; UpdateData; except { Changing EditText sets Modified to false } EditText := S; Modified := WasModified; SelectAll; if CanFocus then SetFocus; DoBeepOnError; end; end; procedure TJvCustomNumEdit.DoEnter; begin SetFocused(True); if FFormatOnEditing then ReformatEditText; inherited DoEnter; end; procedure TJvCustomNumEdit.DoExit; begin try CheckRange; UpdateData; except SelectAll; if CanFocus then SetFocus; raise; end; SetFocused(False); SetCursor(0); inherited DoExit; end; procedure TJvCustomNumEdit.EnabledChanged; begin inherited EnabledChanged; if NewStyleControls and not FFocused then Invalidate; end; {$IFDEF VCL} procedure TJvCustomNumEdit.WMPaint(var Msg: TWMPaint); var S: string; begin if PopupVisible then S := TJvPopupWindow(FPopup).GetPopupText else S := GetDisplayText; if not PaintComboEdit(Self, S, FAlignment, FFocused and not PopupVisible, FCanvas, Msg) then inherited; end; {$ENDIF VCL} {$IFDEF VisualCLX} procedure TJvCustomNumEdit.Paint; var S: string; begin if PopupVisible then S := TJvPopupWindow(FPopup).GetPopupText else S := GetDisplayText; if not PaintComboEdit(Self, S, FAlignment, True, FFocused and not PopupVisible, Canvas) then inherited; end; {$ENDIF VisualCLX} procedure TJvCustomNumEdit.FontChanged; begin inherited FontChanged; Invalidate; end; //=== { TJvxCurrencyEdit } =================================================== constructor TJvxCurrencyEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlState := ControlState + [csCreating]; try ButtonWidth := 0; finally ControlState := ControlState - [csCreating]; end; end; function TJvxCurrencyEdit.DefaultDisplayFormat: string; var CurrStr: string; I: Integer; C: Char; begin Result := ',0.' + MakeStr('0', CurrencyDecimals); CurrStr := ''; for I := 1 to Length(CurrencyString) do begin C := CurrencyString[I]; if C in [',', '.'] then CurrStr := CurrStr + '''' + C + '''' else CurrStr := CurrStr + C; end; if Length(CurrStr) > 0 then case CurrencyFormat of 0: Result := CurrStr + Result; { '$1' } 1: Result := Result + CurrStr; { '1$' } 2: Result := CurrStr + ' ' + Result; { '$ 1' } 3: Result := Result + ' ' + CurrStr; { '1 $' } end; Result := Format('%s;-%s', [Result, Result]); end; //=== { TJvCustomCalcEdit } ================================================== constructor TJvCustomCalcEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle - [csAcceptsControls]; ControlState := ControlState + [csCreating]; try FPopup := TJvPopupWindow(CreatePopupCalculator(Self {$IFDEF VCL}, BiDiMode {$ENDIF})); TJvPopupWindow(FPopup).OnCloseUp := PopupCloseUp; UpdatePopup; finally ControlState := ControlState - [csCreating]; end; end; procedure TJvCustomCalcEdit.PopupChange; begin inherited PopupChange; if EnablePopupChange then DoChange; end; class function TJvCustomNumEdit.DefaultImageIndex: TImageIndex; var Bmp: TBitmap; begin if GCalcImageIndex < 0 then begin Bmp := TBitmap.Create; try //Bmp.Handle := LoadBitmap(HInstance, sCalcBmp); Bmp.LoadFromResourceName(HInstance, sCalcBmp); GCalcImageIndex := DefaultImages.AddMasked(Bmp, clFuchsia); finally Bmp.Free; end; end; Result := GCalcImageIndex; end; {$IFDEF UNITVERSIONING} initialization RegisterUnitVersion(HInstance, UnitVersioning); finalization UnregisterUnitVersion(HInstance); {$ENDIF UNITVERSIONING} end.