diff --git a/SpinFlat.pas b/SpinFlat.pas deleted file mode 100644 index 3f934f6..0000000 --- a/SpinFlat.pas +++ /dev/null @@ -1,672 +0,0 @@ -unit SpinFlat; - -interface - -uses Windows, Classes, StdCtrls, ExtCtrls, Controls, Messages, SysUtils, - Forms, Graphics, Menus, Buttons; - -const - InitRepeatPause = 400; { pause before repeat timer (ms) } - RepeatPause = 100; { pause before hint window displays (ms)} - -type - TNumGlyphs = Buttons.TNumGlyphs; - - TTimerSpeedButton = class; - -{ TSpinButtonFlat } - - TSpinButtonFlat = class (TWinControl) - private - FUpButton: TTimerSpeedButton; - FDownButton: TTimerSpeedButton; - FFocusedButton: TTimerSpeedButton; - FFocusControl: TWinControl; - FOnUpClick: TNotifyEvent; - FOnDownClick: TNotifyEvent; - function CreateButton: TTimerSpeedButton; - function GetUpGlyph: TBitmap; - function GetDownGlyph: TBitmap; - procedure SetUpGlyph(Value: TBitmap); - procedure SetDownGlyph(Value: TBitmap); - function GetUpNumGlyphs: TNumGlyphs; - function GetDownNumGlyphs: TNumGlyphs; - procedure SetUpNumGlyphs(Value: TNumGlyphs); - procedure SetDownNumGlyphs(Value: TNumGlyphs); - procedure BtnClick(Sender: TObject); - procedure BtnMouseDown (Sender: TObject; Button: TMouseButton; - Shift: TShiftState; X, Y: Integer); - procedure SetFocusBtn (Btn: TTimerSpeedButton); - procedure AdjustSize (var W, H: Integer); reintroduce; - procedure WMSize(var Message: TWMSize); message WM_SIZE; - procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS; - procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS; - procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; - function GetFlat: boolean; - procedure SetFlat(const Value: boolean); - protected - procedure Loaded; override; - procedure KeyDown(var Key: Word; Shift: TShiftState); override; - procedure Notification(AComponent: TComponent; - Operation: TOperation); override; - public - constructor Create(AOwner: TComponent); override; - procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; - published - property Align; - property Anchors; - property Constraints; - property Ctl3D; - property DownGlyph: TBitmap read GetDownGlyph write SetDownGlyph; - property DownNumGlyphs: TNumGlyphs read GetDownNumGlyphs write SetDownNumGlyphs default 1; - property DragCursor; - property DragKind; - property DragMode; - property Enabled; - property Flat:boolean read GetFlat write SetFlat; - property FocusControl: TWinControl read FFocusControl write FFocusControl; - property ParentCtl3D; - property ParentShowHint; - property PopupMenu; - property ShowHint; - property TabOrder; - property TabStop; - property UpGlyph: TBitmap read GetUpGlyph write SetUpGlyph; - property UpNumGlyphs: TNumGlyphs read GetUpNumGlyphs write SetUpNumGlyphs default 1; - property Visible; - property OnDownClick: TNotifyEvent read FOnDownClick write FOnDownClick; - property OnDragDrop; - property OnDragOver; - property OnEndDock; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnStartDock; - property OnStartDrag; - property OnUpClick: TNotifyEvent read FOnUpClick write FOnUpClick; - end; - -{ TSpinEditFlat } - - TSpinEditFlat = class(TCustomEdit) - private - FMinValue: LongInt; - FMaxValue: LongInt; - FIncrement: LongInt; - FButton: TSpinButtonFlat; - FEditorEnabled: Boolean; - function GetMinHeight: Integer; - function GetValue: LongInt; - function CheckValue (NewValue: LongInt): LongInt; - procedure SetValue (NewValue: LongInt); - procedure SetEditRect; - procedure WMSize(var Message: TWMSize); message WM_SIZE; - procedure CMEnter(var Message: TCMGotFocus); 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; - protected - procedure GetChildren(Proc: TGetChildProc; Root: TComponent); 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 Button: TSpinButtonFlat read FButton; - published - property Anchors; - property AutoSelect; - property AutoSize; - property Color; - property Constraints; - property Ctl3D; - property DragCursor; - property DragMode; - property EditorEnabled: Boolean read FEditorEnabled write FEditorEnabled default True; - property Enabled; - property Font; - property Increment: LongInt read FIncrement write FIncrement default 1; - property MaxLength; - property MaxValue: LongInt read FMaxValue write FMaxValue; - property MinValue: LongInt read FMinValue write FMinValue; - property ParentColor; - property ParentCtl3D; - property ParentFont; - property ParentShowHint; - property PopupMenu; - property ReadOnly; - property ShowHint; - property TabOrder; - property TabStop; - property Value: LongInt read GetValue write SetValue; - property Visible; - property OnChange; - property OnClick; - property OnDblClick; - property OnDragDrop; - property OnDragOver; - property OnEndDrag; - property OnEnter; - property OnExit; - property OnKeyDown; - property OnKeyPress; - property OnKeyUp; - property OnMouseDown; - property OnMouseMove; - property OnMouseUp; - property OnStartDrag; - end; - -{ TTimerSpeedButton } - - TTimeBtnState = set of (tbFocusRect, tbAllowTimer); - - TTimerSpeedButton = class(TSpeedButton) - private - FRepeatTimer: TTimer; - FTimeBtnState: TTimeBtnState; - procedure TimerExpired(Sender: TObject); - function GetInterval: integer; - procedure SetInterval(const Value: integer); - protected - procedure Paint; override; - procedure MouseDown(Button: TMouseButton; Shift: TShiftState; - X, Y: Integer); override; - procedure MouseUp(Button: TMouseButton; Shift: TShiftState; - X, Y: Integer); override; - public - destructor Destroy; override; - published - property TimeBtnState: TTimeBtnState read FTimeBtnState write FTimeBtnState; - property Interval:integer read GetInterval write SetInterval; - end; - -procedure Register; - -implementation - -{ TSpinButtonFlat } - -constructor TSpinButtonFlat.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] + - [csFramed, csOpaque]; - - FUpButton := CreateButton; - FDownButton := CreateButton; - UpGlyph := nil; - DownGlyph := nil; - - Width := 20; - Height := 25; - FFocusedButton := FUpButton; -end; - -function TSpinButtonFlat.CreateButton: TTimerSpeedButton; -begin - Result := TTimerSpeedButton.Create (Self); - Result.OnClick := BtnClick; - Result.OnMouseDown := BtnMouseDown; - Result.Visible := True; - Result.Enabled := True; - Result.TimeBtnState := [tbAllowTimer]; - Result.Parent := Self; -end; - -procedure TSpinButtonFlat.Notification(AComponent: TComponent; - Operation: TOperation); -begin - inherited Notification(AComponent, Operation); - if (Operation = opRemove) and (AComponent = FFocusControl) then - FFocusControl := nil; -end; - -procedure TSpinButtonFlat.AdjustSize (var W, H: Integer); -begin - if (FUpButton = nil) or (csLoading in ComponentState) then Exit; - if W < 15 then W := 15; - FUpButton.SetBounds (0, 0, W, H div 2); - FDownButton.SetBounds (0, FUpButton.Height - 1, W, H - FUpButton.Height + 1); -end; - -procedure TSpinButtonFlat.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); -var - W, H: Integer; -begin - W := AWidth; - H := AHeight; - AdjustSize (W, H); - inherited SetBounds (ALeft, ATop, W, H); -end; - -procedure TSpinButtonFlat.WMSize(var Message: TWMSize); -var - W, H: Integer; -begin - inherited; - - { check for minimum size } - W := Width; - H := Height; - AdjustSize (W, H); - if (W <> Width) or (H <> Height) then - inherited SetBounds(Left, Top, W, H); - Message.Result := 0; -end; - -procedure TSpinButtonFlat.WMSetFocus(var Message: TWMSetFocus); -begin - FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState + [tbFocusRect]; - FFocusedButton.Invalidate; -end; - -procedure TSpinButtonFlat.WMKillFocus(var Message: TWMKillFocus); -begin - FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState - [tbFocusRect]; - FFocusedButton.Invalidate; -end; - -procedure TSpinButtonFlat.KeyDown(var Key: Word; Shift: TShiftState); -begin - case Key of - VK_UP: - begin - SetFocusBtn (FUpButton); - FUpButton.Click; - end; - VK_DOWN: - begin - SetFocusBtn (FDownButton); - FDownButton.Click; - end; - VK_SPACE: - FFocusedButton.Click; - end; -end; - -procedure TSpinButtonFlat.BtnMouseDown (Sender: TObject; Button: TMouseButton; - Shift: TShiftState; X, Y: Integer); -begin - if Button = mbLeft then - begin - SetFocusBtn (TTimerSpeedButton (Sender)); - if (FFocusControl <> nil) and FFocusControl.TabStop and - FFocusControl.CanFocus and (GetFocus <> FFocusControl.Handle) then - FFocusControl.SetFocus - else if TabStop and (GetFocus <> Handle) and CanFocus then - SetFocus; - end; -end; - -procedure TSpinButtonFlat.BtnClick(Sender: TObject); -begin - if Sender = FUpButton then - begin - if Assigned(FOnUpClick) then FOnUpClick(Self); - end - else - if Assigned(FOnDownClick) then FOnDownClick(Self); -end; - -procedure TSpinButtonFlat.SetFocusBtn (Btn: TTimerSpeedButton); -begin - if TabStop and CanFocus and (Btn <> FFocusedButton) then - begin - FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState - [tbFocusRect]; - FFocusedButton := Btn; - if (GetFocus = Handle) then - begin - FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState + [tbFocusRect]; - Invalidate; - end; - end; -end; - -procedure TSpinButtonFlat.WMGetDlgCode(var Message: TWMGetDlgCode); -begin - Message.Result := DLGC_WANTARROWS; -end; - -procedure TSpinButtonFlat.Loaded; -var - W, H: Integer; -begin - inherited Loaded; - W := Width; - H := Height; - AdjustSize (W, H); - if (W <> Width) or (H <> Height) then - inherited SetBounds (Left, Top, W, H); -end; - -function TSpinButtonFlat.GetUpGlyph: TBitmap; -begin - Result := FUpButton.Glyph; -end; - -procedure TSpinButtonFlat.SetUpGlyph(Value: TBitmap); -begin - if Value <> nil then - FUpButton.Glyph := Value - else - begin - FUpButton.Glyph.Handle := LoadBitmap(HInstance, 'SpinUp'); - FUpButton.NumGlyphs := 1; - FUpButton.Invalidate; - end; -end; - -function TSpinButtonFlat.GetUpNumGlyphs: TNumGlyphs; -begin - Result := FUpButton.NumGlyphs; -end; - -procedure TSpinButtonFlat.SetUpNumGlyphs(Value: TNumGlyphs); -begin - FUpButton.NumGlyphs := Value; -end; - -function TSpinButtonFlat.GetDownGlyph: TBitmap; -begin - Result := FDownButton.Glyph; -end; - -procedure TSpinButtonFlat.SetDownGlyph(Value: TBitmap); -begin - if Value <> nil then - FDownButton.Glyph := Value - else - begin - FDownButton.Glyph.Handle := LoadBitmap(HInstance, 'SpinDown'); - FUpButton.NumGlyphs := 1; - FDownButton.Invalidate; - end; -end; - -function TSpinButtonFlat.GetDownNumGlyphs: TNumGlyphs; -begin - Result := FDownButton.NumGlyphs; -end; - -procedure TSpinButtonFlat.SetDownNumGlyphs(Value: TNumGlyphs); -begin - FDownButton.NumGlyphs := Value; -end; - -function TSpinButtonFlat.GetFlat: boolean; -begin - Result:=FUpButton.Flat; -end; - -procedure TSpinButtonFlat.SetFlat(const Value: boolean); -begin - FUpButton.Flat:=Value; FDownButton.Flat:=Value; -end; - -{ TSpinEditFlat } - -constructor TSpinEditFlat.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FButton := TSpinButtonFlat.Create (Self); - FButton.Width := 15; - FButton.Height := 17; - FButton.Visible := True; - FButton.Parent := Self; - FButton.FocusControl := Self; - FButton.OnUpClick := UpClick; - FButton.OnDownClick := DownClick; - Text := '0'; - ControlStyle := ControlStyle - [csSetCaption]; - FIncrement := 1; - FEditorEnabled := True; -end; - -destructor TSpinEditFlat.Destroy; -begin - FButton := nil; - inherited Destroy; -end; - -procedure TSpinEditFlat.GetChildren(Proc: TGetChildProc; Root: TComponent); -begin -end; - -procedure TSpinEditFlat.KeyDown(var Key: Word; Shift: TShiftState); -begin - if Key = VK_UP then UpClick (Self) - else if Key = VK_DOWN then DownClick (Self); - inherited KeyDown(Key, Shift); -end; - -procedure TSpinEditFlat.KeyPress(var Key: Char); -begin - if not IsValidChar(Key) then - begin - Key := #0; - MessageBeep(0) - end; - if Key <> #0 then inherited KeyPress(Key); -end; - -function TSpinEditFlat.IsValidChar(Key: Char): Boolean; -begin - Result := (Key in [DecimalSeparator, '+', '-', '0'..'9']) or - ((Key < #32) and (Key <> Chr(VK_RETURN))); - if not FEditorEnabled and Result and ((Key >= #32) or - (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE))) then - Result := False; -end; - -procedure TSpinEditFlat.CreateParams(var Params: TCreateParams); -begin - inherited CreateParams(Params); -{ Params.Style := Params.Style and not WS_BORDER; } - Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN; -end; - -procedure TSpinEditFlat.CreateWnd; -begin - inherited CreateWnd; - SetEditRect; -end; - -procedure TSpinEditFlat.SetEditRect; -var - Loc: TRect; -begin - SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc)); - Loc.Bottom := ClientHeight + 1; {+1 is workaround for windows paint bug} - Loc.Right := ClientWidth - FButton.Width - 2; - Loc.Top := 0; - Loc.Left := 0; - SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc)); - SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc)); {debug} -end; - -procedure TSpinEditFlat.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 if FButton <> nil then - begin - if NewStyleControls and Ctl3D then - FButton.SetBounds(Width - FButton.Width - 5, 0, FButton.Width, Height - 5) - else FButton.SetBounds (Width - FButton.Width, 1, FButton.Width, Height - 3); - SetEditRect; - end; -end; - -function TSpinEditFlat.GetMinHeight: Integer; -var - DC: HDC; - SaveFont: HFont; - I: Integer; - SysMetrics, Metrics: TTextMetric; -begin - DC := GetDC(0); - GetTextMetrics(DC, SysMetrics); - SaveFont := SelectObject(DC, Font.Handle); - GetTextMetrics(DC, Metrics); - SelectObject(DC, SaveFont); - ReleaseDC(0, DC); - I := SysMetrics.tmHeight; - if I > Metrics.tmHeight then I := Metrics.tmHeight; - Result := Metrics.tmHeight + I div 4 + GetSystemMetrics(SM_CYBORDER) * 4 + 2; -end; - -procedure TSpinEditFlat.UpClick (Sender: TObject); -begin - if ReadOnly then MessageBeep(0) - else Value := Value + FIncrement; -end; - -procedure TSpinEditFlat.DownClick (Sender: TObject); -begin - if ReadOnly then MessageBeep(0) - else Value := Value - FIncrement; -end; - -procedure TSpinEditFlat.WMPaste(var Message: TWMPaste); -begin - if not FEditorEnabled or ReadOnly then Exit; - inherited; -end; - -procedure TSpinEditFlat.WMCut(var Message: TWMPaste); -begin - if not FEditorEnabled or ReadOnly then Exit; - inherited; -end; - -procedure TSpinEditFlat.CMExit(var Message: TCMExit); -begin - inherited; - if CheckValue (Value) <> Value then - SetValue (Value); -end; - -function TSpinEditFlat.GetValue: LongInt; -begin - try - Result := StrToInt (Text); - except - Result := FMinValue; - end; -end; - -procedure TSpinEditFlat.SetValue (NewValue: LongInt); -begin - Text := IntToStr (CheckValue (NewValue)); -end; - -function TSpinEditFlat.CheckValue (NewValue: LongInt): LongInt; -begin - Result := NewValue; - if (FMaxValue <> FMinValue) then - begin - if NewValue < FMinValue then - Result := FMinValue - else if NewValue > FMaxValue then - Result := FMaxValue; - end; -end; - -procedure TSpinEditFlat.CMEnter(var Message: TCMGotFocus); -begin - if AutoSelect and not (csLButtonDown in ControlState) then - SelectAll; - inherited; -end; - -{TTimerSpeedButton} - -destructor TTimerSpeedButton.Destroy; -begin - if FRepeatTimer <> nil then - FRepeatTimer.Free; - inherited Destroy; -end; - -procedure TTimerSpeedButton.MouseDown(Button: TMouseButton; Shift: TShiftState; - X, Y: Integer); -begin - inherited MouseDown (Button, Shift, X, Y); - if tbAllowTimer in FTimeBtnState then - begin - if FRepeatTimer = nil then - FRepeatTimer := TTimer.Create(Self); - - FRepeatTimer.OnTimer := TimerExpired; - FRepeatTimer.Interval := InitRepeatPause; - FRepeatTimer.Enabled := True; - end; -end; - -procedure TTimerSpeedButton.MouseUp(Button: TMouseButton; Shift: TShiftState; - X, Y: Integer); -begin - inherited MouseUp (Button, Shift, X, Y); - if FRepeatTimer <> nil then - FRepeatTimer.Enabled := False; -end; - -procedure TTimerSpeedButton.TimerExpired(Sender: TObject); -begin - FRepeatTimer.Interval := RepeatPause; - if (FState = bsDown) and MouseCapture then - begin - try - Click; - except - FRepeatTimer.Enabled := False; - raise; - end; - end; -end; - -procedure TTimerSpeedButton.Paint; -var - R: TRect; -begin - inherited Paint; - if tbFocusRect in FTimeBtnState then - begin - R := Bounds(0, 0, Width, Height); - InflateRect(R, -3, -3); - if FState = bsDown then - OffsetRect(R, 1, 1); - DrawFocusRect(Canvas.Handle, R); - end; -end; - - -procedure Register; -begin - RegisterComponents('Additional', [TSpinButtonFlat,TSpinEditFlat,TTimerSpeedButton]); -end; - -function TTimerSpeedButton.GetInterval: integer; -begin - Result:=FRepeatTimer.Interval; -end; - -procedure TTimerSpeedButton.SetInterval(const Value: integer); -begin - FRepeatTimer.Interval:=Value; -end; - -end. - \ No newline at end of file