1494 lines
42 KiB
ObjectPascal
1494 lines
42 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvGrids.PAS, released on 2002-07-04.
|
|
|
|
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 2001,2002 SGB Software
|
|
All Rights Reserved.
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.sourceforge.net
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id: JvGrids.pas 10896 2006-08-18 05:20:11Z marquardt $
|
|
|
|
unit JvGrids;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF UNITVERSIONING}
|
|
JclUnitVersioning,
|
|
{$ENDIF UNITVERSIONING}
|
|
Classes, Windows, Messages, Controls, Graphics, StdCtrls, Forms, Grids,
|
|
{$IFDEF VisualCLX}
|
|
Qt,
|
|
{$ENDIF VisualCLX}
|
|
JvConsts, JvVCL5Utils, JvAppStorage, JvFormPlacement, JvComponent, JvExGrids;
|
|
|
|
type
|
|
TAcceptKeyEvent = function(Sender: TObject; var Key: Char): Boolean of object;
|
|
TEditLimitEvent = procedure(Sender: TObject; var MaxLength: Integer) of object;
|
|
TEditShowEvent = procedure(Sender: TObject; ACol, ARow: Longint;
|
|
var AllowEdit: Boolean) of object;
|
|
TFixedCellClickEvent = procedure(Sender: TObject; ACol, ARow: Longint) of object;
|
|
TFixedCellCheckEvent = procedure(Sender: TObject; ACol, ARow: Longint;
|
|
var Enabled: Boolean) of object;
|
|
|
|
TInplaceEditStyle = TEditStyle;
|
|
|
|
const
|
|
ieSimple = esSimple;
|
|
ieEllipsis = esEllipsis;
|
|
iePickList = esPickList;
|
|
|
|
type
|
|
TEditAlignEvent = procedure(Sender: TObject; ACol, ARow: Longint;
|
|
var Alignment: TAlignment) of object;
|
|
TPicklistEvent = procedure(Sender: TObject; ACol, ARow: Longint;
|
|
PickList: TStrings) of object;
|
|
TEditStyleEvent = procedure(Sender: TObject; ACol, ARow: Longint;
|
|
var Style: TInplaceEditStyle) of object;
|
|
|
|
TJvDrawGrid = class(TJvExDrawGrid)
|
|
private
|
|
FNoUpdateData: Boolean;
|
|
FFixedCellsButtons: Boolean;
|
|
FPressedCell: TGridCoord;
|
|
FCellDown: TGridCoord;
|
|
FPressed: Boolean;
|
|
FTracking: Boolean;
|
|
FSwapButtons: Boolean;
|
|
FDefaultDrawing: Boolean;
|
|
FIniLink: TJvIniLink;
|
|
FOnColumnSized: TNotifyEvent;
|
|
FOnRowSized: TNotifyEvent;
|
|
FOnAcceptEditKey: TAcceptKeyEvent;
|
|
FOnGetEditLimit: TEditLimitEvent;
|
|
FOnEditChange: TNotifyEvent;
|
|
FOnShowEditor: TEditShowEvent;
|
|
FOnCancelEdit: TNotifyEvent;
|
|
FOnFixedCellClick: TFixedCellClickEvent;
|
|
FOnCheckButton: TFixedCellCheckEvent;
|
|
FOnChangeFocus: TNotifyEvent;
|
|
{$IFDEF VCL}
|
|
FOnHScroll: TNotifyEvent;
|
|
FOnVScroll: TNotifyEvent;
|
|
{$ENDIF VCL}
|
|
FOnGetEditAlign: TEditAlignEvent;
|
|
FOnEditButtonClick: TNotifyEvent;
|
|
FOnGetPicklist: TPicklistEvent;
|
|
FOnGetEditStyle: TEditStyleEvent;
|
|
FDrawButtons: Boolean;
|
|
FBeepOnError: Boolean;
|
|
function GetStorage: TJvFormPlacement;
|
|
procedure SetStorage(Value: TJvFormPlacement);
|
|
procedure IniSave(Sender: TObject);
|
|
procedure IniLoad(Sender: TObject);
|
|
procedure SetFixedButtons(Value: Boolean);
|
|
procedure StopTracking;
|
|
procedure TrackButton(X, Y: Integer);
|
|
{$IFDEF VCL}
|
|
function IsActiveControl: Boolean;
|
|
procedure WMCommand(var Msg: TWMCommand); message WM_COMMAND;
|
|
procedure WMCancelMode(var Msg: TMessage); message WM_CANCELMODE;
|
|
procedure WMLButtonDblClk(var Msg: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
|
|
procedure WMRButtonUp(var Msg: TWMMouse); message WM_RBUTTONUP;
|
|
procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
|
|
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
|
|
{$ENDIF VCL}
|
|
procedure SetDrawButtons(const Value: Boolean);
|
|
protected
|
|
function SelectCell(ACol, ARow: Longint): Boolean; override;
|
|
procedure FocusKilled(NextWnd: THandle); override;
|
|
procedure FocusSet(PrevWnd: THandle); override;
|
|
|
|
function CanEditAcceptKey(Key: Char): Boolean; override;
|
|
function CanEditShow: Boolean; override;
|
|
function GetEditLimit: Integer; override;
|
|
procedure TopLeftChanged; override;
|
|
procedure ColWidthsChanged; override;
|
|
procedure RowHeightsChanged; override;
|
|
procedure CallDrawCellEvent(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState);
|
|
procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState); override;
|
|
procedure DoDrawCell(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState); virtual;
|
|
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;
|
|
{$IFDEF VCL}
|
|
procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
procedure SetEditText(ACol, ARow: Longint; const Value: WideString); override;
|
|
{$ENDIF VisualCLX}
|
|
function CreateEditor: TInplaceEdit; override;
|
|
procedure Paint; override;
|
|
procedure EditChanged(Sender: TObject); dynamic;
|
|
procedure DoFixedCellClick(ACol, ARow: Longint); dynamic;
|
|
procedure CheckFixedCellButton(ACol, ARow: Longint;
|
|
var Enabled: Boolean); dynamic;
|
|
procedure EditButtonClick; dynamic;
|
|
function GetEditAlignment(ACol, ARow: Longint): TAlignment; dynamic;
|
|
function GetEditStyle(ACol, ARow: Longint): TEditStyle; override;
|
|
procedure GetPickList(ACol, ARow: Longint; PickList: TStrings); dynamic;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure DrawStr(ARect: TRect; const S: string; Align: TAlignment);
|
|
procedure DrawMultiline(ARect: TRect; const S: string; Align: TAlignment);
|
|
procedure DrawPicture(ARect: TRect; Graphic: TGraphic);
|
|
procedure DrawMasked(ARect: TRect; Graphic: TBitmap);
|
|
procedure InvalidateCell(ACol, ARow: Longint);
|
|
procedure InvalidateCol(ACol: Longint);
|
|
procedure InvalidateRow(ARow: Longint);
|
|
procedure LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
procedure SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
procedure Load;
|
|
procedure Save;
|
|
property InplaceEditor;
|
|
published
|
|
property BeepOnError: Boolean read FBeepOnError write FBeepOnError default True;
|
|
property DefaultRowHeight default 18;
|
|
property DrawButtons: Boolean read FDrawButtons write SetDrawButtons;
|
|
property Options default [goFixedVertLine, goFixedHorzLine, goVertLine,
|
|
goHorzLine, goDrawFocusSelected, goColSizing];
|
|
property IniStorage: TJvFormPlacement read GetStorage write SetStorage;
|
|
property FixedButtons: Boolean read FFixedCellsButtons write SetFixedButtons
|
|
default False;
|
|
property OnAcceptEditKey: TAcceptKeyEvent read FOnAcceptEditKey
|
|
write FOnAcceptEditKey;
|
|
property OnCancelEdit: TNotifyEvent read FOnCancelEdit write FOnCancelEdit;
|
|
property OnCheckButton: TFixedCellCheckEvent read FOnCheckButton
|
|
write FOnCheckButton;
|
|
property OnChangeFocus: TNotifyEvent read FOnChangeFocus write FOnChangeFocus;
|
|
property OnFixedCellClick: TFixedCellClickEvent read FOnFixedCellClick
|
|
write FOnFixedCellClick;
|
|
property OnColumnSized: TNotifyEvent read FOnColumnSized
|
|
write FOnColumnSized;
|
|
property OnRowSized: TNotifyEvent read FOnRowSized write FOnRowSized;
|
|
property OnGetEditLimit: TEditLimitEvent read FOnGetEditLimit write FOnGetEditLimit;
|
|
property OnEditChange: TNotifyEvent read FOnEditChange write FOnEditChange;
|
|
property OnShowEditor: TEditShowEvent read FOnShowEditor write FOnShowEditor;
|
|
property OnGetEditAlign: TEditAlignEvent read FOnGetEditAlign write FOnGetEditAlign;
|
|
property OnGetEditStyle: TEditStyleEvent read FOnGetEditStyle write FOnGetEditStyle;
|
|
property OnGetPicklist: TPicklistEvent read FOnGetPicklist write FOnGetPicklist;
|
|
property OnEditButtonClick: TNotifyEvent read FOnEditButtonClick write FOnEditButtonClick;
|
|
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnParentColorChange;
|
|
{$IFDEF VCL}
|
|
property OnVerticalScroll: TNotifyEvent read FOnVScroll write FOnVScroll;
|
|
property OnHorizontalScroll: TNotifyEvent read FOnHScroll write FOnHScroll;
|
|
{$ENDIF VCL}
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
const
|
|
UnitVersioning: TUnitVersionInfo = (
|
|
RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_32/run/JvGrids.pas $';
|
|
Revision: '$Revision: 10896 $';
|
|
Date: '$Date: 2006-08-18 07:20:11 +0200 (ven., 18 août 2006) $';
|
|
LogPath: 'JVCL\run'
|
|
);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, Math,
|
|
{$IFDEF HAS_UNIT_TYPES}
|
|
Types,
|
|
{$ENDIF HAS_UNIT_TYPES}
|
|
JvJCLUtils, JvJVCLUtils;
|
|
|
|
const
|
|
MaxCustomExtents = MaxListSize;
|
|
MaxShortInt = High(ShortInt);
|
|
|
|
type
|
|
PIntArray = ^TIntArray;
|
|
TIntArray = array [0..MaxCustomExtents] of Integer;
|
|
|
|
//=== { TJvGridPopupListBox } ================================================
|
|
|
|
type
|
|
TJvGridPopupListBox = class;
|
|
|
|
TJvInplaceEdit = class(TJvExInplaceEdit)
|
|
private
|
|
{$IFDEF VCL}
|
|
FAlignment: TAlignment;
|
|
{$ENDIF VCL}
|
|
FButtonWidth: Integer;
|
|
FPickList: TJvGridPopupListBox;
|
|
FActiveList: TWinControl;
|
|
FEditStyle: TInplaceEditStyle;
|
|
FListVisible: Boolean;
|
|
FTracking: Boolean;
|
|
FPressed: Boolean;
|
|
procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure SetEditStyle(Value: TInplaceEditStyle);
|
|
procedure StopTracking;
|
|
procedure TrackButton(X, Y: Integer);
|
|
{$IFDEF VCL}
|
|
procedure SetAlignment(Value: TAlignment);
|
|
procedure CMCancelMode(var Msg: TCMCancelMode); message CM_CANCELMODE;
|
|
procedure WMCancelMode(var Msg: TMessage); message WM_CANCELMODE;
|
|
procedure WMLButtonDblClk(var Msg: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
|
|
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
|
|
procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
|
|
{$ENDIF VCL}
|
|
protected
|
|
procedure FocusKilled(NextWnd: THandle); override;
|
|
{$IFDEF VCL}
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
{$ENDIF VCL}
|
|
procedure BoundsChanged; override;
|
|
procedure CloseUp(Accept: Boolean);
|
|
procedure DoDropDownKeys(var Key: Word; Shift: TShiftState);
|
|
procedure DropDown;
|
|
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;
|
|
{$IFDEF VCL}
|
|
procedure PaintWindow(DC: HDC); override;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
procedure Painting(Sender: QObjectH; EventRegion: QRegionH); override;
|
|
{$ENDIF VisualCLX}
|
|
procedure UpdateContents; override;
|
|
{$IFDEF VCL}
|
|
procedure WndProc(var Message: TMessage); override;
|
|
{$ENDIF VCL}
|
|
property ActiveList: TWinControl read FActiveList write FActiveList;
|
|
property PickList: TJvGridPopupListBox read FPickList;
|
|
public
|
|
constructor Create(Owner: TComponent); override;
|
|
{$IFDEF VCL}
|
|
property Alignment: TAlignment read FAlignment write SetAlignment;
|
|
{$ENDIF VCL}
|
|
property EditStyle: TInplaceEditStyle read FEditStyle write SetEditStyle;
|
|
end;
|
|
|
|
TJvGridPopupListBox = class(TJvPopupListBox)
|
|
protected
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
end;
|
|
|
|
procedure TJvGridPopupListBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
TJvInplaceEdit(Owner).CloseUp((X >= 0) and (Y >= 0) and (X < Width) and (Y < Height));
|
|
end;
|
|
|
|
//=== { TJvInplaceEdit } =====================================================
|
|
|
|
constructor TJvInplaceEdit.Create(Owner: TComponent);
|
|
begin
|
|
inherited Create(Owner);
|
|
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
|
|
// FEditStyle := esSimple;
|
|
FEditStyle := ieSimple;
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvInplaceEdit.CreateParams(var Params: TCreateParams);
|
|
const
|
|
Alignments: array[TAlignment] of Cardinal = (ES_LEFT, ES_RIGHT, ES_CENTER);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
with Params do
|
|
Style := Style or Alignments[FAlignment];
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvInplaceEdit.BoundsChanged;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
SetRect(R, 2, 2, Width - 2, Height);
|
|
if FEditStyle <> ieSimple then
|
|
Dec(R.Right, FButtonWidth);
|
|
{$IFDEF VCL}
|
|
SendMessage(Handle, EM_SETRECTNP, 0, Longint(@R));
|
|
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
|
|
if SysLocale.FarEast then
|
|
SetImeCompositionWindow(Font, R.Left, R.Top);
|
|
{$ENDIF VCL}
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.CloseUp(Accept: Boolean);
|
|
var
|
|
ListValue: string;
|
|
begin
|
|
if FListVisible then
|
|
begin
|
|
{$IFDEF VCL}
|
|
if GetCapture <> 0 then
|
|
SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
|
|
{$ENDIF VCL}
|
|
if FPickList.ItemIndex > -1 then
|
|
ListValue := FPickList.Items[FPickList.ItemIndex];
|
|
SetWindowPos(FActiveList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
|
|
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
|
|
FListVisible := False;
|
|
Invalidate;
|
|
if Accept and EditCanModify then
|
|
Text := ListValue;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.DoDropDownKeys(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
case Key of
|
|
VK_UP, VK_DOWN:
|
|
if ssAlt in Shift then
|
|
begin
|
|
if FListVisible then
|
|
CloseUp(True)
|
|
else
|
|
DropDown;
|
|
Key := 0;
|
|
end;
|
|
VK_RETURN, VK_ESCAPE:
|
|
if FListVisible and not (ssAlt in Shift) then
|
|
begin
|
|
CloseUp(Key = VK_RETURN);
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.DropDown;
|
|
const
|
|
MaxListCount = 8;
|
|
var
|
|
P: TPoint;
|
|
Y, J, I: Integer;
|
|
begin
|
|
if not FListVisible and Assigned(FActiveList) then
|
|
begin
|
|
FPickList.Width := Width;
|
|
FPickList.Color := Color;
|
|
FPickList.Font := Font;
|
|
FPickList.Items.Clear;
|
|
with TJvDrawGrid(Grid) do
|
|
GetPickList(Col, Row, FPickList.Items);
|
|
FPickList.Height := Min(FPickList.Items.Count, MaxListCount) *
|
|
FPickList.ItemHeight + 4;
|
|
FPickList.ItemIndex := FPickList.Items.IndexOf(Text);
|
|
J := FPickList.ClientWidth;
|
|
for I := 0 to FPickList.Items.Count - 1 do
|
|
begin
|
|
Y := FPickList.Canvas.TextWidth(FPickList.Items[I]);
|
|
if Y > J then
|
|
J := Y;
|
|
end;
|
|
if FPickList.Items.Count > MaxListCount then
|
|
Inc(J, GetSystemMetrics(SM_CXVSCROLL));
|
|
FPickList.ClientWidth := J;
|
|
P := Parent.ClientToScreen(Point(Left, Top));
|
|
Y := P.Y + Height;
|
|
if Y + FActiveList.Height > Screen.Height then
|
|
Y := P.Y - FActiveList.Height;
|
|
SetWindowPos(FActiveList.Handle, HWND_TOP, P.X, Y, 0, 0,
|
|
SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
|
|
FListVisible := True;
|
|
Invalidate;
|
|
Windows.SetFocus(Handle);
|
|
end;
|
|
end;
|
|
|
|
type
|
|
THackedWinControl = class(TWinControl);
|
|
|
|
procedure TJvInplaceEdit.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if (EditStyle = ieEllipsis) and (Key = VK_RETURN) and (Shift = [ssCtrl]) then
|
|
begin
|
|
TJvDrawGrid(Grid).EditButtonClick;
|
|
{$IFDEF VCL}
|
|
KillMessage(Handle, WM_CHAR);
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Key := 0;
|
|
{$ENDIF VisualCLX}
|
|
end
|
|
else
|
|
inherited KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.ListMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if Button = mbLeft then
|
|
CloseUp(PtInRect(FActiveList.ClientRect, Point(X, Y)));
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
if (Button = mbLeft) and (FEditStyle <> ieSimple) and
|
|
PtInRect(Rect(Width - FButtonWidth, 0, Width, Height), Point(X, Y)) then
|
|
begin
|
|
if FListVisible then
|
|
CloseUp(False)
|
|
else
|
|
begin
|
|
MouseCapture := True;
|
|
FTracking := True;
|
|
TrackButton(X, Y);
|
|
if Assigned(FActiveList) then
|
|
DropDown;
|
|
end;
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
ListPos: TPoint;
|
|
MousePos: TSmallPoint;
|
|
begin
|
|
if FTracking then
|
|
begin
|
|
TrackButton(X, Y);
|
|
if FListVisible then
|
|
begin
|
|
ListPos := FActiveList.ScreenToClient(ClientToScreen(Point(X, Y)));
|
|
if PtInRect(FActiveList.ClientRect, ListPos) then
|
|
begin
|
|
StopTracking;
|
|
MousePos := PointToSmallPoint(ListPos);
|
|
{$IFDEF VCL}
|
|
SendMessage(FActiveList.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
THackedWinControl(FActiveList).MouseDown(mbLeft, Shift, MousePos.X , MousePos.Y);
|
|
{$ENDIF VisualCLX}
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
inherited MouseMove(Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
WasPressed: Boolean;
|
|
begin
|
|
WasPressed := FPressed;
|
|
StopTracking;
|
|
if (Button = mbLeft) and (FEditStyle = ieEllipsis) and WasPressed then
|
|
TJvDrawGrid(Grid).EditButtonClick;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvInplaceEdit.PaintWindow(DC: HDC);
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
procedure TJvInplaceEdit.Painting(Sender: QObjectH; EventRegion: QRegionH);
|
|
{$ENDIF VisualCLX}
|
|
const
|
|
LeftOffs = 3;
|
|
var
|
|
R: TRect;
|
|
Flags: Integer;
|
|
W, G, I: Integer;
|
|
{$IFDEF VisualCLX}
|
|
DC: QPainterH;
|
|
{$ENDIF VisualCLX}
|
|
begin
|
|
{$IFDEF VisualCLX}
|
|
DC := QPainter_create(QWidget_to_QPaintDevice(Handle), Handle);
|
|
try
|
|
QPainter_setClipRegion(DC, EventRegion);
|
|
QPainter_setClipping(DC, not QRegion_isEmpty(EventRegion));
|
|
{$ENDIF VisualCLX}
|
|
|
|
if FEditStyle <> ieSimple then
|
|
begin
|
|
SetRect(R, Width - FButtonWidth, 0, Width, Height);
|
|
Flags := 0;
|
|
if FEditStyle in [iePickList] then
|
|
begin
|
|
if FActiveList = nil then
|
|
Flags := DFCS_INACTIVE
|
|
else
|
|
if FPressed then
|
|
Flags := DFCS_FLAT or DFCS_PUSHED;
|
|
DrawFrameControl(DC, R, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
|
|
end
|
|
else
|
|
begin { esEllipsis }
|
|
if FPressed then
|
|
Flags := BF_FLAT;
|
|
DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_MIDDLE or Flags);
|
|
W := 2;
|
|
G := (FButtonWidth - LeftOffs * 2 - 3 * W) div 2;
|
|
if G <= 0 then
|
|
G := 1;
|
|
if G > 3 then
|
|
G := 3;
|
|
Flags := R.Left + (FButtonWidth - 3 * W - 2 * G) div 2 + Ord(FPressed);
|
|
I := R.Top + (ClientHeight - W) div 2 {+ Ord(FPressed)};
|
|
PatBlt(DC, Flags, I, W, W, BLACKNESS);
|
|
PatBlt(DC, Flags + G + W, I, W, W, BLACKNESS);
|
|
PatBlt(DC, Flags + 2 * G + 2 * W, I, W, W, BLACKNESS);
|
|
end;
|
|
ExcludeClipRect(DC, R.Left, R.Top, R.Right, R.Bottom);
|
|
end;
|
|
{$IFDEF VisualCLX}
|
|
finally
|
|
QPainter_destroy(DC);
|
|
end;
|
|
{$ENDIF VisualCLX}
|
|
inherited {PaintWindow(DC);}
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvInplaceEdit.SetAlignment(Value: TAlignment);
|
|
begin
|
|
if FAlignment <> Value then
|
|
begin
|
|
FAlignment := Value;
|
|
RecreateWnd;
|
|
end;
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvInplaceEdit.SetEditStyle(Value: TInplaceEditStyle);
|
|
begin
|
|
if Value = FEditStyle then
|
|
Exit;
|
|
FEditStyle := Value;
|
|
case Value of
|
|
iePickList:
|
|
begin
|
|
if FPickList = nil then
|
|
begin
|
|
FPickList := TJvGridPopupListBox.Create(Self);
|
|
FPickList.Visible := False;
|
|
FPickList.Parent := Self;
|
|
FPickList.OnMouseUp := ListMouseUp;
|
|
{$IFDEF VCL}
|
|
FPickList.IntegralHeight := True;
|
|
{$ENDIF VCL}
|
|
FPickList.ItemHeight := 11;
|
|
end;
|
|
FActiveList := FPickList;
|
|
end;
|
|
else
|
|
FActiveList := nil;
|
|
end;
|
|
Repaint;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.StopTracking;
|
|
begin
|
|
if FTracking then
|
|
begin
|
|
TrackButton(-1, -1);
|
|
FTracking := False;
|
|
MouseCapture := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.TrackButton(X, Y: Integer);
|
|
var
|
|
NewState: Boolean;
|
|
R: TRect;
|
|
begin
|
|
SetRect(R, ClientWidth - FButtonWidth, 0, ClientWidth, ClientHeight);
|
|
NewState := PtInRect(R, Point(X, Y));
|
|
if FPressed <> NewState then
|
|
begin
|
|
FPressed := NewState;
|
|
{$IFDEF VCL}
|
|
InvalidateRect(Handle, @R, False);
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
InvalidateRect(R, False);
|
|
{$ENDIF VisualCLX}
|
|
end;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.UpdateContents;
|
|
var
|
|
SaveChanged: TNotifyEvent;
|
|
begin
|
|
with TJvDrawGrid(Grid) do
|
|
begin
|
|
Self.Alignment := GetEditAlignment(Col, Row);
|
|
EditStyle := GetEditStyle(Col, Row);
|
|
end;
|
|
SaveChanged := Self.OnChange;
|
|
try
|
|
Self.OnChange := nil;
|
|
inherited UpdateContents;
|
|
finally
|
|
Self.OnChange := SaveChanged;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
|
|
procedure TJvInplaceEdit.CMCancelMode(var Msg: TCMCancelMode);
|
|
begin
|
|
if (Msg.Sender <> Self) and (Msg.Sender <> FActiveList) then
|
|
CloseUp(False);
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.WMCancelMode(var Msg: TMessage);
|
|
begin
|
|
StopTracking;
|
|
inherited;
|
|
end;
|
|
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvInplaceEdit.FocusKilled(NextWnd: THandle);
|
|
begin
|
|
if not SysLocale.FarEast then
|
|
inherited FocusKilled(NextWnd)
|
|
else
|
|
begin
|
|
{$IFDEF VCL}
|
|
ImeName := Screen.DefaultIme;
|
|
ImeMode := imDontCare;
|
|
{$ENDIF VCL}
|
|
inherited FocusKilled(NextWnd);
|
|
{$IFDEF VCL}
|
|
if NextWnd <> TJvDrawGrid(Grid).Handle then
|
|
ActivateKeyboardLayout(Screen.DefaultKbLayout, KLF_ACTIVATE);
|
|
{$ENDIF VCL}
|
|
end;
|
|
CloseUp(False);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
|
|
procedure TJvInplaceEdit.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
|
|
begin
|
|
with Msg do
|
|
if (FEditStyle <> ieSimple) and PtInRect(Rect(Width - FButtonWidth, 0,
|
|
Width, Height), Point(XPos, YPos)) then
|
|
Exit;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.WMPaint(var Msg: TWMPaint);
|
|
begin
|
|
PaintHandler(Msg);
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.WMSetCursor(var Msg: TWMSetCursor);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
GetCursorPos(P);
|
|
if (FEditStyle <> ieSimple) and
|
|
PtInRect(Rect(Width - FButtonWidth, 0, Width, Height), ScreenToClient(P)) then
|
|
Windows.SetCursor(LoadCursor(0, IDC_ARROW))
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TJvInplaceEdit.WndProc(var Message: TMessage);
|
|
begin
|
|
case Message.Msg of
|
|
WM_KEYDOWN, WM_SYSKEYDOWN, WM_CHAR:
|
|
if EditStyle in [iePickList] then
|
|
with TWMKey(Message) do
|
|
begin
|
|
DoDropDownKeys(CharCode, KeyDataToShiftState(KeyData));
|
|
if (CharCode <> 0) and FListVisible then
|
|
begin
|
|
with TMessage(Message) do
|
|
SendMessage(FActiveList.Handle, Msg, WParam, LParam);
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
inherited WndProc(Message);
|
|
end;
|
|
|
|
{$ENDIF VCL}
|
|
|
|
//=== { TJvDrawGrid } ========================================================
|
|
|
|
constructor TJvDrawGrid.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
DefaultRowHeight := 18;
|
|
Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
|
|
goDrawFocusSelected, goColSizing];
|
|
FIniLink := TJvIniLink.Create;
|
|
FIniLink.OnSave := IniSave;
|
|
FIniLink.OnLoad := IniLoad;
|
|
FPressedCell.X := -1;
|
|
FPressedCell.Y := -1;
|
|
FCellDown.X := -1;
|
|
FCellDown.Y := -1;
|
|
FBeepOnError := True;
|
|
end;
|
|
|
|
destructor TJvDrawGrid.Destroy;
|
|
begin
|
|
FOnChangeFocus := nil;
|
|
FIniLink.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TJvDrawGrid.GetStorage: TJvFormPlacement;
|
|
begin
|
|
Result := FIniLink.Storage;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.SetStorage(Value: TJvFormPlacement);
|
|
begin
|
|
FIniLink.Storage := Value;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.IniSave(Sender: TObject);
|
|
begin
|
|
if (Name <> '') and Assigned(IniStorage) then
|
|
SaveToAppStorage(IniStorage.AppStorage, IniStorage.AppStorage.ConcatPaths([
|
|
IniStorage.AppStoragePath, GetDefaultSection(Self)]));
|
|
end;
|
|
|
|
procedure TJvDrawGrid.IniLoad(Sender: TObject);
|
|
begin
|
|
if (Name <> '') and Assigned(IniStorage) then
|
|
LoadFromAppStorage(IniStorage.AppStorage, IniStorage.AppStorage.ConcatPaths([
|
|
IniStorage.AppStoragePath, GetDefaultSection(Self)]));
|
|
end;
|
|
|
|
function TJvDrawGrid.CanEditAcceptKey(Key: Char): Boolean;
|
|
begin
|
|
if Assigned(FOnAcceptEditKey) then
|
|
Result := FOnAcceptEditKey(Self, Key)
|
|
else
|
|
Result := inherited CanEditAcceptKey(Key);
|
|
end;
|
|
|
|
function TJvDrawGrid.CanEditShow: Boolean;
|
|
begin
|
|
Result := inherited CanEditShow;
|
|
if Result and Assigned(FOnShowEditor) then
|
|
begin
|
|
FOnShowEditor(Self, Col, Row, Result);
|
|
if not Result then
|
|
EditorMode := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DrawPicture(ARect: TRect; Graphic: TGraphic);
|
|
begin
|
|
DrawCellBitmap(Self, 0, 0, Graphic, ARect);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DrawMasked(ARect: TRect; Graphic: TBitmap);
|
|
var
|
|
X, Y: Integer;
|
|
begin
|
|
X := (ARect.Right + ARect.Left - Graphic.Width) div 2;
|
|
Y := (ARect.Bottom + ARect.Top - Graphic.Height) div 2;
|
|
DrawBitmapTransparent(Canvas, X, Y, Graphic, Graphic.TransparentColor and not PaletteMask);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DrawStr(ARect: TRect; const S: string;
|
|
Align: TAlignment);
|
|
begin
|
|
DrawCellTextEx(Self, 0, 0, S, ARect, Align, vaCenterJustify, False, IsRightToLeft);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DrawMultiline(ARect: TRect; const S: string;
|
|
Align: TAlignment);
|
|
begin
|
|
DrawCellTextEx(Self, 0, 0, S, ARect, Align, vaTopJustify, True, IsRightToLeft);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.InvalidateCell(ACol, ARow: Longint);
|
|
begin
|
|
inherited InvalidateCell(ACol, ARow);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.InvalidateCol(ACol: Longint);
|
|
begin
|
|
inherited InvalidateCol(ACol);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.InvalidateRow(ARow: Longint);
|
|
var
|
|
I: Longint;
|
|
begin
|
|
for I := 0 to ColCount - 1 do
|
|
inherited InvalidateCell(I, ARow);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
begin
|
|
if (Name <> '') then
|
|
InternalRestoreGridLayout(Self, IniStorage.AppStorage, Path);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
begin
|
|
if (Name <> '') then
|
|
InternalSaveGridLayout(Self, IniStorage.AppStorage, Path);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.Load;
|
|
begin
|
|
IniLoad(nil);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.Save;
|
|
begin
|
|
IniSave(nil);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if not CanGridAcceptKey(Key, Shift) then
|
|
Exit;
|
|
if not (ssCtrl in Shift) and (Key = VK_ESCAPE) and EditorMode and
|
|
(InplaceEditor <> nil) and InplaceEditor.Visible and
|
|
not (goAlwaysShowEditor in Options) then
|
|
begin
|
|
FNoUpdateData := True;
|
|
try
|
|
HideEditor;
|
|
if Assigned(FOnCancelEdit) then
|
|
FOnCancelEdit(Self);
|
|
finally
|
|
FNoUpdateData := False;
|
|
end;
|
|
end
|
|
else
|
|
inherited KeyDown(Key, Shift);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvDrawGrid.WMCommand(var Msg: TWMCommand);
|
|
begin
|
|
if (Msg.NotifyCode = EN_CHANGE) and
|
|
not (goAlwaysShowEditor in Options) then
|
|
begin
|
|
if (InplaceEditor <> nil) and InplaceEditor.HandleAllocated and
|
|
InplaceEditor.Visible then
|
|
TJvInplaceEdit(InplaceEditor).Change;
|
|
Msg.NotifyCode := 0;
|
|
end;
|
|
inherited;
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvDrawGrid.EditChanged(Sender: TObject);
|
|
begin
|
|
if Assigned(FOnEditChange) then
|
|
FOnEditChange(Self);
|
|
end;
|
|
|
|
function TJvDrawGrid.GetEditLimit: Integer;
|
|
begin
|
|
Result := inherited GetEditLimit;
|
|
if Assigned(FOnGetEditLimit) then
|
|
FOnGetEditLimit(Self, Result);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvDrawGrid.SetEditText(ACol, ARow: Longint; const Value: string);
|
|
begin
|
|
if not FNoUpdateData then
|
|
inherited SetEditText(ACol, ARow, Value);
|
|
end;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
procedure TJvDrawGrid.SetEditText(ACol, ARow: Longint; const Value: WideString);
|
|
begin
|
|
if not FNoUpdateData then
|
|
inherited SetEditText(ACol, ARow, Value);
|
|
end;
|
|
{$ENDIF VisualCLX}
|
|
|
|
procedure TJvDrawGrid.SetFixedButtons(Value: Boolean);
|
|
begin
|
|
if FFixedCellsButtons <> Value then
|
|
begin
|
|
FFixedCellsButtons := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DoFixedCellClick(ACol, ARow: Longint);
|
|
begin
|
|
if Assigned(FOnFixedCellClick) then
|
|
FOnFixedCellClick(Self, ACol, ARow);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.CheckFixedCellButton(ACol, ARow: Longint; var Enabled: Boolean);
|
|
begin
|
|
if (ACol >= 0) and (ARow >= 0) and ((ACol < FixedCols) or (ARow < FixedRows)) then
|
|
begin
|
|
if Assigned(FOnCheckButton) then
|
|
FOnCheckButton(Self, ACol, ARow, Enabled);
|
|
end
|
|
else
|
|
Enabled := False;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.TopLeftChanged;
|
|
begin
|
|
if (goRowSelect in Options) and DefaultDrawing then
|
|
InvalidateRow(Self.Row);
|
|
inherited TopLeftChanged;
|
|
if FTracking then
|
|
StopTracking;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.ColWidthsChanged;
|
|
begin
|
|
inherited ColWidthsChanged;
|
|
if FTracking then
|
|
StopTracking;
|
|
if Assigned(FOnColumnSized) then
|
|
FOnColumnSized(Self);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.RowHeightsChanged;
|
|
begin
|
|
inherited RowHeightsChanged;
|
|
if FTracking then
|
|
StopTracking;
|
|
if Assigned(FOnRowSized) then
|
|
FOnRowSized(Self);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.StopTracking;
|
|
begin
|
|
if FTracking then
|
|
begin
|
|
TrackButton(-1, -1);
|
|
FTracking := False;
|
|
MouseCapture := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.TrackButton(X, Y: Integer);
|
|
var
|
|
Cell: TGridCoord;
|
|
NewPressed: Boolean;
|
|
begin
|
|
Cell := MouseCoord(X, Y);
|
|
NewPressed := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y)) and
|
|
(FPressedCell.X = Cell.X) and (FPressedCell.Y = Cell.Y);
|
|
if FPressed <> NewPressed then
|
|
begin
|
|
FPressed := NewPressed;
|
|
InvalidateCell(Cell.X, Cell.Y);
|
|
InvalidateCell(FPressedCell.X, FPressedCell.Y);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
function TJvDrawGrid.IsActiveControl: Boolean;
|
|
var
|
|
Handle: THandle;
|
|
ParentForm: TCustomForm;
|
|
begin
|
|
ParentForm := GetParentForm(Self);
|
|
if Assigned(ParentForm) then
|
|
Result := ParentForm.ActiveControl = Self
|
|
else
|
|
begin
|
|
Handle := GetFocus;
|
|
Result := False;
|
|
while not Result and IsWindow(Handle) do
|
|
begin
|
|
if Handle = WindowHandle then
|
|
Result := True
|
|
else
|
|
Handle := GetParent(Handle);
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvDrawGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
Cell: TGridCoord;
|
|
EnableClick, Fixed: Boolean;
|
|
begin
|
|
if DrawButtons then
|
|
begin
|
|
if (Button = mbLeft) and ((Shift - [ssLeft]) = []) then
|
|
begin
|
|
MouseToCell(X, Y, Cell.X, Cell.Y);
|
|
if (Cell.X >= FixedCols) and (Cell.Y >= FixedRows) then
|
|
begin
|
|
FCellDown := Cell;
|
|
InvalidateCell(Cell.X, Cell.Y);
|
|
end;
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
Exit;
|
|
end;
|
|
|
|
HideEditor;
|
|
if not (csDesigning in ComponentState) and
|
|
(CanFocus or (GetParentForm(Self) = nil)) then
|
|
begin
|
|
SetFocus;
|
|
if not IsActiveControl then
|
|
begin
|
|
MouseCapture := False;
|
|
Exit;
|
|
end;
|
|
end;
|
|
if (Button = mbLeft) and (ssDouble in Shift) then
|
|
begin
|
|
if FFixedCellsButtons then
|
|
begin
|
|
Cell := MouseCoord(X, Y);
|
|
if not ((Cell.X >= 0) and (Cell.X < FixedCols)) and
|
|
not ((Cell.Y >= 0) and (Cell.Y < FixedRows)) then
|
|
begin
|
|
DblClick;
|
|
Exit;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
DblClick;
|
|
Exit;
|
|
end;
|
|
end;
|
|
if Sizing(X, Y) then
|
|
inherited MouseDown(Button, Shift, X, Y)
|
|
else
|
|
begin
|
|
Cell := MouseCoord(X, Y);
|
|
Fixed := ((Cell.X >= 0) and (Cell.X < FixedCols)) or
|
|
((Cell.Y >= 0) and (Cell.Y < FixedRows));
|
|
if FFixedCellsButtons and Fixed and not (csDesigning in ComponentState) then
|
|
begin
|
|
if ([goRowMoving, goColMoving] * Options <> []) and
|
|
(Button = mbRight) then
|
|
begin
|
|
Button := mbLeft;
|
|
FSwapButtons := True;
|
|
MouseCapture := True;
|
|
end
|
|
else
|
|
if Button = mbLeft then
|
|
begin
|
|
EnableClick := True;
|
|
CheckFixedCellButton(Cell.X, Cell.Y, EnableClick);
|
|
if EnableClick then
|
|
begin
|
|
MouseCapture := True;
|
|
FTracking := True;
|
|
FPressedCell := Cell;
|
|
TrackButton(X, Y);
|
|
end
|
|
else
|
|
if BeepOnError then
|
|
Beep;
|
|
Exit;
|
|
end;
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
Cell: TGridCoord;
|
|
begin
|
|
if DrawButtons then
|
|
begin
|
|
if Shift = [ssLeft] then
|
|
begin
|
|
MouseToCell(X, Y, Cell.X, Cell.Y);
|
|
if not CompareMem(@Cell, @FCellDown, SizeOf(Cell)) then
|
|
begin
|
|
if (FCellDown.X >= 0) and (FCellDown.Y >= 0) then
|
|
InvalidateCell(FCellDown.X, FCellDown.Y);
|
|
FCellDown := Cell;
|
|
InvalidateCell(Cell.X, Cell.Y);
|
|
end;
|
|
end;
|
|
inherited MouseMove(Shift, X, Y);
|
|
Exit;
|
|
end;
|
|
|
|
if FTracking then
|
|
TrackButton(X, Y);
|
|
inherited MouseMove(Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
Cell: TGridCoord;
|
|
ACol, ARow: Longint;
|
|
DoClick: Boolean;
|
|
begin
|
|
if DrawButtons then
|
|
begin
|
|
if (Button = mbLeft) and (Shift = []) then
|
|
begin
|
|
InvalidateCell(FCellDown.X, FCellDown.Y);
|
|
FCellDown.X := -1;
|
|
FCellDown.Y := -1;
|
|
end;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
Exit;
|
|
end;
|
|
|
|
if FTracking and (FPressedCell.Y >= 0) and (FPressedCell.X >= 0) then
|
|
begin
|
|
Cell := MouseCoord(X, Y);
|
|
DoClick := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y)) and
|
|
(Cell.Y = FPressedCell.Y) and (Cell.X = FPressedCell.X);
|
|
StopTracking;
|
|
if DoClick then
|
|
begin
|
|
ACol := Cell.X;
|
|
ARow := Cell.Y;
|
|
if (ARow < RowCount) and (ACol < ColCount) then
|
|
DoFixedCellClick(ACol, ARow);
|
|
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;
|
|
|
|
procedure TJvDrawGrid.Paint;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
FDefaultDrawing := inherited DefaultDrawing;
|
|
inherited DefaultDrawing := False;
|
|
try
|
|
inherited Paint;
|
|
finally
|
|
inherited DefaultDrawing := FDefaultDrawing;
|
|
end;
|
|
if not (csDesigning in ComponentState) and DefaultDrawing and Focused and
|
|
([goRowSelect, goRangeSelect] * Options = [goRowSelect]) then
|
|
begin
|
|
Canvas.Font.Color := Font.Color;
|
|
Canvas.Brush.Color := Color;
|
|
if Row >= FixedRows then
|
|
begin
|
|
R := BoxRect(FixedCols, Row, ColCount - 1, Row);
|
|
if not (goHorzLine in Options) then
|
|
Inc(R.Bottom, GridLineWidth);
|
|
DrawFocusRect(Canvas.Handle, R);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvDrawGrid.CallDrawCellEvent(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState);
|
|
begin
|
|
inherited DrawCell(ACol, ARow, ARect, AState);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DoDrawCell(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState);
|
|
begin
|
|
CallDrawCellEvent(ACol, ARow, ARect, AState);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
|
|
AState: TGridDrawState);
|
|
var
|
|
Down: Boolean;
|
|
TempRect: TRect;
|
|
FrameFlags1, FrameFlags2: DWORD;
|
|
Style: DWORD;
|
|
const
|
|
EdgeFlag: array [Boolean] of UINT = (BDR_RAISEDINNER, BDR_SUNKENINNER);
|
|
begin
|
|
if DrawButtons then
|
|
begin
|
|
TempRect := ARect;
|
|
if not (gdFixed in AState) then
|
|
begin
|
|
Canvas.Brush.Color := clBtnFace;
|
|
Canvas.Font.Color := clBtnText;
|
|
Style := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
|
|
if (FCellDown.X = ACol) and (FCellDown.Y = ARow) then
|
|
Style := Style or DFCS_PUSHED;
|
|
{$IFDEF VisualCLX}
|
|
RequiredState(Canvas, [csHandleValid, csPenValid, csBrushValid]);
|
|
{$ENDIF VisualCLX}
|
|
DrawFrameControl(Canvas.Handle, TempRect, DFC_BUTTON, Style);
|
|
end;
|
|
inherited DrawCell(ACol,ARow,ARect,AState);
|
|
Exit;
|
|
end;
|
|
|
|
if FDefaultDrawing or (csDesigning in ComponentState) then
|
|
with Canvas do
|
|
begin
|
|
Font := Self.Font;
|
|
if ([goRowSelect, goVertLine] * Options = [goRowSelect]) and
|
|
not (gdFixed in AState) then
|
|
Inc(ARect.Right, GridLineWidth);
|
|
if ([goRowSelect, goHorzLine] * Options = [goRowSelect]) and
|
|
not (gdFixed in AState) then
|
|
Inc(ARect.Bottom, GridLineWidth);
|
|
if (gdSelected in AState) and (not (gdFocused in AState) or
|
|
([goDrawFocusSelected, goRowSelect] * Options <> [])) then
|
|
begin
|
|
Brush.Color := clHighlight;
|
|
Font.Color := clHighlightText;
|
|
end
|
|
else
|
|
begin
|
|
if gdFixed in AState then
|
|
Brush.Color := FixedColor
|
|
else
|
|
Brush.Color := Color;
|
|
end;
|
|
FillRect(ARect);
|
|
end;
|
|
Down := FFixedCellsButtons and (gdFixed in AState) and
|
|
{$IFDEF VCL}
|
|
Ctl3D and
|
|
{$ENDIF VCL}
|
|
not (csLoading in ComponentState) and FPressed and FDefaultDrawing and
|
|
(FPressedCell.X = ACol) and (FPressedCell.Y = ARow);
|
|
inherited DefaultDrawing := FDefaultDrawing;
|
|
if Down then
|
|
begin
|
|
Inc(ARect.Left, GridLineWidth);
|
|
Inc(ARect.Top, GridLineWidth);
|
|
end;
|
|
try
|
|
DoDrawCell(ACol, ARow, ARect, AState);
|
|
finally
|
|
inherited DefaultDrawing := False;
|
|
if Down then
|
|
begin
|
|
Dec(ARect.Left, GridLineWidth);
|
|
Dec(ARect.Top, GridLineWidth);
|
|
end;
|
|
end;
|
|
if FDefaultDrawing and
|
|
{$IFDEF VCL}
|
|
Ctl3D and
|
|
{$ENDIF VCL}
|
|
(gdFixed in AState) then
|
|
begin
|
|
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;
|
|
if (FrameFlags1 or FrameFlags2) <> 0 then
|
|
begin
|
|
TempRect := ARect;
|
|
if ((FrameFlags1 and BF_RIGHT) = 0) and
|
|
(goFixedVertLine in Options) then
|
|
Inc(TempRect.Right, GridLineWidth)
|
|
else
|
|
if ((FrameFlags1 and BF_BOTTOM) = 0) and
|
|
(goFixedVertLine in Options) then
|
|
Inc(TempRect.Bottom, GridLineWidth);
|
|
{$IFDEF VisualCLX}
|
|
RequiredState(Canvas, [csHandleValid, csPenValid, csBrushValid]);
|
|
{$ENDIF VisualCLX}
|
|
DrawEdge(Canvas.Handle, TempRect, EdgeFlag[Down], FrameFlags1);
|
|
DrawEdge(Canvas.Handle, TempRect, EdgeFlag[Down], FrameFlags2);
|
|
end;
|
|
end;
|
|
if FDefaultDrawing and not (csDesigning in ComponentState) and
|
|
(gdFocused in AState) and
|
|
([goEditing, goAlwaysShowEditor] * Options <> [goEditing, goAlwaysShowEditor]) and
|
|
not (goRowSelect in Options) then
|
|
DrawFocusRect(Canvas.Handle, ARect);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
|
|
procedure TJvDrawGrid.WMRButtonUp(var Msg: TWMMouse);
|
|
begin
|
|
if not (FGridState in [gsColMoving, gsRowMoving]) then
|
|
inherited
|
|
else
|
|
if not (csNoStdEvents in ControlStyle) then
|
|
with Msg do
|
|
MouseUp(mbRight, KeysToShiftState(Keys), XPos, YPos);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
|
|
var
|
|
Cell: TGridCoord;
|
|
begin
|
|
if FFixedCellsButtons then
|
|
begin
|
|
with Msg do
|
|
Cell := MouseCoord(XPos, YPos);
|
|
if ((Cell.X >= 0) and (Cell.X < FixedCols)) or
|
|
((Cell.Y >= 0) and (Cell.Y < FixedRows)) then
|
|
begin
|
|
SendCancelMode(Self);
|
|
if csCaptureMouse in ControlStyle then
|
|
MouseCapture := True;
|
|
if not (csNoStdEvents in ControlStyle) then
|
|
with Msg do
|
|
MouseDown(mbLeft, KeysToShiftState(Keys) - [ssDouble], XPos, YPos);
|
|
Exit;
|
|
end;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvDrawGrid.FocusKilled(NextWnd: THandle);
|
|
begin
|
|
inherited FocusKilled(NextWnd);
|
|
if Assigned(FOnChangeFocus) then
|
|
FOnChangeFocus(Self);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.FocusSet(PrevWnd: THandle);
|
|
begin
|
|
inherited FocusSet(PrevWnd);
|
|
if Assigned(FOnChangeFocus) then
|
|
FOnChangeFocus(Self);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvDrawGrid.WMCancelMode(var Msg: TMessage);
|
|
begin
|
|
StopTracking;
|
|
inherited;
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
function TJvDrawGrid.CreateEditor: TInplaceEdit;
|
|
begin
|
|
Result := TJvInplaceEdit.Create(Self);
|
|
TEdit(Result).OnChange := EditChanged;
|
|
end;
|
|
|
|
function TJvDrawGrid.GetEditAlignment(ACol, ARow: Longint): TAlignment;
|
|
begin
|
|
Result := taLeftJustify;
|
|
if Assigned(FOnGetEditAlign) then
|
|
FOnGetEditAlign(Self, ACol, ARow, Result);
|
|
end;
|
|
|
|
function TJvDrawGrid.GetEditStyle(ACol, ARow: Longint): TInplaceEditStyle;
|
|
begin
|
|
Result := ieSimple;
|
|
if Assigned(FOnGetEditStyle) then
|
|
FOnGetEditStyle(Self, ACol, ARow, Result);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.GetPickList(ACol, ARow: Longint; PickList: TStrings);
|
|
begin
|
|
if Assigned(FOnGetPicklist) then
|
|
FOnGetPicklist(Self, ACol, ARow, PickList);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.EditButtonClick;
|
|
begin
|
|
if Assigned(FOnEditButtonClick) then
|
|
FOnEditButtonClick(Self);
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvDrawGrid.WMHScroll(var Msg: TWMHScroll);
|
|
begin
|
|
inherited;
|
|
if Assigned(FOnHScroll) then
|
|
FOnHScroll(Self);
|
|
end;
|
|
|
|
procedure TJvDrawGrid.WMVScroll(var Msg: TWMVScroll);
|
|
begin
|
|
inherited;
|
|
if Assigned(FOnVScroll) then
|
|
FOnVScroll(Self);
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvDrawGrid.SetDrawButtons(const Value: Boolean);
|
|
begin
|
|
if FDrawButtons <> Value then
|
|
begin
|
|
FDrawButtons := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
function TJvDrawGrid.SelectCell(ACol, ARow: Integer): Boolean;
|
|
begin
|
|
if DrawButtons then
|
|
Result := False
|
|
else
|
|
Result := inherited SelectCell(ACol, ARow);
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
initialization
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|
|
|
finalization
|
|
UnregisterUnitVersion(HInstance);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
end.
|
|
|