📄 tooledit.pas
字号:
with TCustomComboEdit(Owner) do begin
FNoAction := (FPopup <> nil) and FPopupVisible;
if not FPopupVisible then begin
if TabStop and CanFocus and (GetFocus <> Handle) then SetFocus;
end
else PopupCloseUp(FPopup, True);
end;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TEditButton.Click;
begin
if not FNoAction then inherited Click else FNoAction := False;
end;
{ TPopupWindow }
constructor TPopupWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEditor := TWinControl(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable,
csAcceptsControls];
{$ELSE}
ControlStyle := ControlStyle + [csAcceptsControls];
{$ENDIF}
Ctl3D := False;
ParentCtl3D := False;
Visible := False;
Parent := FEditor;
OnMouseUp := PopupMouseUp;
end;
procedure TPopupWindow.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := WS_POPUP or WS_BORDER or WS_CLIPCHILDREN;
{$IFDEF WIN32}
ExStyle := WS_EX_TOOLWINDOW;
{$ENDIF}
WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
end;
end;
{$IFNDEF WIN32}
procedure TPopupWindow.CreateWnd;
begin
inherited CreateWnd;
if (csDesigning in ComponentState) then SetParent(nil);
end;
{$ENDIF}
procedure TPopupWindow.WMMouseActivate(var Message: TMessage);
begin
Message.Result := MA_NOACTIVATE;
end;
function TPopupWindow.GetPopupText: string;
begin
Result := '';
end;
procedure TPopupWindow.InvalidateEditor;
var
R: TRect;
begin
if (FEditor is TCustomComboEdit) then begin
with TCustomComboEdit(FEditor) do
SetRect(R, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
end
else R := FEditor.ClientRect;
InvalidateRect(FEditor.Handle, @R, False);
UpdateWindow(FEditor.Handle);
end;
procedure TPopupWindow.PopupMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then CloseUp(PtInRect(Self.ClientRect, Point(X, Y)));
end;
procedure TPopupWindow.CloseUp(Accept: Boolean);
begin
if Assigned(FCloseUp) then FCloseUp(Self, Accept);
end;
procedure TPopupWindow.Hide;
begin
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
Visible := False;
end;
procedure TPopupWindow.Show(Origin: TPoint);
begin
SetWindowPos(Handle, HWND_TOP, Origin.X, Origin.Y, 0, 0,
SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOSIZE);
Visible := True;
end;
{ TCustomComboEdit }
constructor TCustomComboEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF RX_D3}
ControlStyle := ControlStyle + [csCaptureMouse];
{$ENDIF}
AutoSize := False;
FDirectInput := True;
FClickKey := scAltDown;
FPopupAlign := epaRight;
FBtnControl := TWinControl.Create(Self);
{$IFDEF WIN32}
with FBtnControl do
ControlStyle := ControlStyle + [csReplicatable];
{$ENDIF}
FBtnControl.Width := DefEditBtnWidth;
FBtnControl.Height := 17;
FBtnControl.Visible := True;
FBtnControl.Parent := Self;
FButton := TEditButton.Create(Self);
FButton.SetBounds(0, 0, FBtnControl.Width, FBtnControl.Height);
FButton.Visible := True;
FButton.Parent := FBtnControl;
TEditButton(FButton).OnClick := EditButtonClick;
Height := 21;
FDefNumGlyphs := 1;
FGlyphKind := gkCustom;
end;
destructor TCustomComboEdit.Destroy;
begin
FButton.OnClick := nil;
inherited Destroy;
end;
procedure TCustomComboEdit.CreateParams(var Params: TCreateParams);
const
Alignments: array[TAlignment] of Longword = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN
or Alignments[FAlignment];
end;
procedure TCustomComboEdit.CreateWnd;
begin
inherited CreateWnd;
SetEditRect;
end;
procedure TCustomComboEdit.HidePopup;
begin
TPopupWindow(FPopup).Hide;
end;
procedure TCustomComboEdit.ShowPopup(Origin: TPoint);
begin
TPopupWindow(FPopup).Show(Origin);
end;
procedure TCustomComboEdit.PopupDropDown(DisableEdit: Boolean);
var
P: TPoint;
Y: Integer;
begin
if (FPopup <> nil) and not (ReadOnly or FPopupVisible) then begin
P := Parent.ClientToScreen(Point(Left, Top));
Y := P.Y + Height;
if Y + FPopup.Height > Screen.Height then
Y := P.Y - FPopup.Height;
case FPopupAlign of
epaRight:
begin
Dec(P.X, FPopup.Width - Width);
if P.X < 0 then Inc(P.X, FPopup.Width - Width);
end;
epaLeft:
begin
if P.X + FPopup.Width > Screen.Width then
Dec(P.X, FPopup.Width - Width);
end;
end;
if P.X < 0 then P.X := 0
else if P.X + FPopup.Width > Screen.Width then
P.X := Screen.Width - FPopup.Width;
{$IFDEF WIN32}
if Text <> '' then SetPopupValue(Text)
else SetPopupValue(Null);
{$ELSE}
SetPopupValue(Text);
{$ENDIF}
if CanFocus then SetFocus;
ShowPopup(Point(P.X, Y));
FPopupVisible := True;
if DisableEdit then begin
inherited ReadOnly := True;
HideCaret(Handle);
end;
end;
end;
procedure TCustomComboEdit.PopupCloseUp(Sender: TObject; Accept: Boolean);
var
{$IFDEF WIN32}
AValue: Variant;
{$ELSE}
AValue: string;
{$ENDIF}
begin
if (FPopup <> nil) and FPopupVisible then begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
AValue := GetPopupValue;
HidePopup;
try
try
if CanFocus then begin
SetFocus;
if GetFocus = Handle then SetShowCaret;
end;
except
{ ignore exceptions }
end;
SetDirectInput(DirectInput);
Invalidate;
if Accept and AcceptPopup(AValue) and EditCanModify then begin
AcceptValue(AValue);
if FFocused then inherited SelectAll;
end;
finally
FPopupVisible := False;
end;
end;
end;
procedure TCustomComboEdit.DoChange;
begin
inherited Change;
end;
{$IFDEF WIN32}
function TCustomComboEdit.GetPopupValue: Variant;
{$ELSE}
function TCustomComboEdit.GetPopupValue: string;
{$ENDIF}
begin
if FPopup <> nil then Result := TPopupWindow(FPopup).GetValue
else Result := '';
end;
{$IFDEF WIN32}
procedure TCustomComboEdit.SetPopupValue(const Value: Variant);
{$ELSE}
procedure TCustomComboEdit.SetPopupValue(const Value: string);
{$ENDIF}
begin
if FPopup <> nil then TPopupWindow(FPopup).SetValue(Value);
end;
{$IFDEF WIN32}
procedure TCustomComboEdit.AcceptValue(const Value: Variant);
begin
if Text <> VarToStr(Value) then begin
{$ELSE}
procedure TCustomComboEdit.AcceptValue(const Value: string);
begin
if Text <> Value then begin
{$ENDIF}
Text := Value;
Modified := True;
UpdatePopupVisible;
DoChange;
end;
end;
{$IFDEF WIN32}
function TCustomComboEdit.AcceptPopup(var Value: Variant): Boolean;
{$ELSE}
function TCustomComboEdit.AcceptPopup(var Value: string): Boolean;
{$ENDIF}
begin
Result := True;
end;
function TCustomComboEdit.EditCanModify: Boolean;
begin
Result := not FReadOnly;
end;
procedure TCustomComboEdit.Change;
begin
if not PopupVisible then DoChange
else PopupChange;
end;
procedure TCustomComboEdit.PopupChange;
begin
end;
procedure TCustomComboEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (FClickKey = ShortCut(Key, Shift)) and (ButtonWidth > 0) then begin
EditButtonClick(Self);
Key := 0;
end;
end;
procedure TCustomComboEdit.KeyPress(var Key: Char);
begin
if (Key = Char(VK_RETURN)) or (Key = Char(VK_ESCAPE)) then
begin
if PopupVisible then begin
PopupCloseUp(FPopup, Key = Char(VK_RETURN));
Key := #0;
end
else begin
{ must catch and remove this, since is actually multi-line }
GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
if Key = Char(VK_RETURN) then begin
inherited KeyPress(Key);
Key := #0;
Exit;
end;
end;
end;
inherited KeyPress(Key);
end;
procedure TCustomComboEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if (FPopup <> nil) and (Button = mbLeft) then begin
if CanFocus then SetFocus;
if not FFocused then Exit;
if FPopupVisible then PopupCloseUp(FPopup, False);
{else if (not ReadOnly or AlwaysEnable) and (not DirectInput) then
PopupDropDown(True);}
end;
inherited MouseDown(Button, Shift, X, Y);
end;
function TCustomComboEdit.GetButtonWidth: Integer;
begin
Result := FButton.Width;
end;
procedure TCustomComboEdit.SetButtonWidth(Value: Integer);
begin
if ButtonWidth <> Value then begin
FBtnControl.Visible := Value > 1;
if (csCreating in ControlState) then begin
FBtnControl.Width := Value;
FButton.Width := Value;
with FButton do
ControlStyle := ControlStyle - [csFixedWidth];
RecreateGlyph;
end
else if (Value <> ButtonWidth) and (Value < ClientWidth) then begin
FButton.Width := Value;
with FButton do
ControlStyle := ControlStyle - [csFixedWidth];
if HandleAllocated then RecreateWnd;
RecreateGlyph;
end;
end;
end;
function TCustomComboEdit.GetButtonHint: string;
begin
Result := FButton.Hint;
end;
procedure TCustomComboEdit.SetButtonHint(const Value: string);
begin
FButton.Hint := Value;
end;
function TCustomComboEdit.GetGlyph: TBitmap;
begin
Result := FButton.Glyph;
end;
procedure TCustomComboEdit.SetGlyph(Value: TBitmap);
begin
FButton.Glyph := Value;
FGlyphKind := gkCustom;
end;
function TCustomComboEdit.GetNumGlyphs: TNumGlyphs;
begin
Result := FButton.NumGlyphs;
end;
procedure TCustomComboEdit.SetNumGlyphs(Value: TNumGlyphs);
begin
if FGlyphKind in [gkDropDown, gkEllipsis] then FButton.NumGlyphs := 1
else if FGlyphKind = gkDefault then FButton.NumGlyphs := FDefNumGlyphs
else FButton.NumGlyphs := Value;
end;
procedure TCustomComboEdit.SetEditRect;
var
Loc: TRect;
begin
SetRect(Loc, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
end;
procedure TCustomComboEdit.UpdateBtnBounds;
var
BtnRect: TRect;
begin
{$IFDEF WIN32}
if NewStyleControls then begin
if Ctl3D and (BorderStyle = bsSingle) then
BtnRect := Bounds(Width - FButton.Width - 4, 0,
FButton.Width, Height - 4)
else begin
if BorderStyle = bsSingle then
BtnRect := Bounds(Width - FButton.Width - 2, 2,
FButton.Width, Height - 4)
else
BtnRect := Bounds(Width - FButton.Width, 0,
FButton.Width, Height);
end;
end
else
BtnRect := Bounds(Width - FButton.Width, 0, FButton.Width, Height);
{$ELSE}
BtnRect := Bounds(Width - FButton.Width, 0, FButton.Width, Height);
{$ENDIF}
with BtnRect do
FBtnControl.SetBounds(Left, Top, Right - Left, Bottom - Top);
FButton.Height := FBtnControl.Height;
SetEditRect;
end;
{$IFDEF WIN32}
procedure TCustomComboEdit.CMCtl3DChanged(var Message: TMessage);
begin
inherited;
UpdateBtnBounds;
end;
{$ENDIF}
procedure TCustomComboEdit.WMSize(var Message: TWMSize);
var
MinHeight: Integer;
begin
inherited;
if not (csLoading in ComponentState) then begin
MinHeight := GetMinHeight;
{ text edit bug: if size to less than MinHeight, then edit ctrl does
not display the text }
if Height < MinHeight then begin
Height := MinHeight;
Exit;
end;
end
else begin
if (FPopup <> nil) and (csDesigning in ComponentState) then
FPopup.SetBounds(0, Height + 1, 10, 10);
end;
UpdateBtnBounds;
end;
function TCustomComboEdit.GetTextHeight: Integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -