📄 jvgrids.pas
字号:
{-----------------------------------------------------------------------------
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,v 1.37 2005/02/18 14:17:28 ahuser Exp $
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, 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: HWND); override;
procedure FocusSet(PrevWnd: HWND); 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: '$RCSfile: JvGrids.pas,v $';
Revision: '$Revision: 1.37 $';
Date: '$Date: 2005/02/18 14:17:28 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
SysUtils, Math,
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: HWND); 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -