📄 jvqspin.pas
字号:
R.Right := Height - 4;
end
else
begin
R.Left := 0;
R.Right := Height;
end;
end;
with R do
FBtnWindow.SetBounds(Left, Top, Right - Left, Bottom - Top);
if BiDiMode = bdRightToLeft then
FBtnWindow.Align := alLeft
else
FBtnWindow.Align := alRight;
//Polaris
FButton.SetBounds(1, 1, FBtnWindow.Width - 1, FBtnWindow.Height - 1);
end;
end;
procedure TJvCustomSpinEdit.SetAlignment(Value: TAlignment);
begin
if FAlignment <> Value then
begin
FAlignment := Value;
Invalidate;
end;
end;
procedure TJvCustomSpinEdit.SetArrowKeys(Value: Boolean);
begin
FArrowKeys := Value;
ResizeButton;
end;
procedure TJvCustomSpinEdit.SetAsInteger(NewValue: Longint);
begin
SetValue(NewValue);
end;
procedure TJvCustomSpinEdit.SetButtonKind(Value: TSpinButtonKind);
var
OldKind: TSpinButtonKind;
begin
OldKind := FButtonKind;
FButtonKind := Value;
if OldKind <> GetButtonKind then
begin
RecreateButton;
ResizeButton;
SetEditRect;
end;
end;
procedure TJvCustomSpinEdit.SetCheckMaxValue(NewValue: Boolean);
begin
if FMaxValue <> 0 then
NewValue := True;
FCheckMaxValue := NewValue;
if csLoading in ComponentState then
FLCheckMaxValue := False;
SetValue(Value);
end;
procedure TJvCustomSpinEdit.SetCheckMinValue(NewValue: Boolean);
begin
if FMinValue <> 0 then
NewValue := True;
FCheckMinValue := NewValue;
if csLoading in ComponentState then
FLCheckMinValue := False;
SetValue(Value);
end;
procedure TJvCustomSpinEdit.SetShowButton(Value: Boolean);
begin
if FShowButton <> Value then
begin
FShowButton := Value;
RecreateButton;
ResizeButton;
SetEditRect;
end;
end;
procedure TJvCustomSpinEdit.SetDecimal(NewValue: Byte);
begin
if FDecimal <> NewValue then
begin
FDecimal := NewValue;
Value := GetValue;
end;
end;
procedure TJvCustomSpinEdit.SetDisplayFormat(const Value: string);
begin
if DisplayFormat <> Value then
begin
FDisplayFormat := Value;
Invalidate;
end;
end;
procedure TJvCustomSpinEdit.SetEditRect;
var
Loc: TRect;
begin
//Polaris
if BiDiMode = bdRightToLeft then
begin
SetRect(Loc, GetButtonWidth + 1, 0, ClientWidth - 1, ClientHeight + 1);
end
else
begin
SetRect(Loc, 0, 0, ClientWidth - GetButtonWidth - 2, ClientHeight + 1);
end;
SendMessage(Handle, EM_SETRECT, 0, Longint(@Loc));
//SetEditorRect(@Loc);
end;
procedure TJvCustomSpinEdit.SetFocused(Value: Boolean);
begin
if Value <> FFocused then
begin
FFocused := Value;
Invalidate;
DataChanged;
end;
end;
procedure TJvCustomSpinEdit.SetMaxValue(NewValue: Extended);
var
Z: Boolean;
b: Boolean;
begin
if NewValue <> FMaxValue then
begin
b := not StoreCheckMaxValue;
Z := (FMaxValue = 0) <> (NewValue = 0);
FMaxValue := NewValue;
if Z and FLCheckMaxValue then
begin
SetCheckMaxValue(CheckDefaultRange(True));
if b and FLCheckMinValue then
SetCheckMinValue(CheckDefaultRange(False));
end;
SetValue(Value);
end;
end;
procedure TJvCustomSpinEdit.SetMinValue(NewValue: Extended);
var
Z: Boolean;
b: Boolean;
begin
if NewValue <> FMinValue then
begin
b := not StoreCheckMinValue;
Z := (FMinValue = 0) <> (NewValue = 0);
FMinValue := NewValue;
if Z and FLCheckMinValue then
begin
SetCheckMinValue(CheckDefaultRange(False));
if b and FLCheckMaxValue then
SetCheckMaxValue(CheckDefaultRange(True));
end;
SetValue(Value);
end;
end;
procedure TJvCustomSpinEdit.SetThousands(Value: Boolean);
begin
if ValueType <> vtHex then
FThousands := Value;
end;
procedure TJvCustomSpinEdit.SetValueType(NewType: TValueType);
begin
if FValueType <> NewType then
begin
FValueType := NewType;
Value := GetValue;
if FValueType in [ vtInteger , vtHex] then
begin
FIncrement := Round(FIncrement);
if FIncrement = 0 then
FIncrement := 1;
end;
if FValueType = vtHex then
Thousands := False;
end;
end;
function TJvCustomSpinEdit.StoreCheckMaxValue: Boolean;
begin
Result := (FMaxValue = 0) and (FCheckMaxValue = (FMinValue = 0));
end;
function TJvCustomSpinEdit.StoreCheckMinValue: Boolean;
begin
Result := (FMinValue = 0) and (FCheckMinValue = (FMaxValue = 0));
end;
procedure TJvCustomSpinEdit.UpClick(Sender: TObject);
var
OldText: string;
begin
if ReadOnly then
DoBeepOnError
else
begin
FChanging := True;
try
OldText := inherited Text;
Value := Value + FIncrement;
finally
FChanging := False;
end;
if AnsiCompareText(inherited Text, OldText) <> 0 then
begin
Modified := True;
Change;
end;
if Assigned(FOnTopClick) then
FOnTopClick(Self);
end;
end;
procedure TJvCustomSpinEdit.UpDownClick(Sender: TObject; Button: TUDBtnType);
begin
if TabStop and CanFocus then
SetFocus;
case Button of
btNext:
UpClick(Sender);
btPrev:
DownClick(Sender);
end;
end;
//=== { TJvSpinButton } ======================================================
procedure TJvSpinButton.BottomClick;
begin
if Assigned(FOnBottomClick) then
begin
FOnBottomClick(Self);
if not (csLButtonDown in ControlState) then
FDown := sbNotDown;
end;
end;
procedure TJvSpinButton.CheckButtonBitmaps;
begin
if Assigned(FButtonBitmaps) and
((TSpinButtonBitmaps(FButtonBitmaps).Height <> Height) or
(TSpinButtonBitmaps(FButtonBitmaps).Width <> Width)) then
RemoveButtonBitmaps;
if FButtonBitmaps = nil then
begin
FButtonBitmaps := SpinButtonBitmapsManager.WantButtons(Width, Height, ButtonStyle,
not FUpBitmap.Empty or not FDownBitmap.Empty);
TSpinButtonBitmaps(FButtonBitmaps).AddClient;
end;
end;
procedure TJvSpinButton.CMSysColorChange(var Msg: TMessage);
begin
// The buttons we draw are buffered, thus we need to repaint them to theme changes etc.
if FButtonBitmaps <> nil then
TSpinButtonBitmaps(FButtonBitmaps).Reset;
end;
constructor TJvSpinButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FButtonStyle := sbsDefault;
FUpBitmap := TBitmap.Create;
FDownBitmap := TBitmap.Create;
FUpBitmap.OnChange := GlyphChanged;
FDownBitmap.OnChange := GlyphChanged;
Height := 20;
Width := 20;
FLastDown := sbNotDown;
FButtonBitmaps := nil;
SpinButtonBitmapsManager.AddClient;
end;
destructor TJvSpinButton.Destroy;
begin
RemoveButtonBitmaps;
SpinButtonBitmapsManager.RemoveClient;
FUpBitmap.Free;
FDownBitmap.Free;
FRepeatTimer.Free;
inherited Destroy;
end;
function TJvSpinButton.GetDownGlyph: TBitmap;
begin
Result := FDownBitmap;
end;
function TJvSpinButton.GetUpGlyph: TBitmap;
begin
Result := FUpBitmap;
end;
procedure TJvSpinButton.GlyphChanged(Sender: TObject);
begin
if Sender is TBitmap then
(Sender as TBitmap).Transparent := True;
RemoveButtonBitmaps;
Invalidate;
end;
procedure TJvSpinButton.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;
//>Polaris
if ((FButtonStyle = sbsDefault) and (Y > (-(Height / Width) * X + Height))) or
((FButtonStyle = sbsClassic) and (Y > (Height div 2))) 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;
function TJvSpinButton.MouseInBottomBtn(const P: TPoint): Boolean;
begin
with P do
Result :=
((FButtonStyle = sbsDefault)) and (Y > (-(Width / Height) * X + Height)) or
((FButtonStyle = sbsClassic) and (Y > (Height div 2)));
end;
procedure TJvSpinButton.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;
//>Polaris
if MouseInBottomBtn(Point(X, Y)) 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 TJvSpinButton.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 TJvSpinButton.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FFocusControl) then
FFocusControl := nil;
end;
procedure TJvSpinButton.Paint;
begin
CheckButtonBitmaps;
if not Enabled and not (csDesigning in ComponentState) then
FDragging := False;
TSpinButtonBitmaps(FButtonBitmaps).Draw(Canvas, FDown, Enabled, False, False);
if not FUpBitmap.Empty or not FDownBitmap.Empty then
TSpinButtonBitmaps(FButtonBitmaps).DrawGlyphs(Canvas, FDown, Enabled, FUpBitmap, FDownBitmap);
end;
procedure TJvSpinButton.RemoveButtonBitmaps;
begin
if Assigned(FButtonBitmaps) then
begin
TSpinButtonBitmaps(FButtonBitmaps).RemoveClient;
FButtonBitmaps := nil;
end;
end;
procedure TJvSpinButton.SetButtonStyle(Value: TJvSpinButtonStyle);
begin
if Value <> FButtonStyle then
begin
FButtonStyle := Value;
GlyphChanged(Self);
end;
end;
procedure TJvSpinButton.SetDown(Value: TSpinButtonState);
var
OldState: TSpinButtonState;
begin
OldState := FDown;
FDown := Value;
if OldState <> FDown then
Repaint;
end;
procedure TJvSpinButton.SetDownGlyph(Value: TBitmap);
begin
if Value <> nil then
FDownBitmap.Assign(Value)
else
FDownBitmap.Handle := NullHandle;
end;
procedure TJvSpinButton.SetFocusControl(Value: TWinControl);
begin
FFocusControl := Value;
if Value <> nil then
Value.FreeNotification(Self);
end;
procedure TJvSpinButton.SetUpGlyph(Value: TBitmap);
begin
if Value <> nil then
FUpBitmap.Assign(Value)
else
FUpBitmap.Handle := NullHandle;
end;
procedure TJvSpinButton.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;
procedure TJvSpinButton.TopClick;
begin
if Assigned(FOnTopClick) then
begin
FOnTopClick(Self);
if not (csLButtonDown in ControlState) then
FDown := sbNotDown;
end;
end;
//=== { TJvSpinEdit } ========================================================
// (rom) quite unusual not to have it in the Custom base class
constructor TJvSpinEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Text := '0';
end;
function TJvSpinEdit.GetValue: Extended;
begin
try
case ValueType of
vtFloat:
begin
if FDisplayFormat <> '' then
try
Result := StrToFloat(TextToValText(Text));
except
Result := FMinValue;
end
else
if not TextToFloat(PChar(RemoveThousands(Text)), Result, fvExtended) then
Result := FMinValue;
end;
vtHex:
Result := StrToIntDef('$' + Text, Round(FMinValue));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -