📄 unitasgrids.pas
字号:
StackFree(PointsList);
end;
{ Draw the cells in the four areas }
Sel := Selection;
FrameFlags1 := 0;
FrameFlags2 := 0;
if goFixedVertLine in Options then
begin
FrameFlags1 := BF_RIGHT;
FrameFlags2 := BF_LEFT;
end;
if goFixedHorzLine in Options then
begin
FrameFlags1 := FrameFlags1 or BF_BOTTOM;
FrameFlags2 := FrameFlags2 or BF_TOP;
end;
DrawCells(0, 0, 0, 0, Horz.FixedBoundary, Vert.FixedBoundary, FixedColor,
[gdFixed]);
DrawCells(LeftCol, 0, Horz.FixedBoundary - FColOffset, 0, Horz.GridBoundary,
//!! clip
Vert.FixedBoundary, FixedColor, [gdFixed]);
DrawCells(0, TopRow, 0, Vert.FixedBoundary, Horz.FixedBoundary,
Vert.GridBoundary, FixedColor, [gdFixed]);
DrawCells(LeftCol, TopRow, Horz.FixedBoundary - FColOffset, //!! clip
Vert.FixedBoundary, Horz.GridBoundary, Vert.GridBoundary, Color, []);
if not (csDesigning in ComponentState) and
(goRowSelect in Options) and DefaultDrawing and Focused then
begin
GridRectToScreenRect(GetSelection, FocRect, False);
if not UseRightToLeftAlignment then
Canvas.DrawFocusRect(FocRect)
else
begin
AFocRect := FocRect;
AFocRect.Left := FocRect.Right;
AFocRect.Right := FocRect.Left;
DrawFocusRect(Canvas.Handle, AFocRect);
end;
end;
{ Fill in area not occupied by cells }
if Horz.GridBoundary < Horz.GridExtent then
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(Rect(Horz.GridBoundary, 0, Horz.GridExtent,
Vert.GridBoundary));
end;
if Vert.GridBoundary < Vert.GridExtent then
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(Rect(0, Vert.GridBoundary, Horz.GridExtent,
Vert.GridExtent));
end;
end;
if UseRightToLeftAlignment then
ChangeGridOrientation(False);
end;
function TCustomASGrid.CalcCoordFromPoint(X, Y: Integer;
const DrawInfo: TGridDrawInfo): TGridCoord;
function DoCalc(const AxisInfo: TGridAxisDrawInfo; N: Integer): Integer;
var
I, Start, Stop: Longint;
Line: Integer;
begin
with AxisInfo do
begin
if N < FixedBoundary then
begin
Start := 0;
Stop := FixedCellCount - 1;
Line := 0;
end
else
begin
Start := FirstGridCell;
Stop := GridCellCount - 1;
Line := FixedBoundary;
end;
Result := -1;
for I := Start to Stop do
begin
Inc(Line, GetExtent(I) + EffectiveLineWidth);
if N < Line then
begin
Result := I;
Exit;
end;
end;
end;
end;
function DoCalcRightToLeft(const AxisInfo: TGridAxisDrawInfo; N: Integer):
Integer;
var
I, Start, Stop: Longint;
Line: Integer;
begin
N := ClientWidth - N;
with AxisInfo do
begin
if N < FixedBoundary then
begin
Start := 0;
Stop := FixedCellCount - 1;
Line := ClientWidth;
end
else
begin
Start := FirstGridCell;
Stop := GridCellCount - 1;
Line := FixedBoundary;
end;
Result := -1;
for I := Start to Stop do
begin
Inc(Line, GetExtent(I) + EffectiveLineWidth);
if N < Line then
begin
Result := I;
Exit;
end;
end;
end;
end;
begin
if not UseRightToLeftAlignment then
Result.X := DoCalc(DrawInfo.Horz, X)
else
Result.X := DoCalcRightToLeft(DrawInfo.Horz, X);
Result.Y := DoCalc(DrawInfo.Vert, Y);
end;
procedure TCustomASGrid.CalcDrawInfo(var DrawInfo: TGridDrawInfo);
begin
CalcDrawInfoXY(DrawInfo, ClientWidth, ClientHeight);
end;
procedure TCustomASGrid.CalcDrawInfoXY(var DrawInfo: TGridDrawInfo;
UseWidth, UseHeight: Integer);
procedure CalcAxis(var AxisInfo: TGridAxisDrawInfo; UseExtent: Integer);
var
I: Integer;
begin
with AxisInfo do
begin
GridExtent := UseExtent;
GridBoundary := FixedBoundary;
FullVisBoundary := FixedBoundary;
LastFullVisibleCell := FirstGridCell;
for I := FirstGridCell to GridCellCount - 1 do
begin
Inc(GridBoundary, GetExtent(I) + EffectiveLineWidth);
if GridBoundary > GridExtent + EffectiveLineWidth then
begin
GridBoundary := GridExtent;
Break;
end;
LastFullVisibleCell := I;
FullVisBoundary := GridBoundary;
end;
end;
end;
begin
CalcFixedInfo(DrawInfo);
CalcAxis(DrawInfo.Horz, UseWidth);
CalcAxis(DrawInfo.Vert, UseHeight);
end;
procedure TCustomASGrid.CalcFixedInfo(var DrawInfo: TGridDrawInfo);
procedure CalcFixedAxis(var Axis: TGridAxisDrawInfo; LineOptions:
TGridOptions;
FixedCount, FirstCell, CellCount: Integer; GetExtentFunc: TGetExtentsFunc);
var
I: Integer;
begin
with Axis do
begin
if LineOptions * Options = [] then
EffectiveLineWidth := 0
else
EffectiveLineWidth := GridLineWidth;
FixedBoundary := 0;
for I := 0 to FixedCount - 1 do
Inc(FixedBoundary, GetExtentFunc(I) + EffectiveLineWidth);
FixedCellCount := FixedCount;
FirstGridCell := FirstCell;
GridCellCount := CellCount;
GetExtent := GetExtentFunc;
end;
end;
begin
CalcFixedAxis(DrawInfo.Horz, [goFixedVertLine, goVertLine], FixedCols,
LeftCol, ColCount, GetColWidths);
CalcFixedAxis(DrawInfo.Vert, [goFixedHorzLine, goHorzLine], FixedRows,
TopRow, RowCount, GetRowHeights);
end;
{ Calculates the TopLeft that will put the given Coord in view }
function TCustomASGrid.CalcMaxTopLeft(const Coord: TGridCoord;
const DrawInfo: TGridDrawInfo): TGridCoord;
function CalcMaxCell(const Axis: TGridAxisDrawInfo; Start: Integer): Integer;
var
Line: Integer;
I, Extent: Longint;
begin
Result := Start;
with Axis do
begin
Line := GridExtent + EffectiveLineWidth;
for I := Start downto FixedCellCount do
begin
Extent := GetExtent(I);
if Extent > 0 then
begin
Dec(Line, Extent);
Dec(Line, EffectiveLineWidth);
if Line < FixedBoundary then
begin
if (Result = Start) and (GetExtent(Start) <= 0) then
Result := I;
Break;
end;
Result := I;
end;
end;
end;
end;
begin
Result.X := CalcMaxCell(DrawInfo.Horz, Coord.X);
Result.Y := CalcMaxCell(DrawInfo.Vert, Coord.Y);
end;
procedure TCustomASGrid.CalcSizingState(X, Y: Integer; var State:
TGridState;
var Index: Longint; var SizingPos, SizingOfs: Integer;
var FixedInfo: TGridDrawInfo);
procedure CalcAxisState(const AxisInfo: TGridAxisDrawInfo; Pos: Integer;
NewState: TGridState);
var
I, Line, Back, Range: Integer;
begin
if (NewState = gsColSizing) and UseRightToLeftAlignment then
Pos := ClientWidth - Pos;
with AxisInfo do
begin
Line := FixedBoundary;
Range := EffectiveLineWidth;
Back := 0;
if Range < 7 then
begin
Range := 7;
Back := (Range - EffectiveLineWidth) shr 1;
end;
for I := FirstGridCell to GridCellCount - 1 do
begin
Inc(Line, GetExtent(I));
if Line > GridBoundary then
Break;
if (Pos >= Line - Back) and (Pos <= Line - Back + Range) then
begin
State := NewState;
SizingPos := Line;
SizingOfs := Line - Pos;
Index := I;
Exit;
end;
Inc(Line, EffectiveLineWidth);
end;
if (GridBoundary = GridExtent) and (Pos >= GridExtent - Back)
and (Pos <= GridExtent) then
begin
State := NewState;
SizingPos := GridExtent;
SizingOfs := GridExtent - Pos;
Index := LastFullVisibleCell + 1;
end;
end;
end;
function XOutsideHorzFixedBoundary: Boolean;
begin
with FixedInfo do
if not UseRightToLeftAlignment then
Result := X > Horz.FixedBoundary
else
Result := X < ClientWidth - Horz.FixedBoundary;
end;
function XOutsideOrEqualHorzFixedBoundary: Boolean;
begin
with FixedInfo do
if not UseRightToLeftAlignment then
Result := X >= Horz.FixedBoundary
else
Result := X <= ClientWidth - Horz.FixedBoundary;
end;
var
EffectiveOptions: TGridOptions;
begin
State := gsNormal;
Index := -1;
EffectiveOptions := Options;
if csDesigning in ComponentState then
EffectiveOptions := EffectiveOptions + DesignOptionsBoost;
if [goColSizing, goRowSizing] * EffectiveOptions <> [] then
with FixedInfo do
begin
Vert.GridExtent := ClientHeight;
Horz.GridExtent := ClientWidth;
if (XOutsideHorzFixedBoundary) and (goColSizing in EffectiveOptions) then
begin
if Y >= Vert.FixedBoundary then
Exit;
CalcAxisState(Horz, X, gsColSizing);
end
else
if (Y > Vert.FixedBoundary) and (goRowSizing in EffectiveOptions) then
begin
if XOutsideOrEqualHorzFixedBoundary then
Exit;
CalcAxisState(Vert, Y, gsRowSizing);
end;
end;
end;
procedure TCustomASGrid.ChangeGridOrientation(RightToLeftOrientation:
Boolean);
var
Org: TPoint;
Ext: TPoint;
begin
if RightToLeftOrientation then
begin
Org := Point(ClientWidth, 0);
Ext := Point(-1, 1);
SetMapMode(Canvas.Handle, mm_Anisotropic);
SetWindowOrgEx(Canvas.Handle, Org.X, Org.Y, nil);
SetViewportExtEx(Canvas.Handle, ClientWidth, ClientHeight, nil);
SetWindowExtEx(Canvas.Handle, Ext.X * ClientWidth, Ext.Y * ClientHeight,
nil);
end
else
begin
Org := Point(0, 0);
Ext := Point(1, 1);
SetMapMode(Canvas.Handle, mm_Anisotropic);
SetWindowOrgEx(Canvas.Handle, Org.X, Org.Y, nil);
SetViewportExtEx(Canvas.Handle, ClientWidth, ClientHeight, nil);
SetWindowExtEx(Canvas.Handle, Ext.X * ClientWidth, Ext.Y * ClientHeight,
nil);
end;
end;
procedure TCustomASGrid.ChangeSize(NewColCount, NewRowCount: Longint);
var
OldColCount, OldRowCount: Longint;
OldDrawInfo: TGridDrawInfo;
procedure MinRedraw(const OldInfo, NewInfo: TGridAxisDrawInfo; Axis: Integer);
var
R: TRect;
First: Integer;
begin
First := Min(OldInfo.LastFullVisibleCell, NewInfo.LastFullVisibleCell);
// Get the rectangle around the leftmost or topmost cell in the target range.
R := CellRect(First and not Axis, First and Axis);
R.Bottom := Height;
R.Right := Width;
Windows.InvalidateRect(Handle, @R, False);
end;
procedure DoChange;
var
Coord: TGridCoord;
NewDrawInfo: TGridDrawInfo;
begin
if FColWidths <> nil then
UpdateExtents(FColWidths, ColCount, DefaultColWidth);
if FTabStops <> nil then
UpdateExtents(FTabStops, ColCount, Integer(True));
if FRowHeights <> nil then
UpdateExtents(FRowHeights, RowCount, DefaultRowHeight);
Coord := FCurrent;
if Row >= RowCount then
Coord.Y := RowCount - 1;
if Col >= ColCount then
Coord.X := ColCount - 1;
if (FCurrent.X <> Coord.X) or (FCurrent.Y <> Coord.Y) then
MoveCurrent(Coord.X, Coord.Y, True, True);
if (FAnchor.X <> Coord.X) or (FAnchor.Y <> Coord.Y) then
MoveAnchor(Coord);
if VirtualView or
(LeftCol <> OldDrawInfo.Horz.FirstGridCell) or
(TopRow <> OldDrawInfo.Vert.FirstGridCell) then
InvalidateGrid
else
if HandleAllocated then
begin
CalcDrawInfo(NewDrawInfo);
MinRedraw(OldDrawInfo.Horz, NewDrawInfo.Horz, 0);
MinRedraw(OldDrawInfo.Vert, NewDrawInfo.Vert, -1);
end;
UpdateScrollRange;
SizeChanged(OldColCount, OldRowCount);
end;
begin
if HandleAllocated then
CalcDrawInfo(OldDrawInfo);
OldColCount := FColCount;
OldRowCou
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -