3

嗨,我正在尝试使用 TButton 构建一个 TEdit 控件以进行 Buttoned Edit,但问题是文本剪辑位于 Button 下方,而后者没有出现,因为按钮位于其上方。如何解决?请注意,当我调用 UpdateEditMargins 时(这是调整文本剪辑的过程)

这是我的代码:

unit YazButtonedEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Buttons, Messages, Windows, Forms;

type
  TYazButtonedEdit = class(TCustomEdit)
  private
    FEditButton: TBitBtn;
    FButtonWidth: Integer;
    FButtonVisible: Boolean;
    procedure WMSize(var Message: TMessage); message WM_SIZE;
    procedure SetButtonVisible(const Value: Boolean);
    procedure GetEditButtonClick(const Value: TNotifyEvent);
    function SetEditButtonClick: TNotifyEvent;
    procedure SetButtonWidth(const Value: Integer);
  protected
    procedure RefreshButton;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WndProc(var Message: TMessage); override;
  public
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure UpdateEditMargins;
  published
    property ButtonWidth: Integer read FButtonWidth write SetButtonWidth;
    property ButtonVisible: Boolean read FButtonVisible write SetButtonVisible;
    property OnEditButtonClick: TNotifyEvent read SetEditButtonClick write GetEditButtonClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('KH-Controls', [TYazButtonedEdit]);
end;

{ TYazButtonedEdit }

constructor TYazButtonedEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle - [csSetCaption];

  FEditButton := TBitBtn.Create(self);
  with FEditButton do begin
     Parent := self;
     TabStop := false;
     Visible := true;
     OnClick := OnEditButtonClick;
  end;
end;

procedure TYazButtonedEdit.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or WS_CLIPCHILDREN;
end;

destructor TYazButtonedEdit.Destroy;
begin
  FEditButton.Free;
  inherited;
end;

procedure TYazButtonedEdit.GetEditButtonClick(const Value: TNotifyEvent);
begin
  FEditButton.OnClick := Value;
end;

procedure TYazButtonedEdit.RefreshButton;
begin
  FEditButton.Width := ButtonWidth;
  FEditButton.Height := Height - 4;
  FEditButton.Visible := ButtonVisible;
  UpdateEditMargins;
end;

procedure TYazButtonedEdit.SetButtonVisible(const Value: Boolean);
begin
  if FButtonVisible <> Value then
  begin
    FButtonVisible := Value;
    RefreshButton;
  end;
end;

procedure TYazButtonedEdit.SetButtonWidth(const Value: Integer);
begin
  if FButtonWidth <> Value then
  begin
    FButtonWidth := Value;
    RefreshButton;
  end;
end;

function TYazButtonedEdit.SetEditButtonClick: TNotifyEvent;
begin
  Result := FEditButton.OnClick;
end;

procedure TYazButtonedEdit.WMSize(var Message: TMessage);
begin
  RefreshButton;
end;

procedure TYazButtonedEdit.WndProc(var Message: TMessage);
var
  LLeft, LTop: Integer;
begin
  case Message.Msg of
    CN_CTLCOLORSTATIC,
    CN_CTLCOLOREDIT:
        if FEditButton.Visible then
        begin
          LLeft := FEditButton.Left;
          LTop := FEditButton.Top;
          ExcludeClipRect(Message.WParam, LLeft + 1, LTop + 1,
            FEditButton.Width + FEditButton.Left - 1, FEditButton.Height - 1);
        end;
  end;
  inherited;
end;

procedure TYazButtonedEdit.UpdateEditMargins;
var
  LMargin, RMargin: Integer;
begin
  if HandleAllocated then
  begin
    LMargin := 0;
    RMargin := 0;
    if FEditButton.Visible then
        LMargin := FEditButton.Width + 2;
    SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN, MakeLong(LMargin, RMargin));
    Invalidate;
  end;
end;

procedure TYazButtonedEdit.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if Operation = opRemove then
  begin
    if AComponent = FEditButton then
    begin
      RefreshButton;
    end;
  end;
end;

end.
4

1 回答 1

5

在创建编辑窗口后调用它,最好是在CreateWnd方法中。因此,添加以下内容:

type
  TYazButtonedEdit = class(TCustomEdit)
  ...
  protected
    procedure CreateWnd; override;
  ...
  end;

implementation

procedure TYazButtonedEdit.CreateWnd;
begin
  inherited;
  UpdateEditMargins;
end;
于 2012-08-27T11:29:43.580 回答