📄 dbngrids.pas
字号:
var
NewPanelIndex, NewPanelCount: Integer;
FocusedControl: TWinControl;
R: TRect;
begin
if csDesigning in ComponentState then
begin
NewPanelIndex := 0;
NewPanelCount := 1;
end else
if FDataLink.Active then
begin
NewPanelIndex := FDataLink.ActiveRecord;
NewPanelCount := FDataLink.RecordCount;
if NewPanelCount = 0 then NewPanelCount := 1;
end else
begin
NewPanelIndex := 0;
NewPanelCount := 0;
end;
FocusedControl := nil;
R := GetPanelBounds(NewPanelIndex);
if Reset or not HandleAllocated then FPanel.BoundsRect := R else
begin
FocusedControl := FindControl(GetFocus);
if (FocusedControl <> FPanel) and FPanel.ContainsControl(FocusedControl) then
FPanel.SetFocus else
FocusedControl := nil;
if NewPanelIndex <> FPanelIndex then
begin
SetWindowPos(FPanel.Handle, 0, R.Left, R.Top, R.Right - R.Left,
R.Bottom - R.Top, SWP_NOZORDER or SWP_NOREDRAW);
RedrawWindow(FPanel.Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
end;
FPanelIndex := NewPanelIndex;
FPanelCount := NewPanelCount;
FPanel.Visible := FPanelCount > 0;
FPanel.Invalidate;
if not Reset then
begin
Invalidate;
Update;
end;
UpdateScrollBar;
if (FocusedControl <> nil) and not FClicking and FocusedControl.CanFocus then
FocusedControl.SetFocus;
end;
procedure TDBnGrid.DestroyPanelBitmap;
begin
Dec(FBitmapCount);
if FBitmapCount = 0 then
begin
SelectObject(FPanelDC, FSaveBitmap);
DeleteDC(FPanelDC);
DeleteObject(FPanelBitmap);
end;
end;
procedure TDBnGrid.DoKey(Key: TDBnGridKey);
var
HInc, VInc: Integer;
begin
if FDataLink.Active then
begin
if FOrientation = goVertical then
begin
HInc := 1;
VInc := FColCount;
end else
begin
HInc := FRowCount;
VInc := 1;
end;
with FDataLink.DataSet do
case Key of
gkEditMode: EditMode := not EditMode;
gkPriorTab: SelectNext(False);
gkNextTab: SelectNext(True);
gkLeft: Scroll(-HInc, False);
gkRight: Scroll(HInc, False);
gkUp: Scroll(-VInc, False);
gkDown: Scroll(VInc, False);
gkScrollUp: Scroll(-VInc, True);
gkScrollDown: Scroll(VInc, True);
gkPageUp: Scroll(-FDataLink.BufferCount, True);
gkPageDown: Scroll(FDataLink.BufferCount, True);
gkHome: First;
gkEnd: Last;
gkInsert:
if FAllowInsert and CanModify then
begin
Insert;
EditMode := True;
end;
gkAppend:
if FAllowInsert and CanModify then
begin
Append;
EditMode := True;
end;
gkDelete:
if FAllowDelete and CanModify then
begin
Delete;
EditMode := False;
end;
gkCancel:
begin
Cancel;
EditMode := False;
end;
end;
end;
end;
procedure TDBnGrid.DrawPanel(DC: HDC; Index: Integer);
var
SaveActive: Integer;
R: TRect;
begin
R := GetPanelBounds(Index);
if Index < FPanelCount then
begin
SaveActive := FDataLink.ActiveRecord;
FDataLink.ActiveRecord := Index;
FPanel.PaintTo(FPanelDC, 0, 0);
FDataLink.ActiveRecord := SaveActive;
end else
DrawPanelBackground(FPanelDC, FPanel.ClientRect, True, False);
BitBlt(DC, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
FPanelDC, 0, 0, SRCCOPY);
end;
procedure TDBnGrid.DrawPanelBackground(DC: HDC; const R: TRect;
Erase, Selected: Boolean);
var
Brush: HBrush;
begin
if Erase then
begin
if Selected then FPanel.Color := FSelectedColor
else FPanel.Color := Color;
Brush := CreateSolidBrush(ColorToRGB(FPanel.Color));
FillRect(DC, R, Brush);
DeleteObject(Brush);
end;
if FPanelBorder = gbRaised then
DrawEdge(DC, PRect(@R)^, BDR_RAISEDINNER, BF_RECT);
end;
function TDBnGrid.GetChildParent: TComponent;
begin
Result := FPanel;
end;
procedure TDBnGrid.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin
FPanel.GetChildren(Proc, Root);
end;
function TDBnGrid.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
function TDBnGrid.GetEditMode: Boolean;
begin
Result := not Focused and ContainsControl(FindControl(GetFocus));
end;
function TDBnGrid.GetPanelBounds(Index: Integer): TRect;
var
Col, Row: Integer;
begin
if FOrientation = goVertical then
begin
Col := Index mod FColCount;
Row := Index div FColCount;
end else
begin
Col := Index div FRowCount;
Row := Index mod FRowCount;
end;
Result.Left := FPanelWidth * Col;
Result.Top := FPanelHeight * Row;
Result.Right := Result.Left + FPanelWidth;
Result.Bottom := Result.Top + FPanelHeight;
end;
procedure TDBnGrid.GetTabOrderList(List: TList);
begin
end;
procedure TDBnGrid.KeyDown(var Key: Word; Shift: TShiftState);
var
GridKey: TDBnGridKey;
begin
inherited KeyDown(Key, Shift);
GridKey := gkNull;
case Key of
VK_LEFT: GridKey := gkLeft;
VK_RIGHT: GridKey := gkRight;
VK_UP: GridKey := gkUp;
VK_DOWN: GridKey := gkDown;
VK_PRIOR: GridKey := gkPageUp;
VK_NEXT: GridKey := gkPageDown;
VK_HOME: GridKey := gkHome;
VK_END: GridKey := gkEnd;
VK_RETURN, VK_F2: GridKey := gkEditMode;
VK_INSERT:
if GetKeyState(VK_CONTROL) >= 0 then
GridKey := gkInsert else
GridKey := gkAppend;
VK_DELETE: if GetKeyState(VK_CONTROL) < 0 then GridKey := gkDelete;
VK_ESCAPE: GridKey := gkCancel;
end;
DoKey(GridKey);
end;
procedure TDBnGrid.PaintWindow(DC: HDC);
var
I: Integer;
Brush: HBrush;
begin
if csDesigning in ComponentState then
begin
FPanel.Update;
Brush := CreateHatchBrush(HS_BDIAGONAL, ColorToRGB(clBtnShadow));
SetBkColor(DC, ColorToRGB(Color));
FillRect(DC, ClientRect, Brush);
DeleteObject(Brush);
for I := 1 to FColCount * FRowCount - 1 do
DrawPanelBackground(DC, GetPanelBounds(I), False, False);
end else
begin
CreatePanelBitmap;
try
for I := 0 to FColCount * FRowCount - 1 do
if (FPanelCount <> 0) and (I = FPanelIndex) then
FPanel.Update else
DrawPanel(DC, I);
finally
DestroyPanelBitmap;
end;
end;
{ When width or height are not evenly divisible by panel size, fill the gaps }
if HandleAllocated then
begin
if (Height <> FPanel.Height * FRowCount) then
begin
Brush := CreateSolidBrush(ColorToRGB(Color));
FillRect(DC, Rect(0, FPanel.Height * FRowCount, Width, Height), Brush);
DeleteObject(Brush);
end;
if (Width <> FPanel.Width * FColCount) then
begin
Brush := CreateSolidBrush(ColorToRGB(Color));
FillRect(DC, Rect(FPanelWidth * FColCount, 0, Width, Height), Brush);
DeleteObject(Brush);
end;
end;
end;
procedure TDBnGrid.PaintPanel(Index: Integer);
begin
if Assigned(FOnPaintPanel) then FOnPaintPanel(Self, Index);
end;
function TDBnGrid.PointInPanel(const P: TSmallPoint): Boolean;
begin
Result := (FPanelCount > 0) and PtInRect(GetPanelBounds(FPanelIndex),
SmallPointToPoint(P));
end;
procedure TDBnGrid.ReadState(Reader: TReader);
begin
inherited ReadState(Reader);
FPanel.FixupTabList;
end;
procedure TDBnGrid.Reset;
begin
if csDesigning in ComponentState then
FDataLink.BufferCount := 1 else
FDataLink.BufferCount := FColCount * FRowCount;
DataSetChanged(True);
end;
procedure TDBnGrid.Scroll(Inc: Integer; ScrollLock: Boolean);
var
NewIndex, ScrollInc, Adjust: Integer;
begin
if FDataLink.Active and (Inc <> 0) then
with FDataLink.DataSet do
if State = dsInsert then
begin
UpdateRecord;
if Modified then Post else
if (Inc < 0) or not EOF then Cancel;
end else
begin
CheckBrowseMode;
DisableControls;
try
if ScrollLock then
if Inc > 0 then
MoveBy(Inc - MoveBy(Inc + FDataLink.BufferCount - FPanelIndex - 1))
else
MoveBy(Inc - MoveBy(Inc - FPanelIndex))
else
begin
NewIndex := FPanelIndex + Inc;
if (NewIndex >= 0) and (NewIndex < FDataLink.BufferCount) then
MoveBy(Inc)
else
if MoveBy(Inc) = Inc then
begin
if FOrientation = goVertical then
ScrollInc := FColCount else
ScrollInc := FRowCount;
if Inc > 0 then
Adjust := ScrollInc - 1 - NewIndex mod ScrollInc
else
Adjust := 1 - ScrollInc - (NewIndex + 1) mod ScrollInc;
MoveBy(-MoveBy(Adjust));
end;
end;
if (Inc = 1) and EOF and FAllowInsert and CanModify then Append;
finally
EnableControls;
end;
end;
end;
procedure TDBnGrid.ScrollMessage(var Message: TWMScroll);
var
Key: TDBnGridKey;
SI: TScrollInfo;
begin
if AcquireFocus then
begin
Key := gkNull;
case Message.ScrollCode of
SB_LINEUP: Key := gkScrollUp;
SB_LINEDOWN: Key := gkScrollDown;
SB_PAGEUP: Key := gkPageUp;
SB_PAGEDOWN: Key := gkPageDown;
SB_TOP: Key := gkHome;
SB_BOTTOM: Key := gkEnd;
SB_THUMBPOSITION:
if FDataLink.Active and FDataLink.DataSet.IsSequenced then
begin
SI.cbSize := sizeof(SI);
SI.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, FScrollBarKind, SI);
if SI.nTrackPos <= 1 then Key := gkHome
else if SI.nTrackPos >= FDataLink.DataSet.RecordCount then Key := gkEnd
else
begin
FDataLink.DataSet.RecNo := SI.nTrackPos;
Exit;
end;
end else
begin
case Message.Pos of
0: Key := gkHome;
1: Key := gkPageUp;
3: Key := gkPageDown;
4: Key := gkEnd;
end;
end;
end;
DoKey(Key);
end;
end;
function TDBnGrid.FindNext(StartControl: TWinControl; GoForward: Boolean;
var WrapFlag: Integer): TWinControl;
var
I, StartIndex: Integer;
List: TList;
begin
List := TList.Create;
try
StartIndex := 0;
I := 0;
Result := StartControl;
FPanel.GetTabOrderList(List);
if List.Count > 0 then
begin
StartIndex := List.IndexOf(StartControl);
if StartIndex = -1 then
if GoForward then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -