📄 rxdbctrl.pas
字号:
{$ENDIF RX_D4}
procedure TRxDBGrid.EditChanged(Sender: TObject);
begin
if Assigned(FOnEditChange) then FOnEditChange(Self);
end;
procedure TRxDBGrid.TopLeftChanged;
begin
if (dgRowSelect in Options) and DefaultDrawing then
GridInvalidateRow(Self, Self.Row);
inherited TopLeftChanged;
if FTracking then StopTracking;
if Assigned(FOnTopLeftChanged) then FOnTopLeftChanged(Self);
end;
procedure TRxDBGrid.StopTracking;
begin
if FTracking then begin
TrackButton(-1, -1);
FTracking := False;
MouseCapture := False;
end;
end;
procedure TRxDBGrid.TrackButton(X, Y: Integer);
var
Cell: TGridCoord;
NewPressed: Boolean;
I, Offset: Integer;
begin
Cell := MouseCoord(X, Y);
Offset := TitleOffset;
NewPressed := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y)) and
(FPressedCol = {$IFDEF WIN32} GetMasterColumn(Cell.X, Cell.Y) {$ELSE}
Cell.X {$ENDIF}) and (Cell.Y < Offset);
if FPressed <> NewPressed then begin
FPressed := NewPressed;
for I := 0 to Offset - 1 do
GridInvalidateRow(Self, I);
end;
end;
procedure TRxDBGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
Cell: TGridCoord;
MouseDownEvent: TMouseEvent;
EnableClick: Boolean;
begin
if not AcquireFocus then Exit;
if (ssDouble in Shift) and (Button = mbLeft) then begin
DblClick;
Exit;
end;
if Sizing(X, Y) then
inherited MouseDown(Button, Shift, X, Y)
else begin
Cell := MouseCoord(X, Y);
{$IFDEF RX_D4}
if (DragKind = dkDock) and (Cell.X < IndicatorOffset) and
(Cell.Y < TitleOffset) and (not (csDesigning in ComponentState)) then
begin
BeginDrag(False);
Exit;
end;
{$ENDIF}
if FTitleButtons and (Datalink <> nil) and Datalink.Active and
(Cell.Y < TitleOffset) and (Cell.X >= IndicatorOffset) and
not (csDesigning in ComponentState) then
begin
if (dgColumnResize in Options) and (Button = mbRight) then begin
Button := mbLeft;
FSwapButtons := True;
MouseCapture := True;
end
else if Button = mbLeft then begin
EnableClick := True;
CheckTitleButton(Cell.X - IndicatorOffset, Cell.Y, EnableClick);
if EnableClick then begin
MouseCapture := True;
FTracking := True;
{$IFDEF WIN32}
FPressedCol := GetMasterColumn(Cell.X, Cell.Y);
{$ELSE}
FPressedCol := Cell.X;
{$ENDIF}
TrackButton(X, Y);
end else Beep;
Exit;
end;
end;
if (Cell.X < FixedCols + IndicatorOffset) and Datalink.Active then begin
if (dgIndicator in Options) then
inherited MouseDown(Button, Shift, 1, Y)
else if Cell.Y >= TitleOffset then
if Cell.Y - Row <> 0 then Datalink.Dataset.MoveBy(Cell.Y - Row);
end
else inherited MouseDown(Button, Shift, X, Y);
MouseDownEvent := OnMouseDown;
if Assigned(MouseDownEvent) then MouseDownEvent(Self, Button, Shift, X, Y);
if not (((csDesigning in ComponentState) or (dgColumnResize in Options)) and
(Cell.Y < TitleOffset)) and (Button = mbLeft) then
begin
if MultiSelect and Datalink.Active then
with SelectedRows do begin
FSelecting := False;
if ssCtrl in Shift then
CurrentRowSelected := not CurrentRowSelected
else begin
Clear;
if FClearSelection then CurrentRowSelected := True;
end;
end;
end;
end;
end;
procedure TRxDBGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if FTracking then TrackButton(X, Y);
inherited MouseMove(Shift, X, Y);
end;
procedure TRxDBGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
Cell: TGridCoord;
ACol: Longint;
DoClick: Boolean;
begin
if FTracking and {$IFDEF WIN32} (FPressedCol <> nil) {$ELSE}
(FPressedCol >= 0) {$ENDIF} then
begin
Cell := MouseCoord(X, Y);
DoClick := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y))
and (Cell.Y < TitleOffset) and
{$IFDEF WIN32}
(FPressedCol = GetMasterColumn(Cell.X, Cell.Y));
{$ELSE}
(Cell.X = FPressedCol);
{$ENDIF}
StopTracking;
if DoClick then begin
ACol := Cell.X;
if (dgIndicator in Options) then Dec(ACol);
if (DataLink <> nil) and DataLink.Active and (ACol >= 0) and
(ACol < {$IFDEF WIN32} Columns.Count {$ELSE} FieldCount {$ENDIF}) then
begin
{$IFDEF WIN32}
DoTitleClick(FPressedCol.Index, FPressedCol.Field);
{$ELSE}
DoTitleClick(ACol, Fields[ACol]);
{$ENDIF}
end;
end;
end
else if FSwapButtons then begin
FSwapButtons := False;
MouseCapture := False;
if Button = mbRight then Button := mbLeft;
end;
inherited MouseUp(Button, Shift, X, Y);
end;
{$IFDEF WIN32}
procedure TRxDBGrid.WMRButtonUp(var Message: TWMMouse);
begin
if not (FGridState in [gsColMoving, gsRowMoving]) then
inherited
else if not (csNoStdEvents in ControlStyle) then
with Message do MouseUp(mbRight, KeysToShiftState(Keys), XPos, YPos);
end;
{$ENDIF}
procedure TRxDBGrid.WMCancelMode(var Message: TMessage);
begin
StopTracking;
inherited;
end;
type
THack = class(TWinControl);
procedure TRxDBGrid.WMChar(var Msg: TWMChar);
function DoKeyPress(var Msg: TWMChar): Boolean;
var
Form: TCustomForm;
Ch: Char;
begin
Result := True;
Form := GetParentForm(Self);
if (Form <> nil) and TForm(Form).KeyPreview and
THack(Form).DoKeyPress(Msg) then Exit;
with Msg do begin
if Assigned(FOnKeyPress) then begin
Ch := Char(CharCode);
FOnKeyPress(Self, Ch);
CharCode := Word(Ch);
end;
if Char(CharCode) = #0 then Exit;
end;
Result := False;
end;
begin
if EditorMode or not DoKeyPress(Msg) then inherited;
end;
procedure TRxDBGrid.KeyPress(var Key: Char);
begin
if EditorMode then inherited OnKeyPress := FOnKeyPress;
try
inherited KeyPress(Key);
finally
inherited OnKeyPress := nil;
end;
end;
procedure TRxDBGrid.DefaultDataCellDraw(const Rect: TRect; Field: TField;
State: TGridDrawState);
begin
DefaultDrawDataCell(Rect, Field, State);
end;
{$IFDEF WIN32}
function TRxDBGrid.GetMasterColumn(ACol, ARow: Longint): TColumn;
begin
if (dgIndicator in Options) then Dec(ACol, IndicatorOffset);
if (Datalink <> nil) and Datalink.Active and (ACol >= 0) and
(ACol < Columns.Count) then
begin
Result := Columns[ACol];
{$IFDEF RX_D4}
Result := ColumnAtDepth(Result, ARow);
{$ENDIF}
end
else Result := nil;
end;
{$ENDIF}
procedure TRxDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
AState: TGridDrawState);
{$IFDEF RX_D4}
function CalcTitleRect(Col: TColumn; ARow: Integer; var MasterCol: TColumn): TRect;
{ copied from Inprise's DbGrids.pas }
var
I,J: Integer;
InBiDiMode: Boolean;
DrawInfo: TGridDrawInfo;
begin
MasterCol := ColumnAtDepth(Col, ARow);
if MasterCol = nil then Exit;
I := DataToRawColumn(MasterCol.Index);
if I >= LeftCol then J := MasterCol.Depth
else begin
if (FixedCols > 0) and (MasterCol.Index < FixedCols) then begin
J := MasterCol.Depth;
end
else begin
I := LeftCol;
if Col.Depth > ARow then J := ARow
else J := Col.Depth;
end;
end;
Result := CellRect(I, J);
InBiDiMode := UseRightToLeftAlignment and (Canvas.CanvasOrientation = coLeftToRight);
for I := Col.Index to Columns.Count - 1 do begin
if ColumnAtDepth(Columns[I], ARow) <> MasterCol then Break;
if not InBiDiMode then begin
J := CellRect(DataToRawColumn(I), ARow).Right;
if J = 0 then Break;
Result.Right := Max(Result.Right, J);
end
else begin
J := CellRect(DataToRawColumn(I), ARow).Left;
if J >= ClientWidth then Break;
Result.Left := J;
end;
end;
J := Col.Depth;
if (J <= ARow) and (J < FixedRows - 1) then begin
CalcFixedInfo(DrawInfo);
Result.Bottom := DrawInfo.Vert.FixedBoundary -
DrawInfo.Vert.EffectiveLineWidth;
end;
end;
procedure DrawExpandBtn(var TitleRect, TextRect: TRect; InBiDiMode: Boolean;
Expanded: Boolean); { copied from Inprise's DbGrids.pas }
const
ScrollArrows: array [Boolean, Boolean] of Integer =
((DFCS_SCROLLRIGHT, DFCS_SCROLLLEFT), (DFCS_SCROLLLEFT, DFCS_SCROLLRIGHT));
var
ButtonRect: TRect;
I: Integer;
begin
I := GetSystemMetrics(SM_CXHSCROLL);
if ((TextRect.Right - TextRect.Left) > I) then begin
Dec(TextRect.Right, I);
ButtonRect := TitleRect;
ButtonRect.Left := TextRect.Right;
I := SaveDC(Canvas.Handle);
try
Canvas.FillRect(ButtonRect);
InflateRect(ButtonRect, -1, -1);
with ButtonRect do
IntersectClipRect(Canvas.Handle, Left, Top, Right, Bottom);
InflateRect(ButtonRect, 1, 1);
{ DrawFrameControl doesn't draw properly when orienatation has changed.
It draws as ExtTextOut does. }
if InBiDiMode then { stretch the arrows box }
Inc(ButtonRect.Right, GetSystemMetrics(SM_CXHSCROLL) + 4);
DrawFrameControl(Canvas.Handle, ButtonRect, DFC_SCROLL,
ScrollArrows[InBiDiMode, Expanded] or DFCS_FLAT);
finally
RestoreDC(Canvas.Handle, I);
end;
TitleRect.Right := ButtonRect.Left;
end;
end;
{$ENDIF RX_D4}
var
FrameOffs: Byte;
BackColor: TColor;
SortMarker: TSortMarker;
Indicator, ALeft: Integer;
Down: Boolean;
Bmp: TBitmap;
SavePen: TColor;
OldActive: Longint;
MultiSelected: Boolean;
FixRect: TRect;
TitleRect, TextRect: TRect;
AField: TField;
{$IFDEF RX_D4}
MasterCol: TColumn;
InBiDiMode: Boolean;
{$ENDIF}
{$IFDEF WIN32}
DrawColumn: TColumn;
const
EdgeFlag: array[Boolean] of UINT = (BDR_RAISEDINNER, BDR_SUNKENINNER);
{$ENDIF}
begin
inherited DrawCell(ACol, ARow, ARect, AState);
{$IFDEF RX_D4}
InBiDiMode := Canvas.CanvasOrientation = coRightToLeft;
{$ENDIF}
if (dgIndicator in Options) and (ACol = 0) and (ARow - TitleOffset >= 0)
and MultiSelect and (DataLink <> nil) and DataLink.Active and
(Datalink.DataSet.State = dsBrowse) then
begin { draw multiselect indicators if needed }
FixRect := ARect;
if ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
begin
InflateRect(FixRect, -1, -1);
FrameOffs := 1;
end
else FrameOffs := 2;
OldActive := DataLink.ActiveRecord;
try
Datalink.ActiveRecord := ARow - TitleOffset;
MultiSelected := ActiveRowSelected;
finally
Datalink.ActiveRecord := OldActive;
end;
if MultiSelected then begin
if (ARow - TitleOffset <> Datalink.ActiveRecord) then Indicator := 0
else Indicator := 1; { multiselected and current row }
{$IFDEF WIN32}
FMsIndicators.BkColor := FixedColor;
{$ELSE}
Canvas.Brush.Color := TitleColor;
Canvas.FillRect(FixRect);
{$ENDIF}
ALeft := FixRect.Right - FMsIndicators.Width - FrameOffs;
{$IFDEF RX_D4}
if InBiDiMode then Inc(ALeft);
{$ENDIF}
FMsIndicators.Draw(Self.Canvas, ALeft, (FixRect.Top +
FixRect.Bottom - FMsIndicators.Height) shr 1, Indicator);
end;
end
else if not (csLoading in ComponentState) and
(FTitleButtons {$IFDEF RX_D4} or (FixedCols > 0) {$ENDIF}) and
(gdFixed in AState) and (dgTitles in Options) and (ARow < TitleOffset) then
begin
SavePen := Canvas.Pen.Color;
try
Canvas.Pen.Color := clWindowFrame;
if (dgIndicator in Options) then Dec(ACol, IndicatorOffset);
AField := nil;
SortMarker := smNone;
{$IFDEF WIN32}
if (Datalink <> nil) and Datalink.Active and (ACol >= 0) and
(ACol < Columns.Count) then
begin
DrawColumn := Columns[ACol];
AField := DrawColumn.Field;
end
else DrawColumn := nil;
{$IFDEF RX_D4}
if Assigned(DrawColumn) and not DrawColumn.Showing then Exit;
TitleRect := CalcTitleRect(DrawColumn, ARow, MasterCol);
if TitleRect.Right < ARect.Right then
TitleRect.Right := ARect.Right;
if MasterCol = nil then
Exit
else if MasterCol <> DrawColumn then
AField := MasterCol.Field;
DrawColumn := MasterCol;
if ((dgColLines in Options) or FTitleButtons) and (ACol = FixedCols - 1) then
begin
if (ACol < Columns.Count - 1) and not (Columns[ACol + 1].Showing) then
begin
Canvas.MoveTo(TitleRect.Right, TitleRect.Top);
Canvas.LineTo(TitleRect.Right, TitleRect.Bottom);
end;
end;
if ((dgRowLines in Options) or FTitleButtons) and not MasterCol.Showing then
begin
Canvas.MoveTo(TitleRect.Left, TitleRect.Bottom);
Canvas.LineTo(TitleRect.Right, TitleRect.Bottom);
end;
{$ELSE}
TitleRect := ARect;
{$ENDIF RX_D4}
Down := FPressed and FTitleButtons and (FPressedCol = DrawColumn);
if FTitleButtons or ([dgRowLines, dgColLines] * Options =
[dgRowLines, dgColLines]) then
begin
DrawEdge(Canvas.Handle, TitleRect, EdgeFlag[Down], BF_BOTTOMRIGHT);
DrawEdge(Canvas.Handle, TitleRect, EdgeFlag[Down], BF_TO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -