
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@44 8e941d3f-bd1b-0410-a28a-d453659cc2b4
1809 lines
44 KiB
ObjectPascal
1809 lines
44 KiB
ObjectPascal
{*********************************************************}
|
|
{* OVCNF.PAS 4.06 *}
|
|
{*********************************************************}
|
|
|
|
{* ***** BEGIN LICENSE BLOCK ***** *}
|
|
{* Version: MPL 1.1 *}
|
|
{* *}
|
|
{* 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/ *}
|
|
{* *}
|
|
{* Software distributed under the License is distributed on an "AS IS" basis, *}
|
|
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *}
|
|
{* for the specific language governing rights and limitations under the *}
|
|
{* License. *}
|
|
{* *}
|
|
{* The Original Code is TurboPower Orpheus *}
|
|
{* *}
|
|
{* The Initial Developer of the Original Code is TurboPower Software *}
|
|
{* *}
|
|
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *}
|
|
{* TurboPower Software Inc. All Rights Reserved. *}
|
|
{* *}
|
|
{* Contributor(s): *}
|
|
{* *}
|
|
{* ***** END LICENSE BLOCK ***** *}
|
|
|
|
{$I OVC.INC}
|
|
|
|
{$B-} {Complete Boolean Evaluation}
|
|
{$I+} {Input/Output-Checking}
|
|
{$P+} {Open Parameters}
|
|
{$T-} {Typed @ Operator}
|
|
{.W-} {Windows Stack Frame}
|
|
{$X+} {Extended Syntax}
|
|
|
|
unit ovcnf;
|
|
{-Numeric field visual component}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFNDEF LCL} Windows, Messages, {$ELSE} LclIntf, LMessages, LclType, MyMisc, {$ENDIF}
|
|
Classes, Controls, Forms, Graphics, Menus, SysUtils,
|
|
OvcBase, OvcCaret, OvcColor, OvcConst, OvcData, OvcEF, OvcExcpt,
|
|
OvcMisc, OvcPB, OvcStr;
|
|
|
|
type
|
|
{numeric field types}
|
|
TNumericDataType = (
|
|
nftLongInt, nftWord, nftInteger, nftByte, nftShortInt, nftReal,
|
|
nftExtended, nftDouble, nftSingle, nftComp);
|
|
|
|
type
|
|
TOvcCustomNumericField = class(TOvcPictureBase)
|
|
{.Z+}
|
|
protected {private}
|
|
{property instance variables}
|
|
FNumericDataType : TNumericDataType;
|
|
FPictureMask : string;
|
|
|
|
{private instance variables}
|
|
nfMaxLen : Word; {maximum length of numeric string}
|
|
nfMaxDigits : Word; {maximum # of digits to left of decimal}
|
|
nfPlaces : Word; {# of decimal places}
|
|
nfMinus : Boolean; {true if number is negative}
|
|
nfTmp : TEditString; {temporary input string}
|
|
|
|
function nfGetDataType(Value : TNumericDataType) : Byte;
|
|
{-return a Byte value representing the data type of this field}
|
|
procedure nfReloadTmp;
|
|
{-reload Tmp from efEditSt, etc.}
|
|
procedure nfResetFieldProperties(FT : TNumericDataType);
|
|
{-reset field properties}
|
|
procedure nfSetDefaultRanges;
|
|
{-set default range values based on the field type}
|
|
procedure nfSetMaxLength(Mask : PAnsiChar);
|
|
{-determine and set MaxLength}
|
|
|
|
procedure WMSetFocus(var Msg : TWMSetFocus);
|
|
message WM_SETFOCUS;
|
|
procedure WMKillFocus(var Msg : TWMKillFocus);
|
|
message WM_KILLFOCUS;
|
|
|
|
protected
|
|
{VCL methods}
|
|
procedure CreateParams(var Params : TCreateParams);
|
|
override;
|
|
procedure CreateWnd;
|
|
override;
|
|
|
|
procedure efCaretToEnd;
|
|
override;
|
|
{-move the caret to the end of the field}
|
|
procedure efCaretToStart;
|
|
override;
|
|
{-move the caret to the beginning of the field}
|
|
procedure efChangeMask(Mask : PAnsiChar);
|
|
override;
|
|
{-change the picture mask}
|
|
procedure efEdit(var Msg : TMessage; Cmd : Word);
|
|
override;
|
|
{-process the specified editing command}
|
|
function efGetDisplayString(Dest : PAnsiChar; Size : Word) : PAnsiChar;
|
|
override;
|
|
{-return the display string in Dest and a pointer as the result}
|
|
procedure efIncDecValue(Wrap : Boolean; Delta : Double);
|
|
override;
|
|
{-increment field by Delta}
|
|
function efTransfer(DataPtr : Pointer; TransferFlag : Word) : Word;
|
|
override;
|
|
{-transfer data to/from the entry fields}
|
|
procedure pbRemoveSemiLits;
|
|
override;
|
|
{-remove semi-literal mask characters from the edit string}
|
|
|
|
{virtual property methods}
|
|
procedure efSetCaretPos(Value : Integer);
|
|
override;
|
|
{-set position of caret within the field}
|
|
procedure nfSetDataType(Value : TNumericDataType);
|
|
virtual;
|
|
{-set the data type for this field}
|
|
procedure nfSetPictureMask(const Value : string);
|
|
virtual;
|
|
{-set the picture mask}
|
|
|
|
public
|
|
procedure Assign(Source : TPersistent);
|
|
override;
|
|
constructor Create(AOwner: TComponent);
|
|
override;
|
|
|
|
function efValidateField : Word;
|
|
override;
|
|
{-validate contents of field; result is error code or 0}
|
|
{.Z-}
|
|
|
|
{public properties}
|
|
property DataType : TNumericDataType
|
|
read FNumericDataType
|
|
write nfSetDataType;
|
|
|
|
property PictureMask : string
|
|
read FPictureMask
|
|
write nfSetPictureMask;
|
|
end;
|
|
|
|
TOvcNumericField = class(TOvcCustomNumericField)
|
|
published
|
|
{inherited properties}
|
|
property DataType; {needs to loaded before most other properties}
|
|
{$IFDEF VERSION4}
|
|
property Anchors;
|
|
property Constraints;
|
|
property DragKind;
|
|
{$ENDIF}
|
|
property AutoSize;
|
|
property BorderStyle;
|
|
property CaretIns;
|
|
property CaretOvr;
|
|
property Color;
|
|
property Controller;
|
|
property Ctl3D;
|
|
property Borders;
|
|
property DragCursor;
|
|
property DragMode;
|
|
property EFColors;
|
|
property Enabled;
|
|
property Font;
|
|
property LabelInfo;
|
|
property Options;
|
|
property PadChar;
|
|
property ParentColor;
|
|
property ParentCtl3D;
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PictureMask;
|
|
property PopupMenu;
|
|
property RangeHi stored False;
|
|
property RangeLo stored False;
|
|
property ShowHint;
|
|
property TabOrder;
|
|
property TabStop default True;
|
|
property Tag;
|
|
property TextMargin;
|
|
property Uninitialized;
|
|
property Visible;
|
|
property ZeroDisplay;
|
|
property ZeroDisplayValue;
|
|
|
|
{inherited events}
|
|
property AfterEnter;
|
|
property AfterExit;
|
|
property OnChange;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnError;
|
|
property OnExit;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnMouseWheel;
|
|
property OnStartDrag;
|
|
property OnUserCommand;
|
|
property OnUserValidation;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{*** TOvcCustomNumericField ***}
|
|
|
|
procedure TOvcCustomNumericField.Assign(Source : TPersistent);
|
|
var
|
|
NF : TOvcCustomNumericField absolute Source;
|
|
begin
|
|
if (Source <> nil) and (Source is TOvcCustomNumericField) then begin
|
|
DataType := NF.DataType;
|
|
AutoSize := NF.AutoSize;
|
|
BorderStyle := NF.BorderStyle;
|
|
Color := NF.Color;
|
|
EFColors.Error.Assign(NF.EFColors.Error);
|
|
EFColors.Highlight.Assign(NF.EFColors.Highlight);
|
|
Options := NF.Options;
|
|
PadChar := NF.PadChar;
|
|
PictureMask := NF.PictureMask;
|
|
RangeHi := NF.RangeHi;
|
|
RangeLo := NF.RangeLo;
|
|
TextMargin := NF.TextMargin;
|
|
Uninitialized := NF.Uninitialized;
|
|
ZeroDisplay := NF.ZeroDisplay;
|
|
ZeroDisplayValue := NF.ZeroDisplayValue;
|
|
end else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
constructor TOvcCustomNumericField.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
FNumericDataType := nftLongInt;
|
|
FPictureMask := 'iiiiiiiiiii';
|
|
efFieldClass := fcNumeric;
|
|
efDataType := nfGetDataType(FNumericDataType);
|
|
efRangeHi.rtLong := High(LongInt);
|
|
efRangeLo.rtLong := Low(LongInt);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
|
|
pfSelPos := 0;
|
|
|
|
{get current picture string}
|
|
StrPLCopy(efPicture, FPictureMask, MaxPicture);
|
|
|
|
{set MaxLength based on picture mask}
|
|
nfSetMaxLength(efPicture);
|
|
|
|
FillChar(nfTmp, SizeOf(nfTmp), #0);
|
|
pfSemiLits := 0;
|
|
pbCalcWidthAndPlaces(nfMaxLen, nfPlaces);
|
|
|
|
{adjust max length for decimal point if needed}
|
|
nfMaxDigits := nfMaxLen;
|
|
if nfPlaces <> 0 then
|
|
Dec(nfMaxDigits, nfPlaces+1);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.CreateWnd;
|
|
var
|
|
P : array[0..MaxEditLen+1] of Byte;
|
|
begin
|
|
{save field data}
|
|
if efSaveData then
|
|
efTransfer(@P, otf_GetData);
|
|
|
|
inherited CreateWnd;
|
|
|
|
{try to optimize InitPictureFlags}
|
|
pbOptimizeInitPictureFlags;
|
|
|
|
pfSemiLits := 0;
|
|
nfSetDefaultRanges;
|
|
efSetInitialValue;
|
|
|
|
{if we saved the field data, restore it}
|
|
if efSaveData then
|
|
efTransfer(@P, otf_SetData);
|
|
|
|
{set save data flag}
|
|
efSaveData := True;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efCaretToEnd;
|
|
{-move the caret to the end of the field}
|
|
begin
|
|
efHPos := efEditEnd + 1;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efCaretToStart;
|
|
{-move the caret to the beginning of the field}
|
|
begin
|
|
efHPos := efEditEnd + 1;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efChangeMask(Mask : PAnsiChar);
|
|
{-change the picture mask}
|
|
begin
|
|
inherited efChangeMask(Mask);
|
|
|
|
pfSemiLits := 0;
|
|
pbCalcWidthAndPlaces(nfMaxLen, nfPlaces);
|
|
|
|
{set MaxLength based on picture mask}
|
|
nfSetMaxLength(Mask);
|
|
nfMaxDigits := nfMaxLen;
|
|
if nfPlaces <> 0 then
|
|
Dec(nfMaxDigits, nfPlaces+1);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efEdit(var Msg : TMessage; Cmd : Word);
|
|
{-process the specified editing command}
|
|
label
|
|
ExitPoint;
|
|
var
|
|
MF : Byte;
|
|
Ch : AnsiChar;
|
|
HaveSel : Boolean;
|
|
PicChar : AnsiChar;
|
|
StLen : Word;
|
|
StBgn : Word;
|
|
StEnd : Word;
|
|
DotPos : Cardinal;
|
|
Found : Boolean;
|
|
|
|
function MinusVal : Byte;
|
|
begin
|
|
if nfMinus then
|
|
Result := 1
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure ClearString;
|
|
{-clear the string being edited}
|
|
begin
|
|
nfTmp[0] := #0;
|
|
nfMinus := False;
|
|
StLen := 0;
|
|
end;
|
|
|
|
function CharIsOK : Boolean;
|
|
{-return true if Ch can be added to the string}
|
|
begin
|
|
Result := (Ch >= ' ');
|
|
end;
|
|
|
|
function CheckAutoAdvance(SP : Integer) : Boolean;
|
|
{-see if we need to auto-advance to next/previous field}
|
|
begin
|
|
Result := False;
|
|
if (SP < 0) and
|
|
(efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
|
|
efMoveFocusToPrevField;
|
|
Result := True;
|
|
end else if (SP > 0) then
|
|
if (Cmd = ccChar) and
|
|
(efoAutoAdvanceChar in Controller.EntryOptions) then begin
|
|
efMoveFocusToNextField;
|
|
Result := True;
|
|
end else if (Cmd <> ccChar) and
|
|
(efoAutoAdvanceLeftRight in Controller.EntryOptions) then begin
|
|
efMoveFocusToNextField;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
procedure DeleteChar;
|
|
{-delete char at end of string}
|
|
begin
|
|
if (StLen = 0) then
|
|
if not nfMinus then
|
|
Exit
|
|
else
|
|
nfMinus := False
|
|
else begin
|
|
{remove the last character}
|
|
nfTmp[StLen-1] := #0;
|
|
Dec(StLen);
|
|
|
|
{if all that's left is a 0, remove it}
|
|
if (StLen = 1) and (nfTmp[0] = '0') then
|
|
nfTmp[0] := #0;
|
|
end;
|
|
MF := 10;
|
|
end;
|
|
|
|
procedure DeleteSel;
|
|
begin
|
|
ClearString;
|
|
efSelStart := 0;
|
|
efSelEnd := 0;
|
|
MF := 10;
|
|
end;
|
|
|
|
function InsertChar : Boolean;
|
|
{-insert Ch}
|
|
var
|
|
tDotPos : Cardinal;
|
|
tFound : Boolean;
|
|
|
|
function DigitCount : Word;
|
|
{-return number of digits to left of decimal place in St}
|
|
begin
|
|
if tFound then
|
|
Result := tDotPos + MinusVal
|
|
else
|
|
Result := StLen + MinusVal;
|
|
end;
|
|
|
|
begin
|
|
Result := False;
|
|
|
|
{reject spaces}
|
|
if (Ch = ' ') then
|
|
Exit;
|
|
|
|
{ok to add decimal point?}
|
|
tFound := StrChPos(nfTmp, pmDecimalPt, tDotPos);
|
|
if (Ch = pmDecimalPt) then
|
|
if not Found or tFound then
|
|
Exit;
|
|
|
|
if (Ch = '-') then begin
|
|
{minus sign treated as toggle}
|
|
if nfMinus then
|
|
nfMinus := False
|
|
else begin
|
|
nfMinus := (DigitCount < nfMaxDigits) and (StLen < nfMaxLen);
|
|
if not nfMinus then
|
|
Exit;
|
|
end
|
|
end else if (StLen+MinusVal < nfMaxLen) then begin
|
|
{don't allow initial zeros}
|
|
if (Ch = '0') and (StLen = 0) then begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
|
|
{check for too many digits to left of decimal point}
|
|
if Found and (Ch <> pmDecimalPt) then
|
|
if not tFound and (DigitCount >= nfMaxDigits) then
|
|
Exit;
|
|
|
|
{append the character}
|
|
nfTmp[StLen] := Ch;
|
|
Inc(StLen);
|
|
nfTmp[StLen] := #0;
|
|
end else if (nfMaxLen = 1) then
|
|
if (Ch = pmDecimalPt) then
|
|
Exit
|
|
else
|
|
{overwrite the character}
|
|
nfTmp[0] := Ch
|
|
else
|
|
Exit;
|
|
|
|
Result := True;
|
|
end;
|
|
|
|
procedure Adjust;
|
|
{-adjust display string to show correct number of decimal places}
|
|
var
|
|
Delta : Integer;
|
|
ActPlaces : Integer;
|
|
DP : Cardinal;
|
|
Len : Word;
|
|
ExDec : TEditString;
|
|
begin
|
|
Len := StrLen(nfTmp);
|
|
if not StrChPos(nfTmp, pmDecimalPt, DP) then
|
|
Delta := nfPlaces+1
|
|
else begin
|
|
ActPlaces := Len-Succ(DP);
|
|
Delta := nfPlaces-ActPlaces;
|
|
end;
|
|
|
|
if Delta = 0 then
|
|
Exit;
|
|
|
|
if Delta > 0 then begin
|
|
StrStDeletePrim(efEditSt, StEnd-Pred(Delta), Delta);
|
|
StrStInsertPrim(efEditSt, CharStrPChar(ExDec, ' ', Delta), StBgn);
|
|
end else begin
|
|
Delta := -Delta;
|
|
StrStCopy(ExDec, nfTmp, DP+nfPlaces+1, Delta);
|
|
StrStDeletePrim(efEditSt, StBgn, Delta);
|
|
StrStInsertPrim(efEditSt, ExDec, StEnd-Pred(Delta));
|
|
end;
|
|
end;
|
|
|
|
procedure UpdateEditSt;
|
|
{-update efEditSt}
|
|
begin
|
|
StrCopy(efEditSt, nfTmp);
|
|
case efEditSt[0] of
|
|
#0 :
|
|
begin
|
|
{string is empty, put in a 0}
|
|
efEditSt[0] := '0';
|
|
efEditSt[1] := #0;
|
|
end;
|
|
'.' :
|
|
StrChInsertPrim(efEditSt, '0', 0);
|
|
end;
|
|
|
|
{prepend the minus sign}
|
|
if nfMinus then
|
|
StrChInsertPrim(efEditSt, '-', 0);
|
|
|
|
pbMergePicture(efEditSt, efEditSt);
|
|
if Found then
|
|
Adjust;
|
|
end;
|
|
|
|
procedure UpdateSel(Delta : Integer);
|
|
begin
|
|
if Delta <> 0 then begin
|
|
efSelStart := 0;
|
|
efSelEnd := MaxEditLen;
|
|
end else begin
|
|
efSelStart := 0;
|
|
efSelEnd := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure PastePrim(P : PAnsiChar);
|
|
begin
|
|
if HaveSel then
|
|
DeleteSel;
|
|
while P^ <> #0 do begin
|
|
Ch := P^;
|
|
if (Ch = '(') then
|
|
if StrScan(efPicture, pmNegParens) <> nil then
|
|
if StrScan(P, ')') <> nil then
|
|
Ch := '-';
|
|
if (Ch <> '-') or not nfMinus then
|
|
if (StLen+MinusVal <= nfMaxLen) then begin
|
|
if Ch = IntlSupport.DecimalChar then
|
|
Ch := pmDecimalPt
|
|
else if Ch = pmDecimalPt then
|
|
Ch := #0;
|
|
if efCharOK(PicChar, Ch, #255, True) then
|
|
if InsertChar then
|
|
MF := 10
|
|
end;
|
|
Inc(P);
|
|
end;
|
|
end;
|
|
|
|
begin {edit}
|
|
HaveSel := efSelStart <> efSelEnd;
|
|
MF := Ord(HaveSel);
|
|
|
|
case Cmd of
|
|
ccAccept : ;
|
|
else
|
|
if not (sefFixSemiLits in sefOptions) then
|
|
pbRemoveSemiLits;
|
|
|
|
Exclude(sefOptions, sefLiteral);
|
|
end;
|
|
|
|
StBgn := efEditBegin;
|
|
StEnd := efEditEnd;
|
|
StLen := StrLen(nfTmp);
|
|
PicChar := efNthMaskChar(efHPos-1);
|
|
Found := StrChPos(efPicture, pmDecimalPt, DotPos);
|
|
|
|
Exclude(sefOptions, sefCharOK);
|
|
case Cmd of
|
|
ccChar :
|
|
begin
|
|
Ch := AnsiChar(Lo(Msg.wParam));
|
|
if not (sefAcceptChar in sefOptions) then
|
|
Exit
|
|
else begin
|
|
Exclude(sefOptions, sefAcceptChar);
|
|
if HaveSel and CharIsOk then
|
|
DeleteSel;
|
|
if StLen+MinusVal <= nfMaxLen then begin
|
|
if Ch = IntlSupport.DecimalChar then
|
|
Ch := pmDecimalPt
|
|
else if Ch = pmDecimalPt then
|
|
Ch := #0;
|
|
if not efCharOK(PicChar, Ch, #255, True) then
|
|
efConditionalBeep
|
|
else begin
|
|
if InsertChar then begin
|
|
if (Ch <> '-') and (StLen+MinusVal = nfMaxLen) then
|
|
CheckAutoAdvance(1);
|
|
MF := 10;
|
|
end else
|
|
efConditionalBeep;
|
|
end;
|
|
end else if not CheckAutoAdvance(1) then
|
|
efConditionalBeep;
|
|
end;
|
|
end;
|
|
ccLeft, ccWordLeft :
|
|
CheckAutoAdvance(-1);
|
|
ccRight, ccWordRight :
|
|
CheckAutoAdvance(1);
|
|
ccUp :
|
|
if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
|
|
efMoveFocusToPrevField
|
|
else if (efoArrowIncDec in Options) and
|
|
not (efoReadOnly in Options) then
|
|
IncreaseValue(True, 1)
|
|
else
|
|
CheckAutoAdvance(-1);
|
|
ccDown :
|
|
if (efoAutoAdvanceUpDown in Controller.EntryOptions) then
|
|
efMoveFocusToNextField
|
|
else if (efoArrowIncDec in Options) and not (efoReadOnly in Options) then
|
|
DecreaseValue(True, 1)
|
|
else
|
|
CheckAutoAdvance(1);
|
|
ccMouse :
|
|
begin
|
|
efSelStart := 0;
|
|
efSelEnd := 0;
|
|
end;
|
|
ccDblClk :
|
|
SetSelection(0, MaxEditLen);
|
|
ccHome, ccEnd : {do nothing};
|
|
ccBack, ccDel :
|
|
if HaveSel then
|
|
DeleteSel
|
|
else
|
|
DeleteChar;
|
|
ccDelWord :
|
|
if HaveSel then
|
|
DeleteSel;
|
|
ccExtendLeft :
|
|
UpdateSel(-1);
|
|
ccExtendRight :
|
|
UpdateSel(+1);
|
|
ccExtWordLeft, ccExtendHome :
|
|
UpdateSel(-MaxEditLen);
|
|
ccExtWordRight, ccExtendEnd :
|
|
UpdateSel(+MaxEditLen);
|
|
ccCut :
|
|
if HaveSel then
|
|
DeleteSel;
|
|
ccCopy : efCopyPrim;
|
|
ccPaste :
|
|
{for some reason, a paste action within the IDE}
|
|
{gets passed to the control. filter it out}
|
|
if not (csDesigning in ComponentState) then
|
|
PastePrim(PAnsiChar(Msg.lParam));
|
|
ccDelLine :
|
|
begin
|
|
ClearString;
|
|
MF := 10;
|
|
end;
|
|
ccIns :
|
|
begin
|
|
if sefInsert in sefOptions then
|
|
Exclude(sefOptions, sefInsert)
|
|
else
|
|
Include(sefOptions, sefInsert);
|
|
efCaret.InsertMode := (sefInsert in sefOptions);
|
|
end;
|
|
ccRestore :
|
|
begin
|
|
Restore;
|
|
nfReloadTmp;
|
|
end;
|
|
ccAccept :
|
|
begin
|
|
Include(sefOptions, sefCharOK);
|
|
Include(sefOptions, sefAcceptChar);
|
|
Exit;
|
|
end;
|
|
ccCtrlChar : {};
|
|
ccDec :
|
|
DecreaseValue(True, 1);
|
|
ccInc :
|
|
IncreaseValue(True, 1);
|
|
ccSuppress, ccPartial :
|
|
goto ExitPoint;
|
|
else
|
|
Include(sefOptions, sefCharOK);
|
|
end;
|
|
Exclude(sefOptions, sefAcceptChar);
|
|
|
|
case Cmd of
|
|
ccMouse : {};
|
|
ccRestore, ccDblClk,
|
|
ccExtendLeft, ccExtendRight, ccExtendEnd,
|
|
ccExtendHome, ccExtWordLeft, ccExtWordRight :
|
|
Inc(MF);
|
|
ccCut, ccCopy, ccPaste : {};
|
|
else
|
|
efSelStart := efHPos;
|
|
efSelEnd := efHPos;
|
|
end;
|
|
|
|
|
|
ExitPoint:
|
|
if MF >= 10 then begin
|
|
UpdateEditSt;
|
|
efFieldModified;
|
|
end;
|
|
if efPositionCaret(True) then
|
|
Inc(MF);
|
|
if MF > 0 then
|
|
Invalidate;
|
|
end;
|
|
|
|
function TOvcCustomNumericField.efGetDisplayString(Dest : PAnsiChar; Size : Word) : PAnsiChar;
|
|
{-return the display string in Dest and a pointer as the result}
|
|
var
|
|
I, J : Cardinal;
|
|
Found : Boolean;
|
|
begin
|
|
Result := inherited efGetDisplayString(Dest, Size);
|
|
|
|
if Uninitialized and not (sefHaveFocus in sefOptions) then
|
|
Exit;
|
|
|
|
Found := StrChPos(Dest, '-', I);
|
|
if StrChPos(efPicture, pmNegParens, J) then
|
|
if not Found then
|
|
Dest[J] := ' '
|
|
else begin
|
|
Dest[I] := '(';
|
|
Dest[J] := ')';
|
|
end;
|
|
|
|
if StrChPos(efPicture, pmNegHere, J) then
|
|
if not Found then
|
|
Dest[J] := ' '
|
|
else begin
|
|
Dest[J] := '-';
|
|
J := efEditBegin;
|
|
if J = I then
|
|
Dest[I] := ' '
|
|
else begin
|
|
StrChDeletePrim(Dest, I);
|
|
StrChInsertPrim(Dest, ' ', J);
|
|
end;
|
|
end;
|
|
|
|
TrimAllSpacesPChar(Dest);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efIncDecValue(Wrap : Boolean; Delta : Double);
|
|
{-increment field by Delta}
|
|
var
|
|
Code : Integer;
|
|
|
|
procedure IncDecValueLongInt;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if efStr2Long(S, L) then begin
|
|
if (Delta < 0) and (L <= efRangeLo.rtLong) then
|
|
if Wrap then
|
|
L := efRangeHi.rtLong
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (L >= efRangeHi.rtLong) then
|
|
if Wrap then
|
|
L := efRangeLo.rtLong
|
|
else
|
|
Exit
|
|
else
|
|
Inc(L, Trunc(Delta));
|
|
|
|
{insure valid value}
|
|
if L < efRangeLo.rtLong then
|
|
L := efRangeLo.rtLong;
|
|
if L > efRangeHi.rtLong then
|
|
L := efRangeHi.rtLong;
|
|
|
|
efTransfer(@L, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
procedure IncDecValueReal;
|
|
var
|
|
Re : Real;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, Re, Code);
|
|
{$ELSE}
|
|
Val(string(S), Re, Code);
|
|
{$ENDIF}
|
|
|
|
if Code = 0 then begin
|
|
if (Delta < 0) and (Re <= efRangeLo.rtReal) then
|
|
if Wrap then
|
|
Re := efRangeHi.rtReal
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (Re >= efRangeHi.rtReal) then
|
|
if Wrap then
|
|
Re := efRangeLo.rtReal
|
|
else
|
|
Exit
|
|
else
|
|
Re := Re + Delta;
|
|
|
|
{insure valid value}
|
|
if Re < efRangeLo.rtReal then
|
|
Re := efRangeLo.rtReal;
|
|
if Re > efRangeHi.rtReal then
|
|
Re := efRangeHi.rtReal;
|
|
|
|
efTransfer(@Re, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
procedure IncDecValueExtended;
|
|
var
|
|
Ex : Extended;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, Ex, Code);
|
|
{$ELSE}
|
|
Val(string(S), Ex, Code);
|
|
{$ENDIF}
|
|
|
|
if Code = 0 then begin
|
|
if (Delta < 0) and (Ex <= efRangeLo.rtExt) then
|
|
if Wrap then
|
|
Ex := efRangeHi.rtExt
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (Ex >= efRangeHi.rtExt) then
|
|
if Wrap then
|
|
Ex := efRangeLo.rtExt
|
|
else
|
|
Exit
|
|
else
|
|
Ex := Ex + Delta;
|
|
|
|
{insure valid value}
|
|
if Ex < efRangeLo.rtExt then
|
|
Ex := efRangeLo.rtExt;
|
|
if Ex > efRangeHi.rtExt then
|
|
Ex := efRangeHi.rtExt;
|
|
|
|
efTransfer(@Ex, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
procedure IncDecValueDouble;
|
|
var
|
|
Db : Double;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, Db, Code);
|
|
{$ELSE}
|
|
Val(string(S), Db, Code);
|
|
{$ENDIF}
|
|
|
|
if Code = 0 then begin
|
|
if (Delta < 0) and (Db <= efRangeLo.rtExt) then
|
|
if Wrap then
|
|
Db := efRangeHi.rtExt
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (Db >= efRangeHi.rtExt) then
|
|
if Wrap then
|
|
Db := efRangeLo.rtExt
|
|
else
|
|
Exit
|
|
else
|
|
Db := Db + Delta;
|
|
|
|
{insure valid value}
|
|
if Db < efRangeLo.rtExt then
|
|
Db := efRangeLo.rtExt;
|
|
if Db > efRangeHi.rtExt then
|
|
Db := efRangeHi.rtExt;
|
|
|
|
efTransfer(@Db, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
procedure IncDecValueSingle;
|
|
var
|
|
Si : Single;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, Si, Code);
|
|
{$ELSE}
|
|
Val(string(S), Si, Code);
|
|
{$ENDIF}
|
|
|
|
if Code = 0 then begin
|
|
if (Delta < 0) and (Si <= efRangeLo.rtExt) then
|
|
if Wrap then
|
|
Si := efRangeHi.rtExt
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (Si >= efRangeHi.rtExt) then
|
|
if Wrap then
|
|
Si := efRangeLo.rtExt
|
|
else
|
|
Exit
|
|
else
|
|
Si := Si + Delta;
|
|
|
|
{insure valid value}
|
|
if Si < efRangeLo.rtExt then
|
|
Si := efRangeLo.rtExt;
|
|
if Si > efRangeHi.rtExt then
|
|
Si := efRangeHi.rtExt;
|
|
|
|
efTransfer(@Si, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
procedure IncDecValueComp;
|
|
var
|
|
{$IFNDEF FPC}
|
|
Co : Comp;
|
|
{$ELSE}
|
|
{$IFDEF CPU86}
|
|
Co : Comp;
|
|
{$ELSE}
|
|
Co : Double;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, Co, Code);
|
|
{$ELSE}
|
|
Val(string(S), Co, Code);
|
|
{$ENDIF}
|
|
|
|
if Code = 0 then begin
|
|
if (Delta < 0) and (Co <= efRangeLo.rtExt) then
|
|
if Wrap then
|
|
Co := efRangeHi.rtExt
|
|
else
|
|
Exit
|
|
else if (Delta > 0) and (Co >= efRangeHi.rtExt) then
|
|
if Wrap then
|
|
Co := efRangeLo.rtExt
|
|
else
|
|
Exit
|
|
else
|
|
Co := Co + Delta;
|
|
|
|
{insure valid value}
|
|
if Co < efRangeLo.rtExt then
|
|
Co := efRangeLo.rtExt;
|
|
if Co > efRangeHi.rtExt then
|
|
Co := efRangeHi.rtExt;
|
|
|
|
efTransfer(@Co, otf_SetData);
|
|
nfReloadTmp;
|
|
efPerformRepaint(True);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if not (sefHaveFocus in sefOptions) then
|
|
Exit;
|
|
|
|
case FNumericDataType of
|
|
nftLongInt,
|
|
nftWord,
|
|
nftInteger,
|
|
nftByte,
|
|
nftShortInt : IncDecValueLongInt;
|
|
nftReal : IncDecValueReal;
|
|
nftExtended : IncDecValueExtended;
|
|
nftDouble : IncDecValueDouble;
|
|
nftSingle : IncDecValueSingle;
|
|
nftComp : IncDecValueComp;
|
|
end;
|
|
efPositionCaret(False);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.efSetCaretPos(Value : Integer);
|
|
{-set position of caret within the field}
|
|
begin
|
|
{do nothing}
|
|
end;
|
|
|
|
function TOvcCustomNumericField.efTransfer(DataPtr : Pointer; TransferFlag : Word) : Word;
|
|
{-transfer data to/from the entry fields}
|
|
var
|
|
E : Extended;
|
|
|
|
procedure TransferLongInt;
|
|
var
|
|
S : TEditString;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, LongInt(DataPtr^)) then
|
|
LongInt(DataPtr^) := 0;
|
|
end else begin
|
|
efLong2Str(S, LongInt(DataPtr^));
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferWord;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if efStr2Long(S, L) then
|
|
Word(DataPtr^) := L
|
|
else
|
|
Word(DataPtr^) := 0;
|
|
end else begin
|
|
efLong2Str(S, Word(DataPtr^));
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferInteger;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if efStr2Long(S, L) then
|
|
SmallInt(DataPtr^) := L
|
|
else
|
|
SmallInt(DataPtr^) := 0;
|
|
end else begin
|
|
efLong2Str(S, SmallInt(DataPtr^));
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferByte;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if efStr2Long(S, L) then
|
|
Byte(DataPtr^) := L
|
|
else
|
|
Byte(DataPtr^) := 0;
|
|
end else begin
|
|
efLong2Str(S, Byte(DataPtr^));
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferShortInt;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if efStr2Long(S, L) then
|
|
ShortInt(DataPtr^) := L
|
|
else
|
|
ShortInt(DataPtr^) := 0;
|
|
end else begin
|
|
efLong2Str(S, ShortInt(DataPtr^));
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferReal;
|
|
var
|
|
Code : Integer;
|
|
Places : Word;
|
|
R : Real;
|
|
S : TEditString;
|
|
Width : Word;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, R, Code);
|
|
{$ELSE}
|
|
Val(string(S), R, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
R := 0;
|
|
Real(DataPtr^) := R;
|
|
end else begin
|
|
pbCalcWidthAndPlaces(Width, Places);
|
|
Str(Real(DataPtr^):Width:Places, S);
|
|
if DecimalPlaces <> 0 then
|
|
TrimTrailingZerosPChar(S)
|
|
else
|
|
TrimAllSpacesPChar(S);
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferExtended;
|
|
var
|
|
Code : Integer;
|
|
Places : Word;
|
|
S : TEditString;
|
|
Width : Word;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, E, Code);
|
|
{$ELSE}
|
|
Val(string(S), E, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
E := 0;
|
|
Extended(DataPtr^) := E;
|
|
end else begin
|
|
pbCalcWidthAndPlaces(Width, Places);
|
|
Str(Extended(DataPtr^):Width:Places, S);
|
|
if DecimalPlaces <> 0 then
|
|
TrimTrailingZerosPChar(S)
|
|
else
|
|
TrimAllSpacesPChar(S);
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferDouble;
|
|
var
|
|
D : Double;
|
|
Code : Integer;
|
|
Places : Word;
|
|
S : TEditString;
|
|
Width : Word;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, D, Code);
|
|
{$ELSE}
|
|
Val(string(S), D, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
D := 0;
|
|
Double(DataPtr^) := D;
|
|
end else begin
|
|
pbCalcWidthAndPlaces(Width, Places);
|
|
Str(Double(DataPtr^):Width:Places, S);
|
|
if DecimalPlaces <> 0 then
|
|
TrimTrailingZerosPChar(S)
|
|
else
|
|
TrimAllSpacesPChar(S);
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferSingle;
|
|
var
|
|
Code : Integer;
|
|
G : Single;
|
|
Places : Word;
|
|
S : TEditString;
|
|
Width : Word;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, G, Code);
|
|
{$ELSE}
|
|
Val(string(S), G, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
G := 0;
|
|
Single(DataPtr^) := G;
|
|
end else begin
|
|
pbCalcWidthAndPlaces(Width, Places);
|
|
Str(Single(DataPtr^):Width:Places, S);
|
|
if DecimalPlaces <> 0 then
|
|
TrimTrailingZerosPChar(S)
|
|
else
|
|
TrimAllSpacesPChar(S);
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
procedure TransferComp;
|
|
var
|
|
{$IFNDEF FPC}
|
|
C : Comp;
|
|
{$ELSE}
|
|
{$IFDEF CPU86}
|
|
C : Comp;
|
|
{$ELSE}
|
|
C : Double;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
Code : Integer;
|
|
Places : Word;
|
|
S : TEditString;
|
|
Width : Word;
|
|
begin
|
|
if TransferFlag = otf_GetData then begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, C, Code);
|
|
{$ELSE}
|
|
Val(string(S), C, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
C := 0;
|
|
{$IFNDEF FPC}
|
|
Comp(DataPtr^) := C;
|
|
{$ELSE}
|
|
{$IFDEF CPU86}
|
|
Comp(DataPtr^) := C;
|
|
{$ELSE}
|
|
Double(DataPtr^) := C;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end else begin
|
|
pbCalcWidthAndPlaces(Width, Places);
|
|
{$IFNDEF FPC}
|
|
Str(Comp(DataPtr^):Width:Places, S);
|
|
{$ELSE}
|
|
{$IFDEF CPU86}
|
|
Str(Comp(DataPtr^):Width:Places, S);
|
|
{$ELSE}
|
|
Str(Double(DataPtr^):Width:Places, S);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
if DecimalPlaces <> 0 then
|
|
TrimTrailingZerosPChar(S)
|
|
else
|
|
TrimAllSpacesPChar(S);
|
|
pbMergePicture(efEditSt, S);
|
|
end;
|
|
end;
|
|
|
|
begin {transfer}
|
|
if DataPtr = nil then begin
|
|
Result := 0;
|
|
Exit;
|
|
end;
|
|
|
|
case FNumericDataType of
|
|
nftLongInt : TransferLongInt;
|
|
nftWord : TransferWord;
|
|
nftInteger : TransferInteger;
|
|
nftByte : TransferByte;
|
|
nftShortInt : TransferShortInt;
|
|
nftReal : TransferReal;
|
|
nftExtended : TransferExtended;
|
|
nftDouble : TransferDouble;
|
|
nftSingle : TransferSingle;
|
|
nftComp : TransferComp;
|
|
end;
|
|
Result := inherited efTransfer(DataPtr, TransferFlag);
|
|
end;
|
|
|
|
function TOvcCustomNumericField.efValidateField : Word;
|
|
{-validate contents of field; result is error code or 0}
|
|
|
|
procedure ValidateLongInt;
|
|
var
|
|
L : LongInt;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, L) then
|
|
Result := oeInvalidNumber
|
|
else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
efTransfer(@L, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateWord;
|
|
var
|
|
L : LongInt;
|
|
W : Word;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, L) then
|
|
Result := oeInvalidNumber
|
|
else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
W := L;
|
|
efTransfer(@W, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateInteger;
|
|
var
|
|
L : LongInt;
|
|
I : Integer;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, L) then
|
|
Result := oeInvalidNumber
|
|
else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
I := L;
|
|
efTransfer(@I, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateByte;
|
|
var
|
|
L : LongInt;
|
|
B : Byte;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, L) then
|
|
Result := oeInvalidNumber
|
|
else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
B := L;
|
|
efTransfer(@B, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateShortInt;
|
|
var
|
|
L : LongInt;
|
|
Si : Byte;
|
|
S : TEditString;
|
|
begin
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
if not efStr2Long(S, L) then
|
|
Result := oeInvalidNumber
|
|
else if (L < efRangeLo.rtLong) or (L > efRangeHi.rtLong) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
Si := L;
|
|
efTransfer(@Si, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateReal;
|
|
var
|
|
R : Real;
|
|
Code : Integer;
|
|
S : TEditString;
|
|
begin
|
|
{convert efEditSt to a real}
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, R, Code);
|
|
{$ELSE}
|
|
Val(string(S), R, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
Result := oeInvalidNumber
|
|
else if (R < efRangeLo.rtReal) or (R > efRangeHi.rtReal) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
efTransfer(@R, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateExtended;
|
|
var
|
|
E : Extended;
|
|
Code : Integer;
|
|
S : TEditString;
|
|
begin
|
|
{convert efEditSt to an extended}
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, E, Code);
|
|
{$ELSE}
|
|
Val(string(S), E, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
Result := oeInvalidNumber
|
|
else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
efTransfer(@E, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateDouble;
|
|
var
|
|
E : Extended;
|
|
D : Double;
|
|
Code : Integer;
|
|
S : TEditString;
|
|
begin
|
|
{convert efEditSt to an extended}
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, E, Code);
|
|
{$ELSE}
|
|
Val(string(S), E, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
Result := oeInvalidNumber
|
|
else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
D := E;
|
|
efTransfer(@D, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateSingle;
|
|
var
|
|
E : Extended;
|
|
Si : Single;
|
|
Code : Integer;
|
|
S : TEditString;
|
|
begin
|
|
{convert efEditSt to an extended}
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, E, Code);
|
|
{$ELSE}
|
|
Val(string(S), E, Code);
|
|
{$ENDIF}
|
|
|
|
if Code <> 0 then
|
|
Result := oeInvalidNumber
|
|
else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
Si := E;
|
|
efTransfer(@Si, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ValidateComp;
|
|
var
|
|
E : Extended;
|
|
{$IFNDEF FPC}
|
|
C : Comp;
|
|
{$ELSE}
|
|
{$IFDEF CPU86}
|
|
C : Comp;
|
|
{$ELSE}
|
|
C : Double;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
Code : Integer;
|
|
S : TEditString;
|
|
begin
|
|
{convert efEditSt to an comp}
|
|
pbStripPicture(S, efEditSt);
|
|
|
|
FixRealPrim(S, IntlSupport.DecimalChar);
|
|
{$IFNDEF FPC}
|
|
Val(S, C, Code);
|
|
{$ELSE}
|
|
Val(string(S), C, Code);
|
|
{$ENDIF}
|
|
|
|
E := C;
|
|
if Code <> 0 then
|
|
Result := oeInvalidNumber
|
|
else if (E < efRangeLo.rtExt) or (E > efRangeHi.rtExt) then
|
|
Result := oeRangeError
|
|
else begin
|
|
if sefHaveFocus in sefOptions then
|
|
if not (sefGettingValue in sefOptions) then begin
|
|
efTransfer(@C, otf_SetData);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin {validate}
|
|
Result := 0;
|
|
case FNumericDataType of
|
|
nftLongInt : ValidateLongInt;
|
|
nftWord : ValidateWord;
|
|
nftInteger : ValidateInteger;
|
|
nftByte : ValidateByte;
|
|
nftShortInt : ValidateShortInt;
|
|
nftReal : ValidateReal;
|
|
nftExtended : ValidateExtended;
|
|
nftDouble : ValidateDouble;
|
|
nftSingle : ValidateSingle;
|
|
nftComp : ValidateComp;
|
|
end;
|
|
|
|
if not (sefUserValidating in sefOptions) then begin
|
|
{user may retrieve data from field. flag that we are doing}
|
|
{user validation to avoid calling this routine recursively}
|
|
Include(sefOptions, sefUserValidating);
|
|
DoOnUserValidation(Result);
|
|
Exclude(sefOptions, sefUserValidating);
|
|
end;
|
|
end;
|
|
|
|
function TOvcCustomNumericField.nfGetDataType(Value: TNumericDataType) : Byte;
|
|
{-return a Byte value representing the type of this field}
|
|
begin
|
|
case Value of
|
|
nftLongInt : Result := fidNumericLongInt;
|
|
nftWord : Result := fidNumericWord;
|
|
nftInteger : Result := fidNumericInteger;
|
|
nftByte : Result := fidNumericByte;
|
|
nftShortInt : Result := fidNumericShortInt;
|
|
nftReal : Result := fidNumericReal;
|
|
nftExtended : Result := fidNumericExtended;
|
|
nftDouble : Result := fidNumericDouble;
|
|
nftSingle : Result := fidNumericSingle;
|
|
nftComp : Result := fidNumericComp;
|
|
else
|
|
raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfReloadTmp;
|
|
{-reload Tmp from efEditSt, etc.}
|
|
begin
|
|
{load nfTmp}
|
|
pbStripPicture(nfTmp, efEditSt);
|
|
|
|
TrimAllSpacesPChar(nfTmp);
|
|
|
|
{remove the minus sign if there is one}
|
|
nfMinus := (nfTmp[0] = '-');
|
|
if nfMinus then
|
|
StrChDeletePrim(nfTmp, 0);
|
|
|
|
{want a blank string if it's a zero}
|
|
if (nfTmp[0] = '0') and (nfTmp[1] = #0) then
|
|
nfTmp[0] := #0;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfResetFieldProperties(FT: TNumericDataType);
|
|
{-reset field properties}
|
|
begin
|
|
DecimalPlaces := 0;
|
|
case FT of
|
|
nftLongInt : PictureMask := 'iiiiiiiiiii';
|
|
nftWord : PictureMask := '99999';
|
|
nftInteger : PictureMask := 'iiiiii';
|
|
nftByte : PictureMask := '999';
|
|
nftShortInt : PictureMask := 'iiii';
|
|
nftReal : PictureMask := '##########';
|
|
nftExtended : PictureMask := '##########';
|
|
nftDouble : PictureMask := '##########';
|
|
nftSingle : PictureMask := '##########';
|
|
nftComp : PictureMask := 'iiiiiiiiii';
|
|
else
|
|
raise EOvcException.Create(GetOrphStr(SCInvalidParamValue));
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfSetDataType(Value: TNumericDataType);
|
|
{-set the data type for this field}
|
|
begin
|
|
if FNumericDataType <> Value then begin
|
|
FNumericDataType := Value;
|
|
efDataType := nfGetDataType(FNumericDataType);
|
|
efSetDefaultRange(efDataType);
|
|
|
|
{set defaults for this field type}
|
|
nfResetFieldProperties(FNumericDataType);
|
|
if HandleAllocated then begin
|
|
{don't save data through create window}
|
|
efSaveData := False;
|
|
{$IFNDEF LCL}
|
|
RecreateWnd;
|
|
{$ELSE}
|
|
MyMisc.RecreateWnd(Self);
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfSetDefaultRanges;
|
|
{-set default range values based on the field type}
|
|
begin
|
|
case FNumericDataType of
|
|
nftLongInt, nftWord, nftInteger, nftByte, nftShortInt :
|
|
if efRangeLo.rtLong = efRangeHi.rtLong then
|
|
efSetDefaultRange(efDataType);
|
|
nftReal :
|
|
if efRangeLo.rtReal = efRangeHi.rtReal then
|
|
efSetDefaultRange(efDataType);
|
|
nftExtended, nftDouble, nftSingle, nftComp :
|
|
if efRangeLo.rtExt = efRangeHi.rtExt then
|
|
efSetDefaultRange(efDataType);
|
|
else
|
|
efSetDefaultRange(efDataType);
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfSetMaxLength(Mask : PChar);
|
|
{-determine and set MaxLength}
|
|
var
|
|
C : Cardinal;
|
|
begin
|
|
FMaxLength := StrLen(Mask);
|
|
|
|
{decrease this if Mask has special characters that}
|
|
{should not be considered part of the display string}
|
|
if StrChPos(Mask, pmNegParens, C) then
|
|
Dec(FMaxLength);
|
|
if StrChPos(Mask, pmNegHere, C) then
|
|
Dec(FMaxLength);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.nfSetPictureMask(const Value: string);
|
|
{-set the picture mask}
|
|
var
|
|
Buf : TPictureMask;
|
|
begin
|
|
if (FPictureMask <> Value) and (Value <> '') then begin
|
|
|
|
{test for blatantly invalid masks}
|
|
if csDesigning in ComponentState then begin
|
|
{check for masks like "999.99" or "iii.ii" in fields editing floating data types}
|
|
if (efDataType mod fcpDivisor) in [fsubReal, fsubExtended, fsubDouble, fsubSingle] then
|
|
if (Pos(pmDecimalPt, Value) > 0) and
|
|
((Pos(pmPositive, Value) > 0) or (Pos(pmWhole, Value) > 0)) then
|
|
raise EInvalidPictureMask.Create(Value);
|
|
end;
|
|
|
|
FPictureMask := Value;
|
|
if csDesigning in ComponentState then begin
|
|
StrPLCopy(efPicture, FPictureMask, MaxPicture);
|
|
efPicLen := StrLen(efPicture);
|
|
{set MaxLength based on picture mask}
|
|
nfSetMaxLength(efPicture);
|
|
pbOptimizeInitPictureFlags;
|
|
efInitializeDataSize;
|
|
Repaint;
|
|
end else begin
|
|
StrPLCopy(Buf, FPictureMask, MaxPicture);
|
|
efChangeMask(Buf);
|
|
{$IFNDEF LCL}
|
|
RecreateWnd;
|
|
{$ELSE}
|
|
MyMisc.RecreateWnd(Self);
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.pbRemoveSemiLits;
|
|
{-remove semi-literal mask characters from the edit string}
|
|
begin
|
|
if (sefHexadecimal in sefOptions) or (sefOctal in sefOptions) or
|
|
(sefBinary in sefOptions) then
|
|
Include(sefOptions, sefFixSemiLits)
|
|
else
|
|
Exclude(sefOptions, sefFixSemiLits);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.WMKillFocus(var Msg : TWMKillFocus);
|
|
begin
|
|
inherited;
|
|
|
|
{are we giving up the focus?}
|
|
if not (sefRetainPos in sefOptions) then
|
|
FillChar(nfTmp, SizeOf(nfTmp), #0);
|
|
end;
|
|
|
|
procedure TOvcCustomNumericField.WMSetFocus(var Msg : TWMSetFocus);
|
|
begin
|
|
inherited;
|
|
nfReloadTmp;
|
|
efResetCaret;
|
|
end;
|
|
|
|
|
|
end.
|