📄 dbcgrids.pas
字号:
if StartIndex = -1 then
if GoForward then
StartIndex := List.Count - 1 else
StartIndex := 0;
I := StartIndex;
repeat
if GoForward then
begin
Inc(I);
if I = List.Count then I := 0;
end else
begin
if I = 0 then I := List.Count;
Dec(I);
end;
Result := List[I];
until (Result.CanFocus and Result.TabStop) or (I = StartIndex);
end;
WrapFlag := 0;
if GoForward then
begin
if I <= StartIndex then WrapFlag := 1;
end else
begin
if I >= StartIndex then WrapFlag := -1;
end;
finally
List.Free;
end;
end;
procedure TDBCtrlGrid.SelectNext(GoForward: Boolean);
var
WrapFlag: Integer;
ParentForm: TCustomForm;
ActiveControl, Control: TWinControl;
begin
ParentForm := GetParentForm(Self);
if ParentForm <> nil then
begin
ActiveControl := ParentForm.ActiveControl;
if ContainsControl(ActiveControl) then
begin
Control := FindNext(ActiveControl, GoForward, WrapFlag);
if not (FDataLink.DataSet.State in dsEditModes) then
FPanel.SetFocus;
try
if WrapFlag <> 0 then Scroll(WrapFlag, False);
except
ActiveControl.SetFocus;
raise;
end;
if not Control.CanFocus then
Control := FindNext(Control, GoForward, WrapFlag);
Control.SetFocus;
end;
end;
end;
procedure TDBCtrlGrid.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
ScrollWidth, ScrollHeight, NewPanelWidth, NewPanelHeight: Integer;
begin
ScrollWidth := 0;
ScrollHeight := 0;
if FOrientation = goVertical then
ScrollWidth := GetSystemMetrics(SM_CXVSCROLL) else
ScrollHeight := GetSystemMetrics(SM_CYHSCROLL);
NewPanelWidth := (AWidth - ScrollWidth) div FColCount;
NewPanelHeight := (AHeight - ScrollHeight) div FRowCount;
if NewPanelWidth < 1 then NewPanelWidth := 1;
if NewPanelHeight < 1 then NewPanelHeight := 1;
if (FPanelWidth <> NewPanelWidth) or (FPanelHeight <> NewPanelHeight) then
begin
FPanelWidth := NewPanelWidth;
FPanelHeight := NewPanelHeight;
Reset;
end;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TDBCtrlGrid.SetColCount(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 100 then Value := 100;
if FColCount <> Value then
begin
FColCount := Value;
AdjustSize;
end;
end;
procedure TDBCtrlGrid.SetDataSource(Value: TDataSource);
begin
FDataLink.DataSource := Value;
UpdateDataLinks(FPanel, True);
end;
procedure TDBCtrlGrid.SetEditMode(Value: Boolean);
var
Control: TWinControl;
begin
if GetEditMode <> Value then
if Value then
begin
Control := FPanel.FindNextControl(nil, True, True, False);
if Control <> nil then Control.SetFocus;
end else
SetFocus;
end;
procedure TDBCtrlGrid.SetOrientation(Value: TDBCtrlGridOrientation);
begin
if FOrientation <> Value then
begin
FOrientation := Value;
RecreateWnd;
AdjustSize;
end;
end;
procedure TDBCtrlGrid.SetPanelBorder(Value: TDBCtrlGridBorder);
begin
if FPanelBorder <> Value then
begin
FPanelBorder := Value;
Invalidate;
FPanel.Invalidate;
end;
end;
procedure TDBCtrlGrid.SetPanelHeight(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 65535 then Value := 65535;
if FPanelHeight <> Value then
begin
FPanelHeight := Value;
AdjustSize;
end;
end;
procedure TDBCtrlGrid.SetPanelIndex(Value: Integer);
begin
if FDataLink.Active and (Value < PanelCount) then
FDataLink.DataSet.MoveBy(Value - FPanelIndex);
end;
procedure TDBCtrlGrid.SetPanelWidth(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 65535 then Value := 65535;
if FPanelWidth <> Value then
begin
FPanelWidth := Value;
AdjustSize;
end;
end;
procedure TDBCtrlGrid.SetRowCount(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 100 then Value := 100;
if FRowCount <> Value then
begin
FRowCount := Value;
AdjustSize;
end;
end;
procedure TDBCtrlGrid.SetSelectedColor(Value: TColor);
begin
if Value <> FSelectedColor then
begin
FSelectedColor := Value;
FSelColorChanged := Value <> Color;
Invalidate;
FPanel.Invalidate;
end;
end;
procedure TDBCtrlGrid.UpdateDataLinks(Control: TControl; Inserting: Boolean);
var
I: Integer;
DataLink: TDataLink;
begin
if Inserting and not (csReplicatable in Control.ControlStyle) then
DatabaseError(SNotReplicatable);
DataLink := TDataLink(Control.Perform(CM_GETDATALINK, 0, 0));
if DataLink <> nil then
begin
DataLink.DataSourceFixed := False;
if Inserting then
begin
DataLink.DataSource := DataSource;
DataLink.DataSourceFixed := True;
end;
end;
if Control is TWinControl then
with TWinControl(Control) do
for I := 0 to ControlCount - 1 do
UpdateDataLinks(Controls[I], Inserting);
end;
procedure TDBCtrlGrid.UpdateScrollBar;
var
SIOld, SINew: TScrollInfo;
begin
if FDatalink.Active and HandleAllocated then
with FDatalink.DataSet do
begin
SIOld.cbSize := sizeof(SIOld);
SIOld.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, FScrollBarKind, SIOld);
SINew := SIOld;
if IsSequenced then
begin
SINew.nMin := 1;
SINew.nPage := Self.RowCount * Self.ColCount;
SINew.nMax := DWORD(RecordCount) + SINew.nPage - 1;
if State in [dsInactive, dsBrowse, dsEdit] then
SINew.nPos := RecNo;
end
else
begin
SINew.nMin := 0;
SINew.nPage := 0;
SINew.nMax := 4;
if BOF then SINew.nPos := 0
else if EOF then SINew.nPos := 4
else SINew.nPos := 2;
end;
if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
(SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then
SetScrollInfo(Self.Handle, FScrollBarKind, SINew, True);
end;
end;
procedure TDBCtrlGrid.WMLButtonDown(var Message: TWMLButtonDown);
var
I: Integer;
P: TPoint;
Window: HWnd;
begin
if FDataLink.Active then
begin
P := SmallPointToPoint(Message.Pos);
for I := 0 to FPanelCount - 1 do
if (I <> FPanelIndex) and PtInRect(GetPanelBounds(I), P) then
begin
FClicking := True;
try
SetPanelIndex(I);
finally
FClicking := False;
end;
P := ClientToScreen(P);
Window := WindowFromPoint(P);
if IsChild(FPanel.Handle, Window) then
begin
Windows.ScreenToClient(Window, P);
Message.Pos := PointToSmallPoint(P);
with TMessage(Message) do SendMessage(Window, Msg, WParam, LParam);
Exit;
end;
Break;
end;
end;
if AcquireFocus then
begin
if PointInPanel(Message.Pos) then
begin
EditMode := False;
Click;
end;
inherited;
end;
end;
procedure TDBCtrlGrid.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
if PointInPanel(Message.Pos) then DblClick;
inherited;
end;
procedure TDBCtrlGrid.WMHScroll(var Message: TWMHScroll);
begin
ScrollMessage(Message);
end;
procedure TDBCtrlGrid.WMVScroll(var Message: TWMVScroll);
begin
ScrollMessage(Message);
end;
procedure TDBCtrlGrid.WMEraseBkgnd(var Message: TMessage);
begin
Message.Result := 1;
end;
procedure TDBCtrlGrid.WMPaint(var Message: TWMPaint);
begin
PaintHandler(Message);
end;
procedure TDBCtrlGrid.WMSetFocus(var Message: TWMSetFocus);
begin
FFocused := True;
FPanel.Repaint;
end;
procedure TDBCtrlGrid.WMKillFocus(var Message: TWMKillFocus);
begin
FFocused := False;
FPanel.Repaint;
end;
procedure TDBCtrlGrid.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
procedure TDBCtrlGrid.WMSize(var Message: TMessage);
begin
inherited;
Invalidate;
end;
function GetShiftState: TShiftState;
begin
Result := [];
if GetKeyState(VK_SHIFT) < 0 then Include(Result, ssShift);
if GetKeyState(VK_CONTROL) < 0 then Include(Result, ssCtrl);
if GetKeyState(VK_MENU) < 0 then Include(Result, ssAlt);
end;
procedure TDBCtrlGrid.CMChildKey(var Message: TCMChildKey);
var
ShiftState: TShiftState;
GridKey: TDBCtrlGridKey;
begin
with Message do
if Sender <> Self then
begin
ShiftState := GetShiftState;
if Assigned(OnKeyDown) then OnKeyDown(Sender, CharCode, ShiftState);
GridKey := gkNull;
case CharCode of
VK_TAB:
if not (ssCtrl in ShiftState) and
(Sender.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTTAB = 0) then
if ssShift in ShiftState then
GridKey := gkPriorTab else
GridKey := gkNextTab;
VK_RETURN:
if (Sender.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) then
GridKey := gkEditMode;
VK_F2: GridKey := gkEditMode;
VK_ESCAPE: GridKey := gkCancel;
end;
if GridKey <> gkNull then
begin
DoKey(GridKey);
Result := 1;
Exit;
end;
end;
inherited;
end;
procedure TDBCtrlGrid.CMColorChanged(var Message: TMessage);
begin
inherited;
if not FSelColorChanged then
FSelectedColor := Color;
end;
{ Defer action processing to datalink }
function TDBCtrlGrid.ExecuteAction(Action: TBasicAction): Boolean;
begin
Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
FDataLink.ExecuteAction(Action);
end;
function TDBCtrlGrid.UpdateAction(Action: TBasicAction): Boolean;
begin
Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
FDataLink.UpdateAction(Action);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -