📄 rm_grid.pas
字号:
unit RM_Grid;
interface
uses Messages, Windows, SysUtils, Classes, Graphics, Menus, Controls, Forms,
StdCtrls, RM_Class;
const
MaxCustomExtents = MaxListSize;
MaxShortInt = High(ShortInt);
type
ERMInvalidGridOperation = class(Exception);
{ Internal grid types }
TRMGetExtentsFunc = function(Index: Longint): Integer of object;
TRMGridAxisDrawInfo = record
EffectiveLineWidth: Integer;
FixedBoundary: Integer;
GridBoundary: Integer;
GridExtent: Integer;
LastFullVisibleCell: Longint;
FullVisBoundary: Integer;
FixedCellCount: Integer;
FirstGridCell: Integer;
GridCellCount: Integer;
GetExtent: TRMGetExtentsFunc;
end;
TRMGridDrawInfo = record
Horz, Vert: TRMGridAxisDrawInfo;
end;
TRMGridState = (rmgsNormal, rmgsSelecting, rmgsRowSizing, rmgsColSizing, rmgsRowMoving, rmgsColMoving);
TRMGridMovement = rmgsRowMoving..rmgsColMoving;
TRMGridEx = class;
TRMGridOption = (rmgoFixedVertLine, rmgoFixedHorzLine, rmgoVertLine, rmgoHorzLine,
rmgoRangeSelect, rmgoDrawFocusSelected, rmgoRowSizing, rmgoColSizing, rmgoThumbTracking);
TRMGridOptions = set of TRMGridOption;
TRMGridDrawState = set of (rmgdSelected, rmgdFocused, rmgdFixed);
TRMGridScrollDirection = set of (rmsdLeft, rmsdRight, rmsdUp, rmsdDown);
TRMSelectCellEvent = procedure(Sender: TObject; ACol, ARow: Longint; var CanSelect: Boolean) of object;
TRMDrawCellEvent = procedure(Sender: TObject; ACol, ARow: Longint;
Rect: TRect; State: TRMGridDrawState) of object;
{ TRMCellInfo }
TRMCellInfo = class(TPersistent)
private
FMutilCell: Boolean;
FFont: TFont;
FAutoWordBreak: Boolean;
FHorizAlign: TRMAlignment;
FVertAlign: TRMLayout;
FView: TRMView;
function GetText: string;
procedure SetText(const Value: string);
function GetFillColor: TColor;
procedure SetFillColor(Value: TColor);
function GetFont: TFont;
procedure SetFont(Value: TFont);
function GetAutoWordBreak: Boolean;
procedure SetAutowordBreak(Value: Boolean);
function GetHorizAlign: TRMAlignment;
procedure SetHorizAlign(Value: TRMAlignment);
function GetVertAlign: TRMLayout;
procedure SetVertAlign(Value: TRMLayout);
protected
FStartCol: Integer;
FStartRow: Integer;
FEndCol: Integer;
FEndRow: Integer;
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure AssignFromCell(Source: TRMCellInfo);
procedure ReCreateView(Typ: Byte; const ClassName: string);
published
property StartCol: Integer read FStartCol;
property StartRow: Integer read FStartRow;
property EndCol: Integer read FEndCol;
property EndRow: Integer read FendRow;
property MutilCell: Boolean read FMutilCell write FMutilCell;
property FillColor: TColor read GetFillColor write SetFillColor;
property Text: string read GetText write SetText;
property Font: TFont read GetFont write SetFont;
property AutoWordBreak: Boolean read GetAutoWordBreak write SetAutoWordBreak;
property HorizAlign: TRMAlignment read GetHorizAlign write SetHorizAlign;
property VertAlign: TRMLayout read GetVertAlign write SetVertAlign;
property View: TRMView read FView;
end;
TRMRowCell = class
private
FList: TList;
function GetItem(Index: Integer): TRMCellInfo;
public
constructor Create(ARow, AColCount: Integer; AGrid: TRMGridEx);
destructor Destroy; override;
procedure Clear;
procedure Add(ARow, ACol: Integer; AGrid: TRMGridEx);
procedure Delete(Index: Integer);
property Items[Index: Integer]: TRMCellInfo read GetItem;
end;
TRMCells = class
private
FList: TList;
FGrid: TRMGridEx;
function GetItem(Index: Integer): TRMRowCell;
protected
public
constructor Create(AColCount, ARowCount: Integer; AGrid: TRMGridEx);
destructor Destroy; override;
procedure Clear;
procedure Add(AIndex: Integer);
procedure Insert(AIndex: Integer);
procedure Delete(AIndex: Integer);
property Items[Index: Integer]: TRMRowCell read GetItem;
end;
{ TRMGridEx }
TRMGridEx = class(TCustomControl)
private
FAutoDraw: Boolean;
FAnchor: TPoint;
FBorderStyle: TBorderStyle;
FCanEditModify: Boolean;
FColCount: Longint;
FColWidths: Pointer;
FCurrent: TPoint;
FDefaultColWidth: Integer;
FDefaultRowHeight: Integer;
FFixedCols: Integer;
FFixedRows: Integer;
FFixedColor: TColor;
FGridLineWidth: Integer;
FOptions: TRMGridOptions;
FRowCount: Longint;
FRowHeights: Pointer;
FScrollBars: TScrollStyle;
FTopLeft: TPoint;
FSizingIndex: Longint;
FSizingPos, FSizingOfs: Integer;
FMoveIndex, FMovePos: Longint;
FHitTest: TPoint;
FColOffset: Integer;
FDefaultDrawing: Boolean;
FPressed: Boolean;
FPressedCell: TPoint;
FCells: TRMCells;
FTitleColor: TColor;
FHighLightColor: TColor;
FHighLightTextColor: TColor;
FFocusedTitleColor: TColor;
FFixedLineColor: TColor;
FClientLineColor: TColor;
FGridCanCopyMove: Boolean;
FGridCanFill: Boolean;
FAutoUpdate: Boolean;
FNewRgn, FOldRgn: HRGN;
FHaveClip: Integer;
FOnSelectCell: TRMSelectCellEvent;
procedure ShowFrame(t: TRMView; aCanvas: TCanvas; x, y, x1, y1: Integer);
function CalcCoordFromPoint(X, Y: Integer; const DrawInfo: TRMGridDrawInfo): TPoint;
procedure CalcDrawInfoXY(var DrawInfo: TRMGridDrawInfo; UseWidth, UseHeight: Integer);
function CalcMaxTopLeft(const Coord: TPoint; const DrawInfo: TRMGridDrawInfo): TPoint;
procedure CancelMode;
procedure ChangeSize(NewColCount, NewRowCount: Longint);
procedure ClampInView(const Coord: TPoint);
procedure DrawSizingLine(const DrawInfo: TRMGridDrawInfo);
procedure DrawMove;
procedure FocusCell(ACol, ARow: Longint; MoveAnchor: Boolean);
procedure GridRectToScreenRect(GridRect: TRect; var ScreenRect: TRect; IncludeLine: Boolean);
procedure Initialize;
procedure ModifyScrollBar(ScrollBar, ScrollCode, Pos: Cardinal; UseRightToLeft: Boolean);
procedure MoveAdjust(var CellPos: Longint; FromIndex, ToIndex: Longint);
procedure MoveAnchor(const NewAnchor: TPoint);
procedure MoveCurrent(ACol, ARow: Longint; MoveAnchor, Show: Boolean);
procedure MoveTopLeft(ALeft, ATop: Longint);
procedure ResizeCol(Index: Longint; OldSize, NewSize: Integer);
procedure ResizeRow(Index: Longint; OldSize, NewSize: Integer);
procedure MoveColumn(FromIndex, ToIndex: Longint);
procedure MoveRow(FromIndex, ToIndex: Longint);
procedure SelectionMoved(const OldSel: TRect);
procedure ScrollDataInfo(DX, DY: Integer; var DrawInfo: TRMGridDrawInfo);
procedure TopLeftMoved(const OldTopLeft: TPoint);
procedure UpdateScrollPos;
procedure UpdateScrollRange;
function GetColWidths(Index: Longint): Integer;
function GetRowHeights(Index: Longint): Integer;
function GetSelection: TRect;
function GetVisibleColCount: Integer;
function GetVisibleRowCount: Integer;
function IsActiveControl: Boolean;
procedure SetBorderStyle(Value: TBorderStyle);
function GetCol: Longint;
procedure SetCol(Value: Longint);
procedure SetColCount(Value: Longint);
procedure SetColWidths(Index: Longint; Value: Integer);
procedure SetFixedColor(Value: TColor);
function GetLeftCol: LongInt;
procedure SetLeftCol(Value: Longint);
function GetRow: Longint;
procedure SetRow(Value: Longint);
procedure SetRowCount(Value: Longint);
procedure SetRowHeights(Index: Longint; Value: Integer);
procedure SetSelection(Value: TRect);
function GetTopRow: Longint;
procedure SetTopRow(Value: Longint);
procedure CMCancelMode(var Msg: TMessage); message CM_CANCELMODE;
procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST;
procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
procedure WMCancelMode(var Msg: TWMCancelMode); message WM_CANCELMODE;
procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
procedure WMSize(var Msg: TWMSize); message WM_SIZE;
procedure WMTimer(var Msg: TWMTimer); message WM_TIMER;
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
procedure TrackButton(X, Y: Integer);
procedure SetDefaultColWidth(Value: Integer);
procedure SetDefaultRowHeight(Value: Integer);
procedure ColCountChange(Value: Integer);
procedure RowCountChange(Value: Integer);
procedure SetClipRect(ACanvas: TCanvas; ClipR: TRect);
procedure RestoreClipRect(ACanvas: TCanvas);
function CellInMerge(ACol, ARow: Integer): Boolean;
function GetCell(ACol, ARow: Integer): TRMCellInfo;
procedure RestoreCells(DestRestoreRect: TRect);
procedure InitCell(AGrid: TRMGridEx; ACell: TRMCellInfo; ACol, ARow: Integer);
protected
FGridState: TRMGridState;
FSaveCellExtents: Boolean;
VirtualView: Boolean;
procedure CalcDrawInfo(var DrawInfo: TRMGridDrawInfo);
procedure CalcFixedInfo(var DrawInfo: TRMGridDrawInfo);
procedure CalcSizingState(X, Y: Integer; var State: TRMGridState;
var Index: Longint; var SizingPos, SizingOfs: Integer; var FixedInfo: TRMGridDrawInfo); virtual;
procedure CreateParams(var Params: TCreateParams); override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
function BoxRect(ALeft, ATop, ARight, ABottom: Longint): TRect;
function CellRect(ACol, ARow: Longint): TRect;
{$IFDEF Delphi4}
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
{$ENDIF}
function GetGridWidth: Integer;
function GetGridHeight: Integer;
procedure DrawCell(ACol, ARow: Longint; ARect, AClipRect: TRect; AState: TRMGridDrawState);
procedure MoveColRow(ACol, ARow: Longint; MoveAnchor, Show: Boolean);
function SelectCell(ACol, ARow: Longint): Boolean; virtual;
procedure SizeChanged(OldColCount, OldRowCount: Longint); dynamic;
function Sizing(X, Y: Integer): Boolean;
procedure ScrollData(DX, DY: Integer);
procedure InvalidateCell(ACol, ARow: Longint);
procedure InvalidateCol(ACol: Longint);
procedure InvalidateRow(ARow: Longint);
procedure TopLeftChanged; dynamic;
procedure TimedScroll(Direction: TRMGridScrollDirection); dynamic;
procedure Paint; override;
procedure ColWidthsChanged; dynamic;
procedure RowHeightsChanged; dynamic;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property GridHeight: Integer read GetGridHeight;
property GridWidth: Integer read GetGridWidth;
property HitTest: TPoint read FHitTest;
property LeftCol: Longint read GetLeftCol write SetLeftCol;
property TopRow: Longint read GetTopRow write SetTopRow;
property ParentColor default False;
property VisibleColCount: Integer read GetVisibleColCount;
property VisibleRowCount: Integer read GetVisibleRowCount;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure CreateViewsName;
function GetCellInfo(ACol, Arow: Integer): TRMCellinfo;
procedure InvalidateGrid;
procedure InvalidateRect(ARect: TRect);
function MouseCoord(X, Y: Integer): TPoint;
procedure MergeCell(FirstCol, FirstRow, EndCol, EndRow: Integer);
procedure MergeSelection;
procedure SplitCell(ARect: TRect);
procedure MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
function GetCellRect(ACell: TRMCellInfo): TRect;
procedure InsertColumn(ACol: Integer);
procedure InsertRow(ARow: Integer);
procedure DeleteColumn(ACol: Integer); virtual;
procedure DeleteRow(ARow: Integer); virtual;
procedure LoadFromFile(aFileName: string);
procedure SaveToFile(aFileName: string);
procedure LoadFromStream(aStream: TStream; OldVersion: Boolean);
procedure SaveToStream(aStream: TStream);
property Selection: TRect read GetSelection write SetSelection;
property Cells[ACol, ARow: Integer]: TRMCellInfo read GetCell;
property ColWidths[Index: Longint]: Integer read GetColWidths write SetColWidths;
property RowHeights[Index: Longint]: Integer read GetRowHeights write SetRowHeights;
property Col: Longint read GetCol write SetCol;
property Row: Longint read GetRow write SetRow;
property AutoDraw: Boolean read FAutoDraw write FAutoDraw;
published
property ColCount: Longint read FColCount write SetColCount;
property RowCount: Longint read FRowCount write SetRowCount;
property DefaultDrawing: Boolean read FDefaultDrawing;
property Options: TRMGridOptions read FOptions;
property DefaultColWidth: Integer read FDefaultColWidth write SetDefaultColWidth;
property DefaultRowHeight: Integer read FDefaultRowHeight write SetDefaultRowHeight;
property FixedColor: TColor read FFixedColor write SetFixedColor;
property Color default clWindow;
property TabStop default True;
property PopupMenu;
property Font;
property OnClick;
property OnDblClick;
property OnSelectCell: TRMSelectCellEvent read FOnSelectCell write FOnSelectCell;
end;
implementation
uses Math, Consts, RM_Utils, RM_Const, RM_Const1;
type
THackView = class(TRMView)
end;
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
constructor TRMCellInfo.Create;
begin
inherited Create;
FFont := TFont.Create;
FView := RMCreateObject(gtMemo, '');
end;
destructor TRMCellInfo.Destroy;
begin
FFont.Free;
FView.Free;
inherited Destroy;
end;
procedure TRMCellInfo.Assign(Source: TPersistent);
begin
if Source is TRMCellInfo then
begin
FStartCol := TRMCellInfo(Source).StartCol;
FStartRow := TRMCellInfo(Source).StartRow;
FEndCol := TRMCellInfo(Source).EndCol;
FEndRow := TRMCellInfo(Source).EndRow;
FMutilCell := TRMCellInfo(Source).MutilCell;
FFont.Assign(TRMCellInfo(Source).Font);
FAutoWordBreak := TRMCellInfo(Source).FAutoWordBreak;
FHorizAlign := TRMCellInfo(Source).FHorizAlign;
FVertAlign := TRMCellInfo(Source).FVertAlign;
ReCreateView(TRMCellInfo(Source).FView.Typ, TRMCellInfo(Source).FView.ClassName);
FView.Assign(TRMCellInfo(Source).FView);
end;
end;
procedure TRMCellInfo.AssignFromCell(Source: TRMCellInfo);
begin
FStartCol := Source.StartCol;
FStartRow := Source.StartRow;
FEndCol := Source.EndCol;
FEndRow := Source.EndRow;
FMutilCell := Source.MutilCell;
end;
procedure TRMCellInfo.ReCreateView(Typ: Byte; const ClassName: string);
var
t: TRMView;
begin
if (FView.Typ <> gtAddin) and (FView.Typ = Typ) then Exit;
if (FView.Typ = gtAddin) and (AnsiCompareText(FView.ClassName, ClassName) = 0) then Exit;
t := RMCreateObject(Typ, ClassName);
t.LeftFrame := FView.LeftFrame;
t.RightFrame := FView.RightFrame;
t.TopFrame := FView.TopFrame;
t.BottomFrame := View.BottomFrame;
t.FillColor := FView.FillColor;
t.CreateUniqueName;
FView.Free;
FView := t;
end;
function TRMCellInfo.GetText: string;
var
i: Integer;
begin
if View is TRMMemoView then
begin
Result := '';
for i := 0 to FView.Memo.Count - 1 do
begin
if i > 0 then
Result := Result + #13#10;
Result := Result + FView.Memo[i];
end;
end
else
Result := THackView(View).GetViewCommon;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -