TMaskEdit 后代中闪烁的 TSpeedButton

Flickering TSpeedButton in a TMaskEdit descendant

我尝试创建一个类似 TComboBox 的组件,它继承自 TMaskEdit,在编辑本身内部有一个 TSpeedButton

当我在编辑器中键入内容时出现的问题是,大部分按钮消失了(右侧和底部边缘仍然可见)。如果我将鼠标移到组件上或使用 TAB 键退出,按钮会再次出现。

代码如下:

interface

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

type
  TMyEdit = class(TCustomMaskEdit)
  private
    FButton: TSpeedButton;
  protected
    procedure CreateButton;
  public
    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
  end;

implementation

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;

  CreateButton;
end;

procedure TMyEdit.CreateButton;
begin
  FButton := TSpeedButton.Create(Self);
  FButton.Parent := Self;
  FButton.Align := alRight;
  FButton.Width := 16;
  FButton.Caption := '';
  FButton.Transparent := False;
end;

destructor TMyEdit.Destroy;
begin
  FreeAndNil(FButton);
  inherited;
end;

procedure TMyEdit.CreateWnd;
begin
  inherited;
  Perform(EM_SETMARGINS, EC_RIGHTMARGIN, (FButton.Width + 4) shl 16);
end;

我错过了什么?

已解决。

WS_CLIPCHILDREN 标志必须包含在 CreateParams() 中并且按钮必须放置在 TWinControl 后代(在我的例子中是 TPanel)或者按钮本身必须成为 TWinControl 后代(例如 TButton)。图形控件没有Handle,就是这个问题。

修改后的代码:

procedure TMyEdit.CreateButton;
var
  xDrawRect: TRect;
  xPanel : TPanel;
begin
  xPanel := TPanel.Create(Self);
  xPanel.Parent := Self;
  xPanel.SetBounds(Width - Height, 0, Height, Height);
  xPanel.BevelOuter := bvNone;

  FButton := TSpeedButton.Create(Self);
  FButton.Parent := xPanel;
  FButton.Align := alClient;
  FButton.Caption := '';
end;

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