📄 ehgrids.pas
字号:
end;
procedure TCustomGridEh.AdjustSize(Index, Amount: Longint; Rows: Boolean);
var
NewCur: TGridCoord;
OldRows, OldCols: Longint;
MovementX, MovementY: Longint;
MoveRect: TGridRect;
ScrollArea: TRect;
AbsAmount: Longint;
function DoSizeAdjust(var Count: Longint; var Extents: Pointer;
DefaultExtent: Integer; var Current: Longint): Longint;
var
I: Integer;
NewCount: Longint;
begin
NewCount := Count + Amount;
if NewCount < Index then InvalidOp(STooManyDeleted);
if (Amount < 0) and Assigned(Extents) then
begin
Result := 0;
for I := Index to Index - Amount - 1 do
Inc(Result, PIntArray(Extents)^[I]);
end
else
Result := Amount * DefaultExtent;
if Extents <> nil then
ModifyExtents(Extents, Index, Amount, DefaultExtent);
Count := NewCount;
if Current >= Index then
if (Amount < 0) and (Current < Index - Amount) then Current := Index
else Inc(Current, Amount);
end;
begin
if Amount = 0 then Exit;
NewCur := FCurrent;
OldCols := ColCount;
OldRows := RowCount;
MoveRect.Left := FixedCols;
MoveRect.Right := ColCount - 1;
MoveRect.Top := FixedRows;
MoveRect.Bottom := RowCount - 1;
MovementX := 0;
MovementY := 0;
AbsAmount := Amount;
if AbsAmount < 0 then AbsAmount := -AbsAmount;
if Rows then
begin
MovementY := DoSizeAdjust(FRowCount, FRowHeights, DefaultRowHeight, NewCur.Y);
MoveRect.Top := Index;
if Index + AbsAmount <= TopRow then MoveRect.Bottom := TopRow - 1;
end
else
begin
MovementX := DoSizeAdjust(FColCount, FColWidths, DefaultColWidth, NewCur.X);
MoveRect.Left := Index;
if Index + AbsAmount <= LeftCol then MoveRect.Right := LeftCol - 1;
end;
GridRectToScreenRect(MoveRect, ScrollArea, True);
if not IsRectEmpty(ScrollArea) then
begin
ScrollWindow(Handle, MovementX, MovementY, @ScrollArea, @ScrollArea);
UpdateWindow(Handle);
end;
SizeChanged(OldCols, OldRows);
if (NewCur.X <> FCurrent.X) or (NewCur.Y <> FCurrent.Y) then
MoveCurrent(NewCur.X, NewCur.Y, True, True);
end;
function TCustomGridEh.BoxRect(ALeft, ATop, ARight, ABottom: Longint): TRect;
var
GridRect: TGridRect;
begin
GridRect.Left := ALeft;
GridRect.Right := ARight;
GridRect.Top := ATop;
GridRect.Bottom := ABottom;
GridRectToScreenRect(GridRect, Result, False);
end;
procedure TCustomGridEh.DoExit;
begin
inherited DoExit;
if not (goAlwaysShowEditor in Options) then HideEditor;
end;
function TCustomGridEh.CellRect(ACol, ARow: Longint): TRect;
begin
Result := BoxRect(ACol, ARow, ACol, ARow);
end;
function TCustomGridEh.CanEditAcceptKey(Key: Char): Boolean;
begin
Result := True;
end;
function TCustomGridEh.CanGridAcceptKey(Key: Word; Shift: TShiftState): Boolean;
begin
Result := True;
end;
function TCustomGridEh.CanEditModify: Boolean;
begin
Result := FCanEditModify;
end;
function TCustomGridEh.CanEditShow: Boolean;
begin
Result := ([goRowSelect, goEditing] * Options = [goEditing]) and
FEditorMode and not (csDesigning in ComponentState) and HandleAllocated and
((goAlwaysShowEditor in Options) or IsActiveControl);
end;
function TCustomGridEh.IsActiveControl: Boolean;
var
H: Hwnd;
ParentForm: TCustomForm;
begin
Result := False;
ParentForm := GetParentForm(Self);
if Assigned(ParentForm) then
begin
if (ParentForm.ActiveControl = Self) then
Result := True
end
else
begin
H := GetFocus;
while IsWindow(H) and (Result = False) do
begin
if H = WindowHandle then
Result := True
else
H := GetParent(H);
end;
end;
end;
function TCustomGridEh.GetEditMask(ACol, ARow: Longint): string;
begin
Result := '';
end;
function TCustomGridEh.GetEditText(ACol, ARow: Longint): string;
begin
Result := '';
end;
procedure TCustomGridEh.SetEditText(ACol, ARow: Longint; const Value: string);
begin
end;
function TCustomGridEh.GetEditLimit: Integer;
begin
Result := 0;
end;
procedure TCustomGridEh.HideEditor;
begin
FEditorMode := False;
HideEdit;
end;
procedure TCustomGridEh.ShowEditor;
begin
FEditorMode := True;
UpdateEdit;
end;
procedure TCustomGridEh.ShowEditorChar(Ch: Char);
begin
ShowEditor;
if FInplaceEdit <> nil then
PostMessage(FInplaceEdit.Handle, WM_CHAR, Word(Ch), 0);
end;
procedure TCustomGridEh.InvalidateEditor;
begin
FInplaceCol := -1;
FInplaceRow := -1;
UpdateEdit;
end;
procedure TCustomGridEh.ReadColWidths(Reader: TReader);
var
I: Integer;
begin
with Reader do
begin
ReadListBegin;
for I := 0 to ColCount - 1 do ColWidths[I] := ReadInteger;
ReadListEnd;
end;
end;
procedure TCustomGridEh.ReadRowHeights(Reader: TReader);
var
I: Integer;
begin
with Reader do
begin
ReadListBegin;
for I := 0 to RowCount - 1 do RowHeights[I] := ReadInteger;
ReadListEnd;
end;
end;
procedure TCustomGridEh.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 TCustomGridEh.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 TCustomGridEh.DefineProperties(Filer: TFiler);
function DoColWidths: Boolean;
begin
if Filer.Ancestor <> nil then
Result := not CompareExtents(TCustomGridEh(Filer.Ancestor).FColWidths, FColWidths)
else
Result := FColWidths <> nil;
end;
function DoRowHeights: Boolean;
begin
if Filer.Ancestor <> nil then
Result := not CompareExtents(TCustomGridEh(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 TCustomGridEh.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 TCustomGridEh.ColumnMoved(FromIndex, ToIndex: Longint);
begin
end;
procedure TCustomGridEh.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 TCustomGridEh.RowMoved(FromIndex, ToIndex: Longint);
begin
end;
function TCustomGridEh.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 TCustomGridEh.MoveColRow(ACol, ARow: Longint; MoveAnchor,
Show: Boolean);
begin
MoveCurrent(ACol, ARow, MoveAnchor, Show);
end;
function TCustomGridEh.SelectCell(ACol, ARow: Longint): Boolean;
begin
Result := True;
end;
procedure TCustomGridEh.SizeChanged(OldColCount, OldRowCount: Longint);
begin
end;
function TCustomGridEh.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 TCustomGridEh.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;
{ StackAlloc allocates a 'small' block of memory from the stack by
decrementing SP. This provides the allocation speed of a local variable,
but the runtime size flexibility of heap allocated memory. }
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;
{ StackFree pops the memory allocated by StackAlloc off the stack.
- Calling StackFree is optional - SP will be restored when the calling routine
exits, but it's a good idea to free the stack allocated memory ASAP anyway.
- StackFree must be called in the same stack context as StackAlloc - not in
a subroutine or finally block.
- Multiple StackFree calls must occur in reverse order of their corresponding
StackAlloc calls.
- Built-in sanity checks guarantee that an improper call to StackFree will not
corrupt the stack. Worst case is that the stack block is not released until
the calling routine exits. }
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]) }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -