RXSpin.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:31k
- {*******************************************************}
- { }
- { Delphi VCL Extensions (RX) }
- { }
- { Copyright (c) 1995 AO ROSNO }
- { Copyright (c) 1997, 1998 Master-Bank }
- { }
- {*******************************************************}
- unit RXSpin;
- interface
- {$I RX.INC}
- uses {$IFDEF WIN32} Windows, ComCtrls, {$ELSE} WinTypes, WinProcs, {$ENDIF}
- Controls, ExtCtrls, Classes, Graphics, Messages, Forms, StdCtrls, Menus,
- SysUtils;
- type
- { TRxSpinButton }
- TSpinButtonState = (sbNotDown, sbTopDown, sbBottomDown);
- TRxSpinButton = class(TGraphicControl)
- private
- FDown: TSpinButtonState;
- FUpBitmap: TBitmap;
- FDownBitmap: TBitmap;
- FDragging: Boolean;
- FInvalidate: Boolean;
- FTopDownBtn: TBitmap;
- FBottomDownBtn: TBitmap;
- FRepeatTimer: TTimer;
- FNotDownBtn: TBitmap;
- FLastDown: TSpinButtonState;
- FFocusControl: TWinControl;
- FOnTopClick: TNotifyEvent;
- FOnBottomClick: TNotifyEvent;
- procedure TopClick;
- procedure BottomClick;
- procedure GlyphChanged(Sender: TObject);
- function GetUpGlyph: TBitmap;
- function GetDownGlyph: TBitmap;
- procedure SetUpGlyph(Value: TBitmap);
- procedure SetDownGlyph(Value: TBitmap);
- procedure SetDown(Value: TSpinButtonState);
- procedure SetFocusControl(Value: TWinControl);
- procedure DrawAllBitmap;
- procedure DrawBitmap(ABitmap: TBitmap; ADownState: TSpinButtonState);
- procedure TimerExpired(Sender: TObject);
- procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
- protected
- procedure Paint; override;
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer); override;
- procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
- procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer); override;
- procedure Notification(AComponent: TComponent;
- Operation: TOperation); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property Down: TSpinButtonState read FDown write SetDown default sbNotDown;
- published
- property DragCursor;
- property DragMode;
- property Enabled;
- property Visible;
- property DownGlyph: TBitmap read GetDownGlyph write SetDownGlyph;
- property UpGlyph: TBitmap read GetUpGlyph write SetUpGlyph;
- property FocusControl: TWinControl read FFocusControl write SetFocusControl;
- property ShowHint;
- property ParentShowHint;
- {$IFDEF RX_D4}
- property Anchors;
- property Constraints;
- property DragKind;
- {$ENDIF}
- property OnBottomClick: TNotifyEvent read FOnBottomClick write FOnBottomClick;
- property OnTopClick: TNotifyEvent read FOnTopClick write FOnTopClick;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- {$IFDEF WIN32}
- property OnStartDrag;
- {$ENDIF}
- {$IFDEF RX_D4}
- property OnEndDock;
- property OnStartDock;
- {$ENDIF}
- end;
- { TRxSpinEdit }
- {$IFDEF CBUILDER}
- TValueType = (vtInt, vtFloat, vtHex);
- {$ELSE}
- TValueType = (vtInteger, vtFloat, vtHex);
- {$ENDIF}
- {$IFDEF WIN32}
- TSpinButtonKind = (bkStandard, bkDiagonal);
- {$ENDIF}
- TRxSpinEdit = class(TCustomEdit)
- private
- FAlignment: TAlignment;
- FMinValue: Extended;
- FMaxValue: Extended;
- FIncrement: Extended;
- FDecimal: Byte;
- FChanging: Boolean;
- FEditorEnabled: Boolean;
- FValueType: TValueType;
- FButton: TRxSpinButton;
- FBtnWindow: TWinControl;
- FArrowKeys: Boolean;
- FOnTopClick: TNotifyEvent;
- FOnBottomClick: TNotifyEvent;
- {$IFDEF WIN32}
- FButtonKind: TSpinButtonKind;
- FUpDown: TCustomUpDown;
- function GetButtonKind: TSpinButtonKind;
- procedure SetButtonKind(Value: TSpinButtonKind);
- procedure UpDownClick(Sender: TObject; Button: TUDBtnType);
- {$ENDIF}
- function GetMinHeight: Integer;
- procedure GetTextHeight(var SysHeight, Height: Integer);
- function GetValue: Extended;
- function CheckValue(NewValue: Extended): Extended;
- function GetAsInteger: Longint;
- function IsIncrementStored: Boolean;
- function IsMaxStored: Boolean;
- function IsMinStored: Boolean;
- function IsValueStored: Boolean;
- procedure SetArrowKeys(Value: Boolean);
- procedure SetAsInteger(NewValue: Longint);
- procedure SetValue(NewValue: Extended);
- procedure SetValueType(NewType: TValueType);
- procedure SetDecimal(NewValue: Byte);
- function GetButtonWidth: Integer;
- procedure RecreateButton;
- procedure ResizeButton;
- procedure SetEditRect;
- procedure SetAlignment(Value: TAlignment);
- procedure WMSize(var Message: TWMSize); message WM_SIZE;
- procedure CMEnter(var Message: TMessage); message CM_ENTER;
- procedure CMExit(var Message: TCMExit); message CM_EXIT;
- procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
- procedure WMCut(var Message: TWMCut); message WM_CUT;
- procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
- procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
- procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
- {$IFDEF RX_D4}
- procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
- {$ENDIF}
- protected
- procedure Change; override;
- function IsValidChar(Key: Char): Boolean; virtual;
- procedure UpClick(Sender: TObject); virtual;
- procedure DownClick(Sender: TObject); virtual;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure KeyPress(var Key: Char); override;
- procedure CreateParams(var Params: TCreateParams); override;
- procedure CreateWnd; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property AsInteger: Longint read GetAsInteger write SetAsInteger default 0;
- property Text;
- published
- property Alignment: TAlignment read FAlignment write SetAlignment
- default taLeftJustify;
- property ArrowKeys: Boolean read FArrowKeys write SetArrowKeys default True;
- {$IFDEF WIN32}
- property ButtonKind: TSpinButtonKind read FButtonKind write SetButtonKind
- default bkDiagonal;
- {$ENDIF}
- property Decimal: Byte read FDecimal write SetDecimal default 2;
- property EditorEnabled: Boolean read FEditorEnabled write FEditorEnabled default True;
- property Increment: Extended read FIncrement write FIncrement stored IsIncrementStored;
- property MaxValue: Extended read FMaxValue write FMaxValue stored IsMaxStored;
- property MinValue: Extended read FMinValue write FMinValue stored IsMinStored;
- property ValueType: TValueType read FValueType write SetValueType
- default {$IFDEF CBUILDER} vtInt {$ELSE} vtInteger {$ENDIF};
- property Value: Extended read GetValue write SetValue stored IsValueStored;
- property AutoSelect;
- property AutoSize;
- property BorderStyle;
- property Color;
- property Ctl3D;
- property DragCursor;
- property DragMode;
- property Enabled;
- property Font;
- {$IFDEF RX_D4}
- property Anchors;
- property BiDiMode;
- property Constraints;
- property DragKind;
- property ParentBiDiMode;
- {$ENDIF}
- {$IFDEF WIN32}
- {$IFNDEF VER90}
- property ImeMode;
- property ImeName;
- {$ENDIF}
- {$ENDIF}
- property MaxLength;
- property ParentColor;
- property ParentCtl3D;
- property ParentFont;
- property ParentShowHint;
- property PopupMenu;
- property ReadOnly;
- property ShowHint;
- property TabOrder;
- property TabStop;
- property Visible;
- property OnBottomClick: TNotifyEvent read FOnBottomClick write FOnBottomClick;
- property OnTopClick: TNotifyEvent read FOnTopClick write FOnTopClick;
- 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;
- {$IFDEF WIN32}
- property OnStartDrag;
- {$ENDIF}
- {$IFDEF RX_D5}
- property OnContextPopup;
- {$ENDIF}
- {$IFDEF RX_D4}
- property OnMouseWheelDown;
- property OnMouseWheelUp;
- property OnEndDock;
- property OnStartDock;
- {$ENDIF}
- end;
- implementation
- uses {$IFDEF WIN32} CommCtrl, {$ENDIF} VCLUtils;
- {$IFDEF WIN32}
- {$R *.R32}
- {$ELSE}
- {$R *.R16}
- {$ENDIF}
- const
- sSpinUpBtn = 'RXSPINUP';
- sSpinDownBtn = 'RXSPINDOWN';
- const
- InitRepeatPause = 400; { pause before repeat timer (ms) }
- RepeatPause = 100;
- { TRxSpinButton }
- constructor TRxSpinButton.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FUpBitmap := TBitmap.Create;
- FDownBitmap := TBitmap.Create;
- FUpBitmap.Handle := LoadBitmap(HInstance, sSpinUpBtn);
- FDownBitmap.Handle := LoadBitmap(HInstance, sSpinDownBtn);
- FUpBitmap.OnChange := GlyphChanged;
- FDownBitmap.OnChange := GlyphChanged;
- Height := 20;
- Width := 20;
- FTopDownBtn := TBitmap.Create;
- FBottomDownBtn := TBitmap.Create;
- FNotDownBtn := TBitmap.Create;
- DrawAllBitmap;
- FLastDown := sbNotDown;
- end;
- destructor TRxSpinButton.Destroy;
- begin
- FTopDownBtn.Free;
- FBottomDownBtn.Free;
- FNotDownBtn.Free;
- FUpBitmap.Free;
- FDownBitmap.Free;
- FRepeatTimer.Free;
- inherited Destroy;
- end;
- procedure TRxSpinButton.GlyphChanged(Sender: TObject);
- begin
- FInvalidate := True;
- Invalidate;
- end;
- function TRxSpinButton.GetUpGlyph: TBitmap;
- begin
- Result := FUpBitmap;
- end;
- procedure TRxSpinButton.SetUpGlyph(Value: TBitmap);
- begin
- if Value <> nil then FUpBitmap.Assign(Value)
- else FUpBitmap.Handle := LoadBitmap(HInstance, sSpinUpBtn);
- end;
- function TRxSpinButton.GetDownGlyph: TBitmap;
- begin
- Result := FDownBitmap;
- end;
- procedure TRxSpinButton.SetDownGlyph(Value: TBitmap);
- begin
- if Value <> nil then FDownBitmap.Assign(Value)
- else FDownBitmap.Handle := LoadBitmap(HInstance, sSpinDownBtn);
- end;
- procedure TRxSpinButton.SetDown(Value: TSpinButtonState);
- var
- OldState: TSpinButtonState;
- begin
- OldState := FDown;
- FDown := Value;
- if OldState <> FDown then Repaint;
- end;
- procedure TRxSpinButton.SetFocusControl(Value: TWinControl);
- begin
- FFocusControl := Value;
- {$IFDEF WIN32}
- if Value <> nil then Value.FreeNotification(Self);
- {$ENDIF}
- end;
- procedure TRxSpinButton.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if (Operation = opRemove) and (AComponent = FFocusControl) then
- FFocusControl := nil;
- end;
- procedure TRxSpinButton.Paint;
- begin
- if not Enabled and not (csDesigning in ComponentState) then
- FDragging := False;
- if (FNotDownBtn.Height <> Height) or (FNotDownBtn.Width <> Width) or
- FInvalidate then DrawAllBitmap;
- FInvalidate := False;
- with Canvas do
- case FDown of
- sbNotDown: Draw(0, 0, FNotDownBtn);
- sbTopDown: Draw(0, 0, FTopDownBtn);
- sbBottomDown: Draw(0, 0, FBottomDownBtn);
- end;
- end;
- procedure TRxSpinButton.DrawAllBitmap;
- begin
- DrawBitmap(FTopDownBtn, sbTopDown);
- DrawBitmap(FBottomDownBtn, sbBottomDown);
- DrawBitmap(FNotDownBtn, sbNotDown);
- end;
- procedure TRxSpinButton.DrawBitmap(ABitmap: TBitmap; ADownState: TSpinButtonState);
- var
- R, RSrc: TRect;
- dRect: Integer;
- {Temp: TBitmap;}
- begin
- ABitmap.Height := Height;
- ABitmap.Width := Width;
- with ABitmap.Canvas do begin
- R := Bounds(0, 0, Width, Height);
- Pen.Width := 1;
- Brush.Color := clBtnFace;
- Brush.Style := bsSolid;
- FillRect(R);
- { buttons frame }
- Pen.Color := clWindowFrame;
- Rectangle(0, 0, Width, Height);
- MoveTo(-1, Height);
- LineTo(Width, -1);
- { top button }
- if ADownState = sbTopDown then Pen.Color := clBtnShadow
- else Pen.Color := clBtnHighlight;
- MoveTo(1, Height - 4);
- LineTo(1, 1);
- LineTo(Width - 3, 1);
- if ADownState = sbTopDown then Pen.Color := clBtnHighlight
- else Pen.Color := clBtnShadow;
- if ADownState <> sbTopDown then begin
- MoveTo(1, Height - 3);
- LineTo(Width - 2, 0);
- end;
- { bottom button }
- if ADownState = sbBottomDown then Pen.Color := clBtnHighlight
- else Pen.Color := clBtnShadow;
- MoveTo(2, Height - 2);
- LineTo(Width - 2, Height - 2);
- LineTo(Width - 2, 1);
- if ADownState = sbBottomDown then Pen.Color := clBtnShadow
- else Pen.Color := clBtnHighlight;
- MoveTo(2, Height - 2);
- LineTo(Width - 1, 1);
- { top glyph }
- dRect := 1;
- if ADownState = sbTopDown then Inc(dRect);
- R := Bounds(Round((Width / 4) - (FUpBitmap.Width / 2)) + dRect,
- Round((Height / 4) - (FUpBitmap.Height / 2)) + dRect, FUpBitmap.Width,
- FUpBitmap.Height);
- RSrc := Bounds(0, 0, FUpBitmap.Width, FUpBitmap.Height);
- {
- if Self.Enabled or (csDesigning in ComponentState) then
- BrushCopy(R, FUpBitmap, RSrc, FUpBitmap.TransparentColor)
- else begin
- Temp := CreateDisabledBitmap(FUpBitmap, clBlack);
- try
- BrushCopy(R, Temp, RSrc, Temp.TransparentColor);
- finally
- Temp.Free;
- end;
- end;
- }
- BrushCopy(R, FUpBitmap, RSrc, FUpBitmap.TransparentColor);
- { bottom glyph }
- R := Bounds(Round((3 * Width / 4) - (FDownBitmap.Width / 2)) - 1,
- Round((3 * Height / 4) - (FDownBitmap.Height / 2)) - 1,
- FDownBitmap.Width, FDownBitmap.Height);
- RSrc := Bounds(0, 0, FDownBitmap.Width, FDownBitmap.Height);
- {
- if Self.Enabled or (csDesigning in ComponentState) then
- BrushCopy(R, FDownBitmap, RSrc, FDownBitmap.TransparentColor)
- else begin
- Temp := CreateDisabledBitmap(FDownBitmap, clBlack);
- try
- BrushCopy(R, Temp, RSrc, Temp.TransparentColor);
- finally
- Temp.Free;
- end;
- end;
- }
- BrushCopy(R, FDownBitmap, RSrc, FDownBitmap.TransparentColor);
- if ADownState = sbBottomDown then begin
- Pen.Color := clBtnShadow;
- MoveTo(3, Height - 2);
- LineTo(Width - 1, 2);
- end;
- end;
- end;
- procedure TRxSpinButton.CMEnabledChanged(var Message: TMessage);
- begin
- inherited;
- FInvalidate := True;
- Invalidate;
- end;
- procedure TRxSpinButton.TopClick;
- begin
- if Assigned(FOnTopClick) then begin
- FOnTopClick(Self);
- if not (csLButtonDown in ControlState) then FDown := sbNotDown;
- end;
- end;
- procedure TRxSpinButton.BottomClick;
- begin
- if Assigned(FOnBottomClick) then begin
- FOnBottomClick(Self);
- if not (csLButtonDown in ControlState) then FDown := sbNotDown;
- end;
- end;
- procedure TRxSpinButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- begin
- inherited MouseDown(Button, Shift, X, Y);
- if (Button = mbLeft) and Enabled then begin
- if (FFocusControl <> nil) and FFocusControl.TabStop and
- FFocusControl.CanFocus and (GetFocus <> FFocusControl.Handle) then
- FFocusControl.SetFocus;
- if FDown = sbNotDown then begin
- FLastDown := FDown;
- if Y > (-(Height/Width) * X + Height) then begin
- FDown := sbBottomDown;
- BottomClick;
- end
- else begin
- FDown := sbTopDown;
- TopClick;
- end;
- if FLastDown <> FDown then begin
- FLastDown := FDown;
- Repaint;
- end;
- if FRepeatTimer = nil then FRepeatTimer := TTimer.Create(Self);
- FRepeatTimer.OnTimer := TimerExpired;
- FRepeatTimer.Interval := InitRepeatPause;
- FRepeatTimer.Enabled := True;
- end;
- FDragging := True;
- end;
- end;
- procedure TRxSpinButton.MouseMove(Shift: TShiftState; X, Y: Integer);
- var
- NewState: TSpinButtonState;
- begin
- inherited MouseMove(Shift, X, Y);
- if FDragging then begin
- if (X >= 0) and (X <= Width) and (Y >= 0) and (Y <= Height) then begin
- NewState := FDown;
- if Y > (-(Width / Height) * X + Height) then begin
- if (FDown <> sbBottomDown) then begin
- if FLastDown = sbBottomDown then FDown := sbBottomDown
- else FDown := sbNotDown;
- if NewState <> FDown then Repaint;
- end;
- end
- else begin
- if (FDown <> sbTopDown) then begin
- if (FLastDown = sbTopDown) then FDown := sbTopDown
- else FDown := sbNotDown;
- if NewState <> FDown then Repaint;
- end;
- end;
- end else
- if FDown <> sbNotDown then begin
- FDown := sbNotDown;
- Repaint;
- end;
- end;
- end;
- procedure TRxSpinButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- begin
- inherited MouseUp(Button, Shift, X, Y);
- if FDragging then begin
- FDragging := False;
- if (X >= 0) and (X <= Width) and (Y >= 0) and (Y <= Height) then begin
- FDown := sbNotDown;
- FLastDown := sbNotDown;
- Repaint;
- end;
- end;
- end;
- procedure TRxSpinButton.TimerExpired(Sender: TObject);
- begin
- FRepeatTimer.Interval := RepeatPause;
- if (FDown <> sbNotDown) and MouseCapture then begin
- try
- if FDown = sbBottomDown then BottomClick else TopClick;
- except
- FRepeatTimer.Enabled := False;
- raise;
- end;
- end;
- end;
- function DefBtnWidth: Integer;
- begin
- Result := GetSystemMetrics(SM_CXVSCROLL);
- if Result > 15 then Result := 15;
- end;
- {$IFDEF WIN32}
- type
- TRxUpDown = class(TCustomUpDown)
- private
- FChanging: Boolean;
- procedure ScrollMessage(var Message: TWMVScroll);
- procedure WMHScroll(var Message: TWMHScroll); message CN_HSCROLL;
- procedure WMVScroll(var Message: TWMVScroll); message CN_VSCROLL;
- procedure WMSize(var Message: TWMSize); message WM_SIZE;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property OnClick;
- end;
- constructor TRxUpDown.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Orientation := udVertical;
- Min := -1;
- Max := 1;
- Position := 0;
- end;
- destructor TRxUpDown.Destroy;
- begin
- OnClick := nil;
- inherited Destroy;
- end;
- procedure TRxUpDown.ScrollMessage(var Message: TWMVScroll);
- begin
- if Message.ScrollCode = SB_THUMBPOSITION then begin
- if not FChanging then begin
- FChanging := True;
- try
- if Message.Pos > 0 then Click(btNext)
- else if Message.Pos < 0 then Click(btPrev);
- if HandleAllocated then
- SendMessage(Handle, UDM_SETPOS, 0, 0);
- finally
- FChanging := False;
- end;
- end;
- end;
- end;
- procedure TRxUpDown.WMHScroll(var Message: TWMHScroll);
- begin
- ScrollMessage(TWMVScroll(Message));
- end;
- procedure TRxUpDown.WMVScroll(var Message: TWMVScroll);
- begin
- ScrollMessage(Message);
- end;
- procedure TRxUpDown.WMSize(var Message: TWMSize);
- begin
- inherited;
- if Width <> DefBtnWidth then Width := DefBtnWidth;
- end;
- {$ENDIF WIN32}
- { TRxSpinEdit }
- constructor TRxSpinEdit.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Text := '0';
- ControlStyle := ControlStyle - [csSetCaption];
- FIncrement := 1.0;
- FDecimal := 2;
- FEditorEnabled := True;
- {$IFDEF WIN32}
- FButtonKind := bkDiagonal;
- {$ENDIF}
- FArrowKeys := True;
- RecreateButton;
- end;
- destructor TRxSpinEdit.Destroy;
- begin
- Destroying;
- FChanging := True;
- if FButton <> nil then begin
- FButton.Free;
- FButton := nil;
- FBtnWindow.Free;
- FBtnWindow := nil;
- end;
- {$IFDEF WIN32}
- if FUpDown <> nil then begin
- FUpDown.Free;
- FUpDown := nil;
- end;
- {$ENDIF}
- inherited Destroy;
- end;
- procedure TRxSpinEdit.RecreateButton;
- begin
- if (csDestroying in ComponentState) then Exit;
- FButton.Free;
- FButton := nil;
- FBtnWindow.Free;
- FBtnWindow := nil;
- {$IFDEF WIN32}
- FUpDown.Free;
- FUpDown := nil;
- if GetButtonKind = bkStandard then begin
- FUpDown := TRxUpDown.Create(Self);
- with TRxUpDown(FUpDown) do begin
- Visible := True;
- SetBounds(0, 0, DefBtnWidth, Self.Height);
- {$IFDEF RX_D4}
- if (BiDiMode = bdRightToLeft) then Align := alLeft else
- {$ENDIF}
- Align := alRight;
- Parent := Self;
- OnClick := UpDownClick;
- end;
- end
- else begin
- {$ENDIF}
- FBtnWindow := TWinControl.Create(Self);
- FBtnWindow.Visible := True;
- FBtnWindow.Parent := Self;
- FBtnWindow.SetBounds(0, 0, Height, Height);
- FButton := TRxSpinButton.Create(Self);
- FButton.Visible := True;
- FButton.Parent := FBtnWindow;
- FButton.FocusControl := Self;
- FButton.OnTopClick := UpClick;
- FButton.OnBottomClick := DownClick;
- FButton.SetBounds(0, 0, FBtnWindow.Width, FBtnWindow.Height);
- {$IFDEF WIN32}
- end;
- {$ENDIF}
- end;
- procedure TRxSpinEdit.SetArrowKeys(Value: Boolean);
- begin
- FArrowKeys := Value;
- {$IFDEF WIN32}
- ResizeButton;
- {$ENDIF}
- end;
- {$IFDEF WIN32}
- function TRxSpinEdit.GetButtonKind: TSpinButtonKind;
- begin
- if NewStyleControls then Result := FButtonKind
- else Result := bkDiagonal;
- end;
- procedure TRxSpinEdit.SetButtonKind(Value: TSpinButtonKind);
- var
- OldKind: TSpinButtonKind;
- begin
- OldKind := FButtonKind;
- FButtonKind := Value;
- if OldKind <> GetButtonKind then begin
- RecreateButton;
- ResizeButton;
- SetEditRect;
- end;
- end;
- procedure TRxSpinEdit.UpDownClick(Sender: TObject; Button: TUDBtnType);
- begin
- if TabStop and CanFocus then SetFocus;
- case Button of
- btNext: UpClick(Sender);
- btPrev: DownClick(Sender);
- end;
- end;
- {$ENDIF WIN32}
- function TRxSpinEdit.GetButtonWidth: Integer;
- begin
- {$IFDEF WIN32}
- if FUpDown <> nil then Result := FUpDown.Width else
- {$ENDIF}
- if FButton <> nil then Result := FButton.Width
- else Result := DefBtnWidth;
- end;
- procedure TRxSpinEdit.ResizeButton;
- {$IFDEF WIN32}
- var
- R: TRect;
- {$ENDIF}
- begin
- {$IFDEF WIN32}
- if FUpDown <> nil then begin
- FUpDown.Width := DefBtnWidth;
- {$IFDEF RX_D4}
- if (BiDiMode = bdRightToLeft) then FUpDown.Align := alLeft else
- {$ENDIF}
- FUpDown.Align := alRight;
- end
- else if FButton <> nil then begin { bkDiagonal }
- if NewStyleControls and Ctl3D and (BorderStyle = bsSingle) then
- R := Bounds(Width - Height - 1, -1, Height - 3, Height - 3)
- else
- R := Bounds(Width - Height, 0, Height, Height);
- {$IFDEF RX_D4}
- if (BiDiMode = bdRightToLeft) then begin
- if NewStyleControls and Ctl3D and (BorderStyle = bsSingle) then begin
- R.Left := -1;
- R.Right := Height - 4;
- end
- else begin
- R.Left := 0;
- R.Right := Height;
- end;
- end;
- {$ENDIF}
- with R do
- FBtnWindow.SetBounds(Left, Top, Right - Left, Bottom - Top);
- FButton.SetBounds(0, 0, FBtnWindow.Width, FBtnWindow.Height);
- end;
- {$ELSE}
- if FButton <> nil then begin
- FBtnWindow.SetBounds(Width - Height, 0, Height, Height);
- FButton.SetBounds(0, 0, FBtnWindow.Width, FBtnWindow.Height);
- end;
- {$ENDIF}
- end;
- procedure TRxSpinEdit.KeyDown(var Key: Word; Shift: TShiftState);
- begin
- inherited KeyDown(Key, Shift);
- if ArrowKeys and (Key in [VK_UP, VK_DOWN]) then begin
- if Key = VK_UP then UpClick(Self)
- else if Key = VK_DOWN then DownClick(Self);
- Key := 0;
- end;
- end;
- procedure TRxSpinEdit.Change;
- begin
- if not FChanging then inherited Change;
- end;
- procedure TRxSpinEdit.KeyPress(var Key: Char);
- begin
- if not IsValidChar(Key) then begin
- Key := #0;
- MessageBeep(0)
- end;
- if Key <> #0 then begin
- inherited KeyPress(Key);
- if (Key = Char(VK_RETURN)) or (Key = Char(VK_ESCAPE)) then begin
- { must catch and remove this, since is actually multi-line }
- GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
- if Key = Char(VK_RETURN) then Key := #0;
- end;
- end;
- end;
- function TRxSpinEdit.IsValidChar(Key: Char): Boolean;
- var
- ValidChars: set of Char;
- begin
- ValidChars := ['+', '-', '0'..'9'];
- if ValueType = vtFloat then begin
- if Pos(DecimalSeparator, Text) = 0 then
- ValidChars := ValidChars + [DecimalSeparator];
- if Pos('E', AnsiUpperCase(Text)) = 0 then
- ValidChars := ValidChars + ['e', 'E'];
- end
- else if ValueType = vtHex then begin
- ValidChars := ValidChars + ['A'..'F', 'a'..'f'];
- end;
- Result := (Key in ValidChars) or (Key < #32);
- if not FEditorEnabled and Result and ((Key >= #32) or
- (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE))) then Result := False;
- end;
- procedure TRxSpinEdit.CreateParams(var Params: TCreateParams);
- const
- {$IFDEF RX_D4}
- Alignments: array[Boolean, TAlignment] of DWORD =
- ((ES_LEFT, ES_RIGHT, ES_CENTER), (ES_RIGHT, ES_LEFT, ES_CENTER));
- {$ELSE}
- Alignments: array[TAlignment] of Longint = (ES_LEFT, ES_RIGHT, ES_CENTER);
- {$ENDIF}
- begin
- inherited CreateParams(Params);
- Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN or
- {$IFDEF RX_D4}
- Alignments[UseRightToLeftAlignment, FAlignment];
- {$ELSE}
- Alignments[FAlignment];
- {$ENDIF}
- end;
- procedure TRxSpinEdit.CreateWnd;
- begin
- inherited CreateWnd;
- SetEditRect;
- end;
- procedure TRxSpinEdit.SetEditRect;
- var
- Loc: TRect;
- begin
- {$IFDEF RX_D4}
- if (BiDiMode = bdRightToLeft) then
- SetRect(Loc, GetButtonWidth + 1, 0, ClientWidth - 1,
- ClientHeight + 1) else
- {$ENDIF RX_D4}
- SetRect(Loc, 0, 0, ClientWidth - GetButtonWidth - 2, ClientHeight + 1);
- SendMessage(Handle, EM_SETRECTNP, 0, Longint(@Loc));
- end;
- procedure TRxSpinEdit.SetAlignment(Value: TAlignment);
- begin
- if FAlignment <> Value then begin
- FAlignment := Value;
- RecreateWnd;
- end;
- end;
- procedure TRxSpinEdit.WMSize(var Message: TWMSize);
- var
- MinHeight: Integer;
- begin
- inherited;
- MinHeight := GetMinHeight;
- { text edit bug: if size to less than minheight, then edit ctrl does
- not display the text }
- if Height < MinHeight then
- Height := MinHeight
- else begin
- ResizeButton;
- SetEditRect;
- end;
- end;
- procedure TRxSpinEdit.GetTextHeight(var SysHeight, Height: Integer);
- var
- DC: HDC;
- SaveFont: HFont;
- SysMetrics, Metrics: TTextMetric;
- begin
- DC := GetDC(0);
- GetTextMetrics(DC, SysMetrics);
- SaveFont := SelectObject(DC, Font.Handle);
- GetTextMetrics(DC, Metrics);
- SelectObject(DC, SaveFont);
- ReleaseDC(0, DC);
- SysHeight := SysMetrics.tmHeight;
- Height := Metrics.tmHeight;
- end;
- function TRxSpinEdit.GetMinHeight: Integer;
- var
- I, H: Integer;
- begin
- GetTextHeight(I, H);
- if I > H then I := H;
- Result := H + {$IFNDEF WIN32} (I div 4) + {$ENDIF}
- (GetSystemMetrics(SM_CYBORDER) * 4) + 1;
- end;
- procedure TRxSpinEdit.UpClick(Sender: TObject);
- var
- OldText: string;
- begin
- if ReadOnly then MessageBeep(0)
- else begin
- FChanging := True;
- try
- OldText := inherited Text;
- Value := Value + FIncrement;
- finally
- FChanging := False;
- end;
- if CompareText(inherited Text, OldText) <> 0 then begin
- Modified := True;
- Change;
- end;
- if Assigned(FOnTopClick) then FOnTopClick(Self);
- end;
- end;
- procedure TRxSpinEdit.DownClick(Sender: TObject);
- var
- OldText: string;
- begin
- if ReadOnly then MessageBeep(0)
- else begin
- FChanging := True;
- try
- OldText := inherited Text;
- Value := Value - FIncrement;
- finally
- FChanging := False;
- end;
- if CompareText(inherited Text, OldText) <> 0 then begin
- Modified := True;
- Change;
- end;
- if Assigned(FOnBottomClick) then FOnBottomClick(Self);
- end;
- end;
- {$IFDEF RX_D4}
- procedure TRxSpinEdit.CMBiDiModeChanged(var Message: TMessage);
- begin
- inherited;
- ResizeButton;
- SetEditRect;
- end;
- {$ENDIF}
- procedure TRxSpinEdit.CMFontChanged(var Message: TMessage);
- begin
- inherited;
- ResizeButton;
- SetEditRect;
- end;
- procedure TRxSpinEdit.CMCtl3DChanged(var Message: TMessage);
- begin
- inherited;
- ResizeButton;
- SetEditRect;
- end;
- procedure TRxSpinEdit.CMEnabledChanged(var Message: TMessage);
- begin
- inherited;
- {$IFDEF WIN32}
- if FUpDown <> nil then begin
- FUpDown.Enabled := Enabled;
- ResizeButton;
- end;
- {$ENDIF}
- if FButton <> nil then FButton.Enabled := Enabled;
- end;
- procedure TRxSpinEdit.WMPaste(var Message: TWMPaste);
- begin
- if not FEditorEnabled or ReadOnly then Exit;
- inherited;
- end;
- procedure TRxSpinEdit.WMCut(var Message: TWMCut);
- begin
- if not FEditorEnabled or ReadOnly then Exit;
- inherited;
- end;
- procedure TRxSpinEdit.CMExit(var Message: TCMExit);
- begin
- inherited;
- if CheckValue(Value) <> Value then SetValue(Value);
- end;
- procedure TRxSpinEdit.CMEnter(var Message: TMessage);
- begin
- if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
- inherited;
- end;
- function TRxSpinEdit.GetValue: Extended;
- begin
- try
- if ValueType = vtFloat then Result := StrToFloat(Text)
- else if ValueType = vtHex then Result := StrToInt('$' + Text)
- else Result := StrToInt(Text);
- except
- if ValueType = vtFloat then Result := FMinValue
- else Result := Trunc(FMinValue);
- end;
- end;
- procedure TRxSpinEdit.SetValue(NewValue: Extended);
- begin
- if ValueType = vtFloat then
- Text := FloatToStrF(CheckValue(NewValue), ffFixed, 15, FDecimal)
- else if ValueType = vtHex then
- Text := IntToHex(Round(CheckValue(NewValue)), 1)
- else
- Text := IntToStr(Round(CheckValue(NewValue)));
- end;
- function TRxSpinEdit.GetAsInteger: Longint;
- begin
- Result := Trunc(GetValue);
- end;
- procedure TRxSpinEdit.SetAsInteger(NewValue: Longint);
- begin
- SetValue(NewValue);
- end;
- procedure TRxSpinEdit.SetValueType(NewType: TValueType);
- begin
- if FValueType <> NewType then begin
- FValueType := NewType;
- Value := GetValue;
- if FValueType in [{$IFDEF CBUILDER} vtInt {$ELSE} vtInteger {$ENDIF}, vtHex] then
- begin
- FIncrement := Round(FIncrement);
- if FIncrement = 0 then FIncrement := 1;
- end;
- end;
- end;
- function TRxSpinEdit.IsIncrementStored: Boolean;
- begin
- Result := FIncrement <> 1.0;
- end;
- function TRxSpinEdit.IsMaxStored: Boolean;
- begin
- Result := (MaxValue <> 0.0);
- end;
- function TRxSpinEdit.IsMinStored: Boolean;
- begin
- Result := (MinValue <> 0.0);
- end;
- function TRxSpinEdit.IsValueStored: Boolean;
- begin
- Result := (GetValue <> 0.0);
- end;
- procedure TRxSpinEdit.SetDecimal(NewValue: Byte);
- begin
- if FDecimal <> NewValue then begin
- FDecimal := NewValue;
- Value := GetValue;
- end;
- end;
- function TRxSpinEdit.CheckValue(NewValue: Extended): Extended;
- begin
- Result := NewValue;
- if (FMaxValue <> FMinValue) then begin
- if NewValue < FMinValue then
- Result := FMinValue
- else if NewValue > FMaxValue then
- Result := FMaxValue;
- end;
- end;
- end.