Reputation: 862
I would like to create a Delphi component which can have the style of TComboBox
or TEdit
. If I set the style as stCombo
I would like to see a TComboBox
and if I set to stEdit
then I would like to see the component as a TEdit
.
The main reason of this component will be to change the look of TComboBox
when is ReadOnly
to an colored TEdit
.
Also, when is styled as stEdit
, I would like to add some features to TEdit
.
I've tried to descend the component from TCustomPanel
, TCustomComboBox
or even TWinControl
.
unit ComboEdit;
interface
uses
Winapi.Windows, Winapi.Messages,
System.Classes, System.SysUtils, System.Types, System.DateUtils,
Vcl.StdCtrls, VCL.ExtCtrls, Vcl.Controls, Vcl.Graphics, Vcl.Dialogs,
Vcl.Forms, Vcl.Buttons, Vcl.Themes, Vcl.ComCtrls;
type
TStyle = (stCombo, stEdit);
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
TComboEdit = class(TWinControl)
private
FPanel: TPanel;
FCombo: TComboBox;
FEdit: TEdit;
FStyle: TStyle;
procedure SetStyle(const Value: TStyle);
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Style: TStyle read FStyle write SetStyle;
end;
implementation
constructor TComboEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width:= 145;
Height:= 21;
FPanel:= TPanel.Create(AOwner);
FPanel.Parent:= Self;
FPanel.Top:= 0;
FPanel.Left:= 0;
FPanel.Width:= 145;
FPanel.Height:= 21;
FCombo:= TComboBox.Create(AOwner);
FCombo.Parent:= FPanel;
FCombo.Top:= 0;
FCombo.Left:= 0;
FCombo.Width:= 145;
FCombo.Height:= 21;
FEdit:= TEdit.Create(AOwner);
FEdit.Parent:= FPanel;
FEdit.Top:= 0;
FEdit.Left:= 0;
FEdit.Width:= 145;
FEdit.Height:= 21;
FEdit.Visible:= False;
FStyle:= stCombo;
end;
destructor TComboEdit.Destroy;
begin
FreeAndNil(FPanel);
FreeAndNil(FCombo);
FreeAndNil(FEdit);
inherited Destroy;
end;
procedure TComboEdit.SetStyle;
begin
if Value <> FStyle then
begin
FStyle:= Value;
case FStyle of
stCombo:
begin
FCombo.Visible:= True;
FEdit.Visible:= False;
end;
stEdit:
begin
FCombo.Visible:= False;
FEdit.Visible:= True;
end;
end;
Invalidate;
end;
end;
end.
If I do like this I get some nasty errors and I don't like the fact that editors can be selected inside of Panel
.
PS: I'm aware about csSimple
style from TComboBox
but it looks different than TEdit
(see below)
Upvotes: 1
Views: 640
Reputation: 862
I succeed to do it by creating compound component as indicated on this link
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
TComboEdit = class(TWinControl)
private
FCombo: TComboBox;
FEdit: TEdit;
FReadOnly: Boolean;
FStyle: TStyle;
procedure SetReadOnly(const Value: Boolean);
procedure SetStyle(const Value: TStyle);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Combo: TComboBox read FCombo;
property Edit: TEdit read FEdit;
property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
property Style: TStyle read FStyle write SetStyle default stCombo;
property Align;
property Font;
property ParentFont;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
end;
constructor TComboEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FReadOnly:= False;
FStyle:= stCombo;
Width:= 145;
Height:= 21;
FCombo:= TComboBox.Create(Self);
FCombo.Parent:= Self;
FCombo.Align:= alClient;
FCombo.Name:= 'ComboBox';
FCombo.SetSubComponent(True); //<--- here is the trick
FEdit:= TEdit.Create(Self);
FEdit.Parent:= Self;
FEdit.Visible:= False;
FEdit.Align:= alClient;
FEdit.Name:= 'Edit';
FEdit.SetSubComponent(True); //<--- here is the trick
end;
Upvotes: 2