Fórum Criação de componente container #29140
15/03/2010
0
Estou criando um componente container que terá um TLabel, um TDBEdit, um TDBLookupComboBox e um TSppedButton. A idéia é sempre que eu precisar em uma tela de uma informação que está em outra tabela eu uso este componente para realizar o lookup. No TDBEdit exibo o campo da tabela dependente que é o objeto da edição, no TDBLookUpComboBox mostro a descrição referente a este código que esta em outra tabela. O botão é para acionar a tela de cadastro desta tabela caso não exista o registro sendo pesquisado no combo.
Criado o componente básico sem praticamente nenhum código, quando tento colocá-lo em um Form para visualiza-lo obtenho o erro "Control '' has no parent window". Descobri que ocorre quando dentro do construtor estou tentando posicionar o DBLookUpComboBox. Alguém tem idéia do porque ? Com os demais componentes que reposiciono não ocorre nada de erro. Abaixo o código deste componente até o momento:
unit uScyLookupTable;
interface
uses
SysUtils, Classes, Controls, DB, StdCtrls, DBCtrls, DBTables, Buttons, Graphics, Forms;
type
TScyLookupTable = class(TWinControl)
private
{ Private declarations }
lblLiteral : TLabel;
dbeCodigo : TDBEdit;
dbcbDesc : TDBLookupComboBox;
spbAbreForm: TSpeedButton;
qryLkp : TQuery;
dtsLkp : TDataSource;
{Properties Variables}
FCaption : TCaption; // caption do label
FShowButton: Boolean; // Indica se o botão para o form deve ser mostrado
{Functions and Procedures}
procedure SetCaptionLiteral(pCaption: TCaption);
procedure SetShowButton(pShowButton: Boolean);
procedure ControleKeyPress(Sender: TObject; var Key: Char);
procedure ControleCodigoExit(Sender: TObject);
procedure ControleLookUpClick(Sender: TObject);
procedure PosicionaComponentes;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Caption read FCaption write SetCaptionLiteral;
property ShowButton: Boolean read FShowButton write SetShowButton default False;
property Parent;
property Owner;
property ParentWindow;
end;
const
HOR_SPACE_OBJECTS = 4;
VER_SPACE_OBJECTS = 2;
procedure Register;
implementation
{$RESOURCE ScyLookupTable.res}
{ TScyLookupTable }
procedure TScyLookupTable.ControleCodigoExit(Sender: TObject);
begin
if dbcbDesc.Text = '' then
(Sender as TDBEdit).Text := '';
end;
procedure TScyLookupTable.ControleKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SelectNext(TWinControl(sender), true, true);
key := #0;
end;
end;
procedure TScyLookupTable.ControleLookUpClick(Sender: TObject);
begin
dbeCodigo.Text := dbcbDesc.Text;
end;
constructor TScyLookupTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// Self.Parent := (Aowner as TWinControl);
FCaption := 'lblLiteral';
ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
csSetCaption, csOpaque, csDoubleClicks, csReplicatable, csReflector];
// Criando objetos de acesso a dados
qryLkp := TQuery.Create(Self);
qryLkp.Name := 'qryLkp';
qryLkp.DatabaseName := 'dbApp';
dtsLkp := TDataSource.Create(Self);
dtsLkp.Name := 'dtsLkp';
dtsLkp.DataSet := qryLkp;
// Criando os objetos de tela
lblLiteral := TLabel.Create(Self);
lblLiteral.Name := 'lblLiteral';
lblLiteral.Caption := FCaption;
lblLiteral.Parent := Self;
lblLiteral.Visible := true;
lblLiteral.Top := Self.Top + (VER_SPACE_OBJECTS * 2);
dbeCodigo := TDBEdit.Create(Self);
dbeCodigo.Name := 'dbeCodigo';
dbeCodigo.Parent := Self;
dbeCodigo.TabOrder := 0;
dbeCodigo.TabStop := True;
dbeCodigo.Visible := True;
dbeCodigo.Text := '';
dbeCodigo.Top := Self.Top + VER_SPACE_OBJECTS;
dbeCodigo.OnKeyPress := ControleKeyPress;
dbeCodigo.OnExit := ControleCodigoExit;
dbcbDesc := TDBLookupComboBox.Create(Self);
dbcbDesc.Name := 'dbcbLookup';
dbcbDesc.Parent := Self;
dbcbDesc.Visible := True;
dbcbDesc.TabOrder := 0;
dbcbDesc.TabStop := True;
dbcbDesc.Top := dbeCodigo.Top;
dbcbDesc.OnClick := ControleLookUpClick;
spbAbreForm := TSpeedButton.Create(Self);
spbAbreForm.Name := 'spbAbreForm';
spbAbreForm.Parent := Self;
spbAbreForm.Top := dbeCodigo.Top;
spbAbreForm.Top := dbeCodigo.Top;
spbAbreForm.Visible := FShowButton;
spbAbreForm.Glyph.LoadFromResourceName(HInstance, 'ABRETELA');
PosicionaComponentes;
end;
destructor TScyLookupTable.Destroy;
begin
lblLiteral.Free;
dbeCodigo.Free;
dbcbDesc.Free;
inherited;
end;
procedure TScyLookupTable.PosicionaComponentes;
begin
Self.Height := dbeCodigo.Height + (VER_SPACE_OBJECTS * 2);
Self.Width := lblLiteral.Width + dbeCodigo.Width + dbcbDesc.Width + (HOR_SPACE_OBJECTS * 3);
if FShowButton then
Self.Width := Self.Width + spbAbreForm.Width;
lblLiteral.Left := 0;
dbeCodigo.Left := lblLiteral.Left + lblLiteral.Width + HOR_SPACE_OBJECTS;
dbcbDesc.Left := dbeCodigo.Left + dbeCodigo.Width + HOR_SPACE_OBJECTS;
spbAbreForm.Left := dbcbDesc.Left + dbcbDesc.Width + HOR_SPACE_OBJECTS;
Self.Repaint;
end;
procedure TScyLookupTable.SetCaptionLiteral(pCaption: TCaption);
begin
FCaption := pCaption;
lblLiteral.Caption := FCaption;
lblLiteral.Width := lblLiteral.Canvas.TextWidth(FCaption);
PosicionaComponentes;
end;
procedure TScyLookupTable.SetShowButton(pShowButton: Boolean);
begin
FShowButton := pShowButton;
Self.Width := lblLiteral.Width + dbeCodigo.Width + dbcbDesc.Width + (HOR_SPACE_OBJECTS * 3);
if FShowButton then
Self.Width := Self.Width + spbAbreForm.Width;
end;
{ Registra o Componente }
procedure Register;
begin
RegisterComponents('Scy', [TScyLookupTable]);
end;
end.
Criado o componente básico sem praticamente nenhum código, quando tento colocá-lo em um Form para visualiza-lo obtenho o erro "Control '' has no parent window". Descobri que ocorre quando dentro do construtor estou tentando posicionar o DBLookUpComboBox. Alguém tem idéia do porque ? Com os demais componentes que reposiciono não ocorre nada de erro. Abaixo o código deste componente até o momento:
unit uScyLookupTable;
interface
uses
SysUtils, Classes, Controls, DB, StdCtrls, DBCtrls, DBTables, Buttons, Graphics, Forms;
type
TScyLookupTable = class(TWinControl)
private
{ Private declarations }
lblLiteral : TLabel;
dbeCodigo : TDBEdit;
dbcbDesc : TDBLookupComboBox;
spbAbreForm: TSpeedButton;
qryLkp : TQuery;
dtsLkp : TDataSource;
{Properties Variables}
FCaption : TCaption; // caption do label
FShowButton: Boolean; // Indica se o botão para o form deve ser mostrado
{Functions and Procedures}
procedure SetCaptionLiteral(pCaption: TCaption);
procedure SetShowButton(pShowButton: Boolean);
procedure ControleKeyPress(Sender: TObject; var Key: Char);
procedure ControleCodigoExit(Sender: TObject);
procedure ControleLookUpClick(Sender: TObject);
procedure PosicionaComponentes;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Caption read FCaption write SetCaptionLiteral;
property ShowButton: Boolean read FShowButton write SetShowButton default False;
property Parent;
property Owner;
property ParentWindow;
end;
const
HOR_SPACE_OBJECTS = 4;
VER_SPACE_OBJECTS = 2;
procedure Register;
implementation
{$RESOURCE ScyLookupTable.res}
{ TScyLookupTable }
procedure TScyLookupTable.ControleCodigoExit(Sender: TObject);
begin
if dbcbDesc.Text = '' then
(Sender as TDBEdit).Text := '';
end;
procedure TScyLookupTable.ControleKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SelectNext(TWinControl(sender), true, true);
key := #0;
end;
end;
procedure TScyLookupTable.ControleLookUpClick(Sender: TObject);
begin
dbeCodigo.Text := dbcbDesc.Text;
end;
constructor TScyLookupTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// Self.Parent := (Aowner as TWinControl);
FCaption := 'lblLiteral';
ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
csSetCaption, csOpaque, csDoubleClicks, csReplicatable, csReflector];
// Criando objetos de acesso a dados
qryLkp := TQuery.Create(Self);
qryLkp.Name := 'qryLkp';
qryLkp.DatabaseName := 'dbApp';
dtsLkp := TDataSource.Create(Self);
dtsLkp.Name := 'dtsLkp';
dtsLkp.DataSet := qryLkp;
// Criando os objetos de tela
lblLiteral := TLabel.Create(Self);
lblLiteral.Name := 'lblLiteral';
lblLiteral.Caption := FCaption;
lblLiteral.Parent := Self;
lblLiteral.Visible := true;
lblLiteral.Top := Self.Top + (VER_SPACE_OBJECTS * 2);
dbeCodigo := TDBEdit.Create(Self);
dbeCodigo.Name := 'dbeCodigo';
dbeCodigo.Parent := Self;
dbeCodigo.TabOrder := 0;
dbeCodigo.TabStop := True;
dbeCodigo.Visible := True;
dbeCodigo.Text := '';
dbeCodigo.Top := Self.Top + VER_SPACE_OBJECTS;
dbeCodigo.OnKeyPress := ControleKeyPress;
dbeCodigo.OnExit := ControleCodigoExit;
dbcbDesc := TDBLookupComboBox.Create(Self);
dbcbDesc.Name := 'dbcbLookup';
dbcbDesc.Parent := Self;
dbcbDesc.Visible := True;
dbcbDesc.TabOrder := 0;
dbcbDesc.TabStop := True;
dbcbDesc.Top := dbeCodigo.Top;
dbcbDesc.OnClick := ControleLookUpClick;
spbAbreForm := TSpeedButton.Create(Self);
spbAbreForm.Name := 'spbAbreForm';
spbAbreForm.Parent := Self;
spbAbreForm.Top := dbeCodigo.Top;
spbAbreForm.Top := dbeCodigo.Top;
spbAbreForm.Visible := FShowButton;
spbAbreForm.Glyph.LoadFromResourceName(HInstance, 'ABRETELA');
PosicionaComponentes;
end;
destructor TScyLookupTable.Destroy;
begin
lblLiteral.Free;
dbeCodigo.Free;
dbcbDesc.Free;
inherited;
end;
procedure TScyLookupTable.PosicionaComponentes;
begin
Self.Height := dbeCodigo.Height + (VER_SPACE_OBJECTS * 2);
Self.Width := lblLiteral.Width + dbeCodigo.Width + dbcbDesc.Width + (HOR_SPACE_OBJECTS * 3);
if FShowButton then
Self.Width := Self.Width + spbAbreForm.Width;
lblLiteral.Left := 0;
dbeCodigo.Left := lblLiteral.Left + lblLiteral.Width + HOR_SPACE_OBJECTS;
dbcbDesc.Left := dbeCodigo.Left + dbeCodigo.Width + HOR_SPACE_OBJECTS;
spbAbreForm.Left := dbcbDesc.Left + dbcbDesc.Width + HOR_SPACE_OBJECTS;
Self.Repaint;
end;
procedure TScyLookupTable.SetCaptionLiteral(pCaption: TCaption);
begin
FCaption := pCaption;
lblLiteral.Caption := FCaption;
lblLiteral.Width := lblLiteral.Canvas.TextWidth(FCaption);
PosicionaComponentes;
end;
procedure TScyLookupTable.SetShowButton(pShowButton: Boolean);
begin
FShowButton := pShowButton;
Self.Width := lblLiteral.Width + dbeCodigo.Width + dbcbDesc.Width + (HOR_SPACE_OBJECTS * 3);
if FShowButton then
Self.Width := Self.Width + spbAbreForm.Width;
end;
{ Registra o Componente }
procedure Register;
begin
RegisterComponents('Scy', [TScyLookupTable]);
end;
end.
Luis Paz
Curtir tópico
+ 0
Responder
Posts
19/05/2010
Jose Pascoal
Ai Luis, blz ?!
Seguinte colega.. muda as linhas alterando para o que está em negrito :
TScyLookupTable = class(TCustomControl)
e mais abaixo no metodo construtor
constructor TScyLookupTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Parent := (Aowner as TWinControl);
Testei aqui e funcionou !
Abraço
Seguinte colega.. muda as linhas alterando para o que está em negrito :
TScyLookupTable = class(TCustomControl)
e mais abaixo no metodo construtor
constructor TScyLookupTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Parent := (Aowner as TWinControl);
Testei aqui e funcionou !
Abraço
Responder
Gostei + 0
19/05/2010
Luis Paz
Oi José,
Valeu pela dica. Como estava demorando um pouco para obter resposta eu havia encontrado um outro modo sobrescrevendo o método WMPaint, mas a tua solução é mais simples.
Muito Obrigado !
Abraço
Valeu pela dica. Como estava demorando um pouco para obter resposta eu havia encontrado um outro modo sobrescrevendo o método WMPaint, mas a tua solução é mais simples.
Muito Obrigado !
Abraço
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)