📄 dbgrideh.pas
字号:
finally
Free;
end;
end;
{ Error reporting }
procedure RaiseGridError(const S: string);
begin
raise EInvalidGridOperation.Create(S);
end;
procedure KillMessage(Wnd: HWnd; Msg: Integer);
// Delete the requested message from the queue, but throw back
// any WM_QUIT msgs that PeekMessage may also return
var
M: TMsg;
begin
M.Message := 0;
if PeekMessage(M, Wnd, Msg, Msg, pm_Remove) and (M.Message = WM_QUIT) then
PostQuitMessage(M.wparam);
end;
//ddd
//Pure RX
type
//ddd
TCharSet = Set of Char;
//\\\
function ExtractWord(N: Integer; const S: string; WordDelims: TCharSet): string; forward;
function GetDefaultSection(Component: TComponent): string;
var
F: TCustomForm;
Owner: TComponent;
begin
if Component <> nil then begin
if Component is TCustomForm then Result := Component.ClassName
else begin
Result := Component.Name;
if Component is TControl then begin
F := GetParentForm(TControl(Component));
if F <> nil then Result := F.ClassName + Result
else begin
if TControl(Component).Parent <> nil then
Result := TControl(Component).Parent.Name + Result;
end;
end
else begin
Owner := Component.Owner;
if Owner is TForm then
Result := Format('%s.%s', [Owner.ClassName, Result]);
end;
end;
end
else Result := '';
end;
function Max(A, B: Longint): Longint;
begin
if A > B then Result := A
else Result := B;
end;
function Min(A, B: Longint): Longint;
begin
if A < B then Result := A
else Result := B;
end;
function iif(Condition:Boolean;V1,V2:Integer):Integer;
begin
if (Condition) then Result := V1 else Result := V2;
end;
//\\\
procedure GridInvalidateRow(Grid: TCustomDBGridEh; Row: Longint);
var
I: Longint;
begin
for I := 0 to Grid.ColCount - 1 do Grid.InvalidateCell(I, Row);
end;
function DefineCursor(Identifier: PChar): TCursor;
var Handle:HCursor;
begin
Handle := LoadCursor(hInstance, Identifier);
if Handle = 0 then raise EOutOfResources.Create('Cannot load cursor resource');
for Result := 1 to High(TCursor) do
if Screen.Cursors[Result] = Screen.Cursors[crArrow] then
begin
Screen.Cursors[Result] := Handle;
Exit;
end;
raise EOutOfResources.Create('Too many user-defined cursors');
end;
function GetTextWidth(Canvas:TCanvas; Text:String):Integer;
var ARect:TRect;
uFormat:Integer;
begin
uFormat := DT_CALCRECT or DT_LEFT or DT_NOPREFIX;
ARect := Rect(0,0,1,0);
DrawText(Canvas.Handle, PChar(Text), Length(Text), ARect, uFormat);
Result := ARect.Right - ARect.Left;
end;
{ TDBGridInplaceEdit }
{ TDBGridInplaceEdit adds support for a button on the in-place editor,
which can be used to drop down a table-based lookup list, a stringlist-based
pick list, or (if button style is esEllipsis) fire the grid event
OnEditButtonClick. }
type
TEditStyle = (esSimple, esEllipsis, esPickList, esDataList, esDateCalendar ,esUpDown, esDropDown);
TPopupListbox = class;
TPopupMonthCalendar = class;
TDBGridInplaceEdit = class(TInplaceEditEh)
private
FButtonWidth: Integer;
FDataList: TDBLookupListBox;
FPickList: TPopupListbox;
FActiveList: TWinControl;
FLookupSource: TDatasource;
FEditStyle: TEditStyle;
FListVisible: Boolean;
FTracking: Boolean;
FPressed: Boolean;
//ddd
FPopupMonthCalendar: TPopupMonthCalendar;
FWordWrap: Boolean;
FUpDown:TUpDown;
procedure ListMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure ListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure UpDownChanging (Sender: TObject; var AllowChange: Boolean);
procedure UpDownClick(Sender: TObject; Button: TUDBtnType);
//\\\
procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SetEditStyle(Value: TEditStyle);
procedure StopTracking;
procedure TrackButton(X,Y: Integer);
procedure CMCancelMode(var Message: TCMCancelMode); message CM_CancelMode;
procedure WMCancelMode(var Message: TMessage); message WM_CancelMode;
procedure WMKillFocus(var Message: TMessage); message WM_KillFocus;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message wm_LButtonDblClk;
procedure WMPaint(var Message: TWMPaint); message wm_Paint;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SetCursor;
procedure SetWordWrap(const Value: Boolean);
protected
procedure BoundsChanged; override;
procedure CloseUp(Accept: Boolean);
//ddd
procedure CreateParams(var Params: TCreateParams); override;
//\\\
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;
procedure PaintWindow(DC: HDC); override;
procedure UpdateContents; override;
procedure WndProc(var Message: TMessage); override;
//ddd
procedure KeyPress(var Key: Char); override;
property WordWrap: Boolean read FWordWrap write SetWordWrap;
//\\\
property EditStyle: TEditStyle read FEditStyle write SetEditStyle;
property ActiveList: TWinControl read FActiveList write FActiveList;
property DataList: TDBLookupListBox read FDataList;
property PickList: TPopupListbox read FPickList;
public
constructor Create(Owner: TComponent); override;
end;
{ TPopupListbox }
TPopupListbox = class(TCustomListbox)
private
FSearchText: String;
FSearchTickCount: Longint;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure KeyPress(var Key: Char); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
end;
//ddd
{ TPopupMonthCalendar }
TPopupMonthCalendar = class(TMonthCalendar)
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
end;
//\\\
procedure TPopupListBox.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
WindowClass.Style := CS_SAVEBITS;
end;
end;
procedure TPopupListbox.CreateWnd;
begin
inherited CreateWnd;
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
end;
procedure TPopupListbox.Keypress(var Key: Char);
var
TickCount: Integer;
begin
case Key of
#8, #27: FSearchText := '';
#32..#255:
begin
TickCount := GetTickCount;
if TickCount - FSearchTickCount > 2000 then FSearchText := '';
FSearchTickCount := TickCount;
if Length(FSearchText) < 32 then FSearchText := FSearchText + Key;
SendMessage(Handle, LB_SelectString, WORD(-1), Longint(PChar(FSearchText)));
Key := #0;
end;
end;
inherited Keypress(Key);
end;
procedure TPopupListbox.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
TDBGridInPlaceEdit(Owner).CloseUp((X >= 0) and (Y >= 0) and
(X < Width) and (Y < Height));
end;
//ddd
procedure TPopupMonthCalendar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
WindowClass.Style := CS_SAVEBITS;
end;
end;
procedure TPopupMonthCalendar.CreateWnd;
begin
inherited CreateWnd;
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
end;
procedure TPopupMonthCalendar.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var MCHInfo:TMCHitTestInfo;
begin
inherited MouseUp(Button, Shift, X, Y);
MCHInfo.cbSize := SizeOf(TMCHitTestInfo);
MCHInfo.pt.x := X;
MCHInfo.pt.y := Y;
MonthCal_HitTest(Handle,MCHInfo);
if ((MCHInfo.uHit and MCHT_CALENDARDATE) > 0) and (MCHInfo.uHit <> MCHT_CALENDARDAY) and
(MCHInfo.uHit <> MCHT_TITLEBTNNEXT) and (MCHInfo.uHit <> MCHT_TITLEBTNPREV) then
TDBGridInPlaceEdit(Owner).CloseUp(True)
else if (MCHInfo.uHit and MCHT_NOWHERE > 0) then
TDBGridInPlaceEdit(Owner).CloseUp(False)
else if not ((X >= 0) and (Y >= 0) and
(X < Width) and (Y < Height)) then
TDBGridInPlaceEdit(Owner).CloseUp(False);
end;
//\\\
constructor TDBGridInplaceEdit.Create(Owner: TComponent);
begin
inherited Create(Owner);
FLookupSource := TDataSource.Create(Self);
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
FEditStyle := esSimple;
end;
procedure TDBGridInplaceEdit.BoundsChanged;
var
R: TRect;
begin
SetRect(R, 2, 2, Width - 2, Height);
if FEditStyle <> esSimple then Dec(R.Right, FButtonWidth);
SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@R));
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
if SysLocale.FarEast then
SetImeCompositionWindow(Font, R.Left, R.Top);
//ddd
if FEditStyle = esUpDown then
begin
FUpDown.Visible := True;
FUpDown.SetBounds(Width - FButtonWidth, 0, FButtonWidth, Height);
end;
//\\\
end;
procedure TDBGridInplaceEdit.CloseUp(Accept: Boolean);
var
MasterField: TField;
ListValue: Variant;
//ddd
CurColumn:TColumnEh;
idx:Integer;
//\\\
begin
//ddd
CurColumn :=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -