📄 unitasgrids.pas
字号:
procedure TCustomASGrid.WriteColWidths(Writer: TWriter);
var
I: Integer;
begin
with Writer do
begin
WriteListBegin;
for I := 0 to ColCount - 1 do
WriteInteger(ColWidths[I]);
WriteListEnd;
end;
end;
procedure TCustomASGrid.WriteRowHeights(Writer: TWriter);
var
I: Integer;
begin
with Writer do
begin
WriteListBegin;
for I := 0 to RowCount - 1 do
WriteInteger(RowHeights[I]);
WriteListEnd;
end;
end;
procedure TCustomASGrid.DefineProperties(Filer: TFiler);
function DoColWidths: Boolean;
begin
if Filer.Ancestor <> nil then
Result := not CompareExtents(TCustomASGrid(Filer.Ancestor).FColWidths,
FColWidths)
else
Result := FColWidths <> nil;
end;
function DoRowHeights: Boolean;
begin
if Filer.Ancestor <> nil then
Result := not
CompareExtents(TCustomASGrid(Filer.Ancestor).FRowHeights,
FRowHeights)
else
Result := FRowHeights <> nil;
end;
begin
inherited DefineProperties(Filer);
if FSaveCellExtents then
with Filer do
begin
DefineProperty('ColWidths', ReadColWidths, WriteColWidths, DoColWidths);
DefineProperty('RowHeights', ReadRowHeights, WriteRowHeights,
DoRowHeights);
end;
end;
procedure TCustomASGrid.MoveColumn(FromIndex, ToIndex: Longint);
var
Rect: TGridRect;
begin
if FromIndex = ToIndex then
Exit;
if Assigned(FColWidths) then
begin
MoveExtent(FColWidths, FromIndex + 1, ToIndex + 1);
MoveExtent(FTabStops, FromIndex + 1, ToIndex + 1);
end;
MoveAdjust(FCurrent.X, FromIndex, ToIndex);
MoveAdjust(FAnchor.X, FromIndex, ToIndex);
MoveAdjust(FInplaceCol, FromIndex, ToIndex);
Rect.Top := 0;
Rect.Bottom := VisibleRowCount;
if FromIndex < ToIndex then
begin
Rect.Left := FromIndex;
Rect.Right := ToIndex;
end
else
begin
Rect.Left := ToIndex;
Rect.Right := FromIndex;
end;
InvalidateRect(Rect);
ColumnMoved(FromIndex, ToIndex);
if Assigned(FColWidths) then
ColWidthsChanged;
UpdateEdit;
end;
procedure TCustomASGrid.ColumnMoved(FromIndex, ToIndex: Longint);
begin
end;
procedure TCustomASGrid.MoveRow(FromIndex, ToIndex: Longint);
begin
if Assigned(FRowHeights) then
MoveExtent(FRowHeights, FromIndex + 1, ToIndex + 1);
MoveAdjust(FCurrent.Y, FromIndex, ToIndex);
MoveAdjust(FAnchor.Y, FromIndex, ToIndex);
MoveAdjust(FInplaceRow, FromIndex, ToIndex);
RowMoved(FromIndex, ToIndex);
if Assigned(FRowHeights) then
RowHeightsChanged;
UpdateEdit;
end;
procedure TCustomASGrid.RowMoved(FromIndex, ToIndex: Longint);
begin
end;
function TCustomASGrid.MouseCoord(X, Y: Integer): TGridCoord;
var
DrawInfo: TGridDrawInfo;
begin
CalcDrawInfo(DrawInfo);
Result := CalcCoordFromPoint(X, Y, DrawInfo);
if Result.X < 0 then
Result.Y := -1
else
if Result.Y < 0 then
Result.X := -1;
end;
procedure TCustomASGrid.MoveColRow(ACol, ARow: Longint; MoveAnchor,
Show: Boolean);
begin
MoveCurrent(ACol, ARow, MoveAnchor, Show);
end;
function TCustomASGrid.SelectCell(ACol, ARow: Longint): Boolean;
begin
Result := True;
end;
procedure TCustomASGrid.SizeChanged(OldColCount, OldRowCount: Longint);
begin
end;
function TCustomASGrid.Sizing(X, Y: Integer): Boolean;
var
DrawInfo: TGridDrawInfo;
State: TGridState;
Index: Longint;
Pos, Ofs: Integer;
begin
State := FGridState;
if State = gsNormal then
begin
CalcDrawInfo(DrawInfo);
CalcSizingState(X, Y, State, Index, Pos, Ofs, DrawInfo);
end;
Result := State <> gsNormal;
end;
procedure TCustomASGrid.TopLeftChanged;
begin
if FEditorMode and (FInplaceEdit <> nil) then
FInplaceEdit.UpdateLoc(CellRect(Col, Row));
end;
procedure FillDWord(var Dest; Count, Value: Integer); register;
asm
XCHG EDX, ECX
PUSH EDI
MOV EDI, EAX
MOV EAX, EDX
REP STOSD
POP EDI
end;
function StackAlloc(Size: Integer): Pointer; register;
asm
POP ECX { return address }
MOV EDX, ESP
ADD EAX, 3
AND EAX, not 3 // round up to keep ESP dword aligned
CMP EAX, 4092
JLE @@2
@@1:
SUB ESP, 4092
PUSH EAX { make sure we touch guard page, to grow stack }
SUB EAX, 4096
JNS @@1
ADD EAX, 4096
@@2:
SUB ESP, EAX
MOV EAX, ESP { function result = low memory address of block }
PUSH EDX { save original SP, for cleanup }
MOV EDX, ESP
SUB EDX, 4
PUSH EDX { save current SP, for sanity check (sp = [sp]) }
PUSH ECX { return to caller }
end;
procedure StackFree(P: Pointer); register;
asm
POP ECX { return address }
MOV EDX, DWORD PTR [ESP]
SUB EAX, 8
CMP EDX, ESP { sanity check #1 (SP = [SP]) }
JNE @@1
CMP EDX, EAX { sanity check #2 (P = this stack block) }
JNE @@1
MOV ESP, DWORD PTR [ESP+4] { restore previous SP }
@@1:
PUSH ECX { return to caller }
end;
procedure TCustomASGrid.Paint;
var
LineColor: TColor;
DrawInfo: TGridDrawInfo;
Sel: TGridRect;
UpdateRect: TRect;
AFocRect, FocRect: TRect;
PointsList: PIntArray;
StrokeList: PIntArray;
MaxStroke: Integer;
FrameFlags1, FrameFlags2: DWORD;
procedure DrawLines(DoHorz, DoVert: Boolean; Col, Row: Longint;
const CellBounds: array of Integer; OnColor, OffColor: TColor);
{ Cellbounds is 4 integers: StartX, StartY, StopX, StopY
Horizontal lines: MajorIndex = 0
Vertical lines: MajorIndex = 1 }
const
FlatPenStyle = PS_Geometric or PS_Solid or PS_EndCap_Flat or
PS_Join_Miter;
procedure DrawAxisLines(const AxisInfo: TGridAxisDrawInfo;
Cell, MajorIndex: Integer; UseOnColor: Boolean);
var
Line: Integer;
LogBrush: TLOGBRUSH;
Index: Integer;
Points: PIntArray;
StopMajor, StartMinor, StopMinor, StopIndex: Integer;
LineIncr: Integer;
begin
with Canvas, AxisInfo do
begin
if EffectiveLineWidth <> 0 then
begin
Pen.Width := GridLineWidth;
if UseOnColor then
Pen.Color := OnColor
else
Pen.Color := OffColor;
if Pen.Width > 1 then
begin
LogBrush.lbStyle := BS_Solid;
LogBrush.lbColor := Pen.Color;
LogBrush.lbHatch := 0;
Pen.Handle := ExtCreatePen(FlatPenStyle, Pen.Width, LogBrush, 0,
nil);
end;
Points := PointsList;
Line := CellBounds[MajorIndex] + EffectiveLineWidth shr 1 +
GetExtent(Cell);
//!!! ??? Line needs to be incremented for RightToLeftAlignment ???
if UseRightToLeftAlignment and (MajorIndex = 0) then
Inc(Line);
StartMinor := CellBounds[MajorIndex xor 1];
StopMinor := CellBounds[2 + (MajorIndex xor 1)];
StopMajor := CellBounds[2 + MajorIndex] + EffectiveLineWidth;
StopIndex := MaxStroke * 4;
Index := 0;
repeat
Points^[Index + MajorIndex] := Line; { MoveTo }
Points^[Index + (MajorIndex xor 1)] := StartMinor;
Inc(Index, 2);
Points^[Index + MajorIndex] := Line; { LineTo }
Points^[Index + (MajorIndex xor 1)] := StopMinor;
Inc(Index, 2);
// Skip hidden columns/rows. We don't have stroke slots for them
// A column/row with an extent of -EffectiveLineWidth is hidden
repeat
Inc(Cell);
LineIncr := GetExtent(Cell) + EffectiveLineWidth;
until (LineIncr > 0) or (Cell > LastFullVisibleCell);
Inc(Line, LineIncr);
until (Line > StopMajor) or (Cell > LastFullVisibleCell) or (Index >
StopIndex);
{ 2 integers per point, 2 points per line -> Index div 4 }
PolyPolyLine(Canvas.Handle, Points^, StrokeList^, Index shr 2);
end;
end;
end;
begin
if (CellBounds[0] = CellBounds[2]) or (CellBounds[1] = CellBounds[3]) then
Exit;
if not DoHorz then
begin
DrawAxisLines(DrawInfo.Vert, Row, 1, DoHorz);
DrawAxisLines(DrawInfo.Horz, Col, 0, DoVert);
end
else
begin
DrawAxisLines(DrawInfo.Horz, Col, 0, DoVert);
DrawAxisLines(DrawInfo.Vert, Row, 1, DoHorz);
end;
end;
procedure DrawCells(ACol, ARow: Longint; StartX, StartY, StopX, StopY:
Integer;
Color: TColor; IncludeDrawState: TGridDrawState);
var
CurCol, CurRow: Longint;
AWhere, Where, TempRect: TRect;
DrawState: TGridDrawState;
Focused: Boolean;
begin
CurRow := ARow;
Where.Top := StartY;
while (Where.Top < StopY) and (CurRow < RowCount) do
begin
CurCol := ACol;
Where.Left := StartX;
Where.Bottom := Where.Top + RowHeights[CurRow];
while (Where.Left < StopX) and (CurCol < ColCount) do
begin
Where.Right := Where.Left + ColWidths[CurCol];
if (Where.Right > Where.Left) and RectVisible(Canvas.Handle, Where) then
begin
DrawState := IncludeDrawState;
Focused := IsActiveControl;
if Focused and (CurRow = Row) and (CurCol = Col) then
Include(DrawState, gdFocused);
if PointInGridRect(CurCol, CurRow, Sel) then
Include(DrawState, gdSelected);
if not (gdFocused in DrawState) or not (goEditing in Options) or
not FEditorMode or (csDesigning in ComponentState) then
begin
if DefaultDrawing or (csDesigning in ComponentState) then
with Canvas do
begin
Font := Self.Font;
if (gdSelected in DrawState) and
(not (gdFocused in DrawState) or
([goDrawFocusSelected, goRowSelect] * Options <> [])) then
begin
Brush.Color := clHighlight;
Font.Color := clHighlightText;
end
else
Brush.Color := Color;
FillRect(Where);
end;
DrawCell(CurCol, CurRow, Where, DrawState);
if DefaultDrawing and (gdFixed in DrawState) and Ctl3D and
((FrameFlags1 or FrameFlags2) <> 0) then
begin
TempRect := Where;
if (FrameFlags1 and BF_RIGHT) = 0 then
Inc(TempRect.Right, DrawInfo.Horz.EffectiveLineWidth)
else
if (FrameFlags1 and BF_BOTTOM) = 0 then
Inc(TempRect.Bottom, DrawInfo.Vert.EffectiveLineWidth);
DrawEdge(Canvas.Handle, TempRect, BDR_RAISEDINNER, FrameFlags1);
DrawEdge(Canvas.Handle, TempRect, BDR_RAISEDINNER, FrameFlags2);
end;
if DefaultDrawing and not (csDesigning in ComponentState) and
(gdFocused in DrawState) and
([goEditing, goAlwaysShowEditor] * Options <>
[goEditing, goAlwaysShowEditor])
and not (goRowSelect in Options) then
begin
if not UseRightToLeftAlignment then
DrawFocusRect(Canvas.Handle, Where)
else
begin
AWhere := Where;
AWhere.Left := Where.Right;
AWhere.Right := Where.Left;
DrawFocusRect(Canvas.Handle, AWhere);
end;
end;
end;
end;
Where.Left := Where.Right + DrawInfo.Horz.EffectiveLineWidth;
Inc(CurCol);
end;
Where.Top := Where.Bottom + DrawInfo.Vert.EffectiveLineWidth;
Inc(CurRow);
end;
end;
begin
if UseRightToLeftAlignment then
ChangeGridOrientation(True);
UpdateRect := Canvas.ClipRect;
CalcDrawInfo(DrawInfo);
with DrawInfo do
begin
if (Horz.EffectiveLineWidth > 0) or (Vert.EffectiveLineWidth > 0) then
begin
{ Draw the grid line in the four areas (fixed, fixed), (variable, fixed),
(fixed, variable) and (variable, variable) }
LineColor := clSilver;
MaxStroke := Max(Horz.LastFullVisibleCell - LeftCol + FixedCols,
Vert.LastFullVisibleCell - TopRow + FixedRows) + 3;
PointsList := StackAlloc(MaxStroke * sizeof(TPoint) * 2);
StrokeList := StackAlloc(MaxStroke * sizeof(Integer));
FillDWord(StrokeList^, MaxStroke, 2);
if ColorToRGB(Color) = clSilver then
LineColor := clGray;
DrawLines(goFixedHorzLine in Options, goFixedVertLine in Options,
0, 0, [0, 0, Horz.FixedBoundary, Vert.FixedBoundary], clBlack,
FixedColor);
DrawLines(goFixedHorzLine in Options, goFixedVertLine in Options,
LeftCol, 0, [Horz.FixedBoundary, 0, Horz.GridBoundary,
Vert.FixedBoundary], clBlack, FixedColor);
DrawLines(goFixedHorzLine in Options, goFixedVertLine in Options,
0, TopRow, [0, Vert.FixedBoundary, Horz.FixedBoundary,
Vert.GridBoundary], clBlack, FixedColor);
DrawLines(goHorzLine in Options, goVertLine in Options, LeftCol,
TopRow, [Horz.FixedBoundary, Vert.FixedBoundary, Horz.GridBoundary,
Vert.GridBoundary], LineColor, Color);
StackFree(StrokeList);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -