6
votes

I have a composite component that consists of a TEdit and a TButton (yes, I know about TButtonedEdit) that inherits from TCustomControl. The edit and button are created in its constructor and placed on itself.

At designtime the selection box is not drawn properly - my guess is that the edit and button are hiding it because its been drawn for the custom control and then overdrawn by them.

Here the comparison:

enter image description here

I have also seen this for other 3rd party components (like the TcxGrid also only draws the outer part of the selection indicator)

Question: how can I change that?

Most simple case for reproducing:

unit SearchEdit;

interface

uses
  Classes, Controls, StdCtrls;

type
  TSearchEdit = class(TCustomControl)
  private
    fEdit: TEdit;
  public
    constructor Create(AOwner: TComponent); override;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Custom', [TSearchEdit]);
end;

{ TSearchEdit }

constructor TSearchEdit.Create(AOwner: TComponent);
begin
  inherited;
  fEdit := TEdit.Create(Self);
  fEdit.Parent := Self;
  fEdit.Align := alClient;
end;

end.
1
Which version of Delphi, in case it mattersDavid Heffernan
But I don't think you are going to have any luck. I think that the selection indicators are implemented by the IDE hooking the control window procedures. And your control is painted before its children.David Heffernan
Probably the easiest, off the top of my head, is to setup your own painting for design time.Graymatter
@Gray you mean do the painting in the parent, and suppress child painting?David Heffernan
@DavidHeffernan Yes, use something like fEdit.PaintTo(...) in the parent at design time and paint directly to the parents canvas.Graymatter

1 Answers

3
votes

As I said in the comments, the easiest thing I can think of is to paint the controls in the parent and "hide" them from the designer at design time. You can do this by calling SetDesignVisible(False) on each of the child controls. Then you use PaintTo to do the painting on the parent.

Using your example we get:

type
  TSearchEdit = class(TCustomControl)
  ...
  protected
    procedure Paint; override;
  ...
  end;

constructor TSearchEdit.Create(AOwner: TComponent);
begin
  inherited;
  fEdit := TEdit.Create(Self);
  fEdit.Parent := Self;
  fEdit.Align := alClient;
  fEdit.SetDesignVisible(False);
end;

procedure TSearchEdit.Paint;
begin
  Inherited;
  if (csDesigning in ComponentState) then
    fEdit.PaintTo(Self.Canvas, FEdit.Left, FEdit.Top);
end;