📄 复件 oldschooldbnavigator.pas
字号:
var
Count: Integer;
I: TNavigateBtn;
Space, Temp, Remain: Integer;
X: Integer;
begin
if (csLoading in ComponentState) then Exit;
if Buttons[nbFirst] = nil then Exit;
CalcMinSize(W, H);
Count := 0;
for I := Low(Buttons) to High(Buttons) do
if Buttons[I].Visible then
Inc(Count);
if Count = 0 then Inc(Count);
ButtonWidth := W div Count;
Temp := Count * ButtonWidth;
if Align = alNone then W := Temp;
X := 0;
Remain := W - Temp;
Temp := Count div 2;
for I := Low(Buttons) to High(Buttons) do
begin
if Buttons[I].Visible then
begin
Space := 0;
if Remain <> 0 then
begin
Dec(Temp, Remain);
if Temp < 0 then
begin
Inc(Temp, Count);
Space := 1;
end;
end;
Buttons[I].SetBounds(X, 0, ButtonWidth + Space, Height);
Inc(X, ButtonWidth + Space);
end
else
Buttons[I].SetBounds (Width + 1, 0, ButtonWidth, Height);
end;
end;
procedure TOldSchoolDBNavigator.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
W, H: Integer;
begin
W := AWidth;
H := AHeight;
if not HandleAllocated then SetSize(W, H);
inherited SetBounds (ALeft, ATop, W, H);
end;
procedure TOldSchoolDBNavigator.WMSize(var Message: TWMSize);
var
W, H: Integer;
begin
inherited;
W := Width;
H := Height;
SetSize(W, H);
end;
procedure TOldSchoolDBNavigator.WMWindowPosChanging(var Message: TWMWindowPosChanging);
begin
inherited;
if (SWP_NOSIZE and Message.WindowPos.Flags) = 0 then
CalcMinSize(Message.WindowPos.cx, Message.WindowPos.cy);
end;
procedure TOldSchoolDBNavigator.ClickHandler(Sender: TObject);
begin
BtnClick (TOSButton (Sender).Index);
end;
procedure TOldSchoolDBNavigator.BtnMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
OldFocus: TNavigateBtn;
begin
OldFocus := FocusedButton;
FocusedButton := TOSButton (Sender).Index;
if TabStop and (GetFocus <> Handle) and CanFocus then
begin
SetFocus;
if (GetFocus <> Handle) then
Exit;
end
else if TabStop and (GetFocus = Handle) and (OldFocus <> FocusedButton) then
begin
Buttons[OldFocus].Invalidate;
Buttons[FocusedButton].Invalidate;
end;
end;
procedure TOldSchoolDBNavigator.BtnClick(Index: TNavigateBtn);
begin
if (DataSource <> nil) and (DataSource.State <> dsInactive) then
begin
if not (csDesigning in ComponentState) and Assigned(FBeforeAction) then
FBeforeAction(Self, Index);
with DataSource.DataSet do
begin
case Index of
nbPrior: Prior;
nbNext: Next;
nbFirst: First;
nbLast: Last;
nbInsert: Insert;
nbEdit: Edit;
nbCancel: Cancel;
nbPost: Post;
nbRefresh: Refresh;
nbDelete:
if not FConfirmDelete or
(MessageDlg(SDeleteRecordQuestion, mtConfirmation,
mbOKCancel, 0) <> idCancel) then Delete;
end;
end;
end;
if not (csDesigning in ComponentState) and Assigned(FOnNavClick) then
FOnNavClick(Self, Index);
end;
procedure TOldSchoolDBNavigator.WMSetFocus(var Message: TWMSetFocus);
begin
Buttons[FocusedButton].Invalidate;
end;
procedure TOldSchoolDBNavigator.WMKillFocus(var Message: TWMKillFocus);
begin
Buttons[FocusedButton].Invalidate;
end;
procedure TOldSchoolDBNavigator.KeyDown(var Key: Word; Shift: TShiftState);
var
NewFocus: TNavigateBtn;
OldFocus: TNavigateBtn;
begin
OldFocus := FocusedButton;
case Key of
VK_RIGHT:
begin
if OldFocus < High(Buttons) then
begin
NewFocus := OldFocus;
repeat
NewFocus := Succ(NewFocus);
until (NewFocus = High(Buttons)) or (Buttons[NewFocus].Visible);
if Buttons[NewFocus].Visible then
begin
FocusedButton := NewFocus;
Buttons[OldFocus].Invalidate;
Buttons[NewFocus].Invalidate;
end;
end;
end;
VK_LEFT:
begin
NewFocus := FocusedButton;
repeat
if NewFocus > Low(Buttons) then
NewFocus := Pred(NewFocus);
until (NewFocus = Low(Buttons)) or (Buttons[NewFocus].Visible);
if NewFocus <> FocusedButton then
begin
FocusedButton := NewFocus;
Buttons[OldFocus].Invalidate;
Buttons[FocusedButton].Invalidate;
end;
end;
VK_SPACE:
begin
if Buttons[FocusedButton].Enabled then
Buttons[FocusedButton].Click;
end;
end;
end;
procedure TOldSchoolDBNavigator.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS;
end;
procedure TOldSchoolDBNavigator.DataChanged;
var
UpEnable, DnEnable: Boolean;
begin
UpEnable := Enabled and FDataLink.Active and not FDataLink.DataSet.BOF;
DnEnable := Enabled and FDataLink.Active and not FDataLink.DataSet.EOF;
Buttons[nbFirst].Enabled := UpEnable;
Buttons[nbPrior].Enabled := UpEnable;
Buttons[nbNext].Enabled := DnEnable;
Buttons[nbLast].Enabled := DnEnable;
Buttons[nbDelete].Enabled := Enabled and FDataLink.Active and
FDataLink.DataSet.CanModify and
not (FDataLink.DataSet.BOF and FDataLink.DataSet.EOF);
end;
procedure TOldSchoolDBNavigator.EditingChanged;
var
CanModify: Boolean;
begin
CanModify := Enabled and FDataLink.Active and FDataLink.DataSet.CanModify;
Buttons[nbInsert].Enabled := CanModify;
Buttons[nbEdit].Enabled := CanModify and not FDataLink.Editing;
Buttons[nbPost].Enabled := CanModify and FDataLink.Editing;
Buttons[nbCancel].Enabled := CanModify and FDataLink.Editing;
Buttons[nbRefresh].Enabled := CanModify;
end;
procedure TOldSchoolDBNavigator.ActiveChanged;
var
I: TNavigateBtn;
begin
if not (Enabled and FDataLink.Active) then
for I := Low(Buttons) to High(Buttons) do
Buttons[I].Enabled := False
else
begin
DataChanged;
EditingChanged;
end;
end;
procedure TOldSchoolDBNavigator.CMEnabledChanged(var Message: TMessage);
begin
inherited;
if not (csLoading in ComponentState) then
ActiveChanged;
end;
procedure TOldSchoolDBNavigator.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
if not (csLoading in ComponentState) then
ActiveChanged;
if Value <> nil then Value.FreeNotification(Self);
end;
function TOldSchoolDBNavigator.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TOldSchoolDBNavigator.Loaded;
var
W, H: Integer;
begin
inherited Loaded;
W := Width;
H := Height;
SetSize(W, H);
if (W <> Width) or (H <> Height) then
inherited SetBounds (Left, Top, W, H);
InitHints;
ActiveChanged;
end;
{TOSButton}
destructor TOSButton.Destroy;
begin
if FRepeatTimer <> nil then
FRepeatTimer.Free;
inherited Destroy;
end;
procedure TOSButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseDown (Button, Shift, X, Y);
if nsAllowTimer in FNavStyle then
begin
if FRepeatTimer = nil then
FRepeatTimer := TTimer.Create(Self);
FRepeatTimer.OnTimer := TimerExpired;
FRepeatTimer.Interval := InitRepeatPause;
FRepeatTimer.Enabled := True;
end;
end;
procedure TOSButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp (Button, Shift, X, Y);
if FRepeatTimer <> nil then
FRepeatTimer.Enabled := False;
end;
procedure TOSButton.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 TOSButton.Paint;
var
R: TRect;
begin
inherited Paint;
if (GetFocus = Parent.Handle) and
(FIndex = TOldSchoolDBNavigator (Parent).FocusedButton) then
begin
R := Bounds(0, 0, Width, Height);
InflateRect(R, -3, -3);
if FState = bsDown then
OffsetRect(R, 1, 1);
Canvas.Brush.Style := bsSolid;
Font.Color := clBtnShadow;
DrawFocusRect(Canvas.Handle, R);
end;
end;
{ TOSDataLink }
constructor TOSDataLink.Create(ANav: TOldSchoolDBNavigator);
begin
inherited Create;
FNavigator := ANav;
VisualControl := True;
end;
destructor TOSDataLink.Destroy;
begin
FNavigator := nil;
inherited Destroy;
end;
procedure TOSDataLink.EditingChanged;
begin
if FNavigator <> nil then FNavigator.EditingChanged;
end;
procedure TOSDataLink.DataSetChanged;
begin
if FNavigator <> nil then FNavigator.DataChanged;
end;
procedure TOSDataLink.ActiveChanged;
begin
if FNavigator <> nil then FNavigator.ActiveChanged;
end;
procedure Register;
begin
RegisterComponents('Standard', [TOldSchoolDBNavigator]);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -