Fórum Erro na criação de componente #278371

21/04/2005

0

Olá,

Estou com um problema sério!!!

Necessito que na criação de um componente meu, ele crie outros componentes no mesmo form, aonde esse novo componente vai ser inserido.

Por exemplo, como no código abaixo, aonde o TButton2 vai inserir o Label1 automaticamente:




unit Button2;

interface

uses
SysUtils, Classes, Controls, StdCtrls;

type
TButton2 = class(TButton)
private
FLabel: TLabel;
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents(´Teste´, [TButton2]);
end;

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

if csDesigning in ComponentState then
begin
FLabel := TLabel.Create(AOwner);
FLabel.Name := ´Label1´;
FLabel.Parent := Parent;
end;
end;

end.



O problema é o seguinte, quando eu insiro o componente TButton2 via click não tenho problema nenhum, meu programa roda certinho, mas quando eu abro o formulário onde contêm outro TButton padrão, e clico no menu ´View as Text´, e modifico simplesmente o TButton para TButton2, ele me monta o label que eu quero tranquilamente, só que ao rodar o programa aparece ´Class TLabel not found´.

Porque isso acontece?? Acontece porque o novo componente, ´Label1´, não foi inserido no ´interface section´ do meu formulário.

Ao invés de ficar:



type
TForm1 = class(TForm)
Button1: TButton2;
Label1: TLabel;
private
...



ele fica:


type
TForm1 = class(TForm)
Button1: TButton2;
private
...




Porque preciso disso?? Preciso disso, pois tenho os componentes do meu sistema todos herdados, por exemplo, TEButton, TEDBGrid e assim por diante, e comprei o pacote da DevExpress, e não quero mudar de tela em tela todos os meus componentes, isso fica inviável, quero simplesmente,
ao invés de herdar dos componentes do Delphi, herdar dos componentes da DevExpress, com a codificação para herdar não tive problemas, só me resta agora esse problema q impossibita meu programa de rodar.

Eh isso.

Qualquer ajuda será bem vinda!!!

Obrigado a todos!!!


Giordanok

Giordanok

Responder

Posts

21/04/2005

Michael

Olá amigo!

Infelizmente eu acho q não há uma solução para o seu problema, pelo menos da forma q ele foi apresentado. Alterando o código do formulário manualmente não vai chamar o construtor da classe TButton2, onde o Label é criado de fato. Por isso vc recebe a mensagem de [b:b1feb0f700]Class not found[/b:b1feb0f700].

O Delphi só é automático com as coisas q ele mesmo cria, como por exemplo as chamadas aos eventos dos componentes de um formulário. Por exemplo: quando vc coloca um TButton no form, e dá dois cliques sobre ele, o evento OnClick é criado. Se vc salvar o arquivo sem adicionar nada ao evento, o Delphi automaticamente remove a declaração. Mas se vc criar o evento manualmente, fora da seção private, ele não fará nada. Da mesma forma q se vc remover a declaração de um componente via código, ele não será removido do formulário.

Bom, minha dica é: crie um componente conversor. Vc disse q comprou o pacote da DevExpress. Se foi o de barras de ferramentas e menus, sabe q existe um conversor q transforma os menus derivados de TMainMenu nos da suite DevExpress Bars. É mais ou menos isso q vc deveria fazer.

Sinto muito não ter uma resposta fácil para o seu problema. Mas talvez haja uma. Ei usuários do fórum, ajudem aqui! ;-)

Abraços!


Responder

Gostei + 0

21/04/2005

Giordanok

Realmente cara, existe o conversor para o meu caso, que é o ExpressQuantumGrid, mas daí eu tenho que entrar em cada tela e converter o grid, 1 a 1, tem o detalhe que as colunas do grid são variáveis para cada tela, senão eu converteria no formulário pai da herança e resolveria.

A minha questão não é nem alterar através do ´View as Text´, mas é uma forma de simular o meu problema. Que seria alterar somente a derivação do meu componente ´TEDBGrid´, do DBGrid para o cxGrid que é da DevExpress, e alterar em todas as telas automaticamente, sem precisar entrar em todas as telas.

Será que existe alguma solução para esse meu problema??

Ah, e obrigado pela atenção ao meu problema.


Responder

Gostei + 0

21/04/2005

Massuda

Não sei se isso resolve seu problema, mas tem duas coisas estranhas no seu exemplo...
constructor TButton2.Create(AOwner: TComponent); begin inherited Create(AOwner); if csDesigning in ComponentState then begin FLabel := TLabel.Create(AOwner); FLabel.Name := ´Label1´; FLabel.Parent := Parent; end; end;

A primeira coisa é a linha...
if csDesigning in ComponentState then
...isso faz com que o label seja criado apenas quando o TButton2 é criado pela IDE, mas não quando o TButton2 é criado pelo seu programa. Do jeito que está, quando o programa é executado, o label não é criado e coisas estranhas devem acontecer.

A segunda coisa é...
FLabel.Name := ´Label1´;
FLabel.Parent := Parent;
Normalmente componentes criados dinamicamente não necessitam de receber um nome, mas, além de ter Parent, precisam ter uma posição (FLabel.Top e FLabel.Left) definidas.


Responder

Gostei + 0

21/04/2005

Giordanok

Realmente, cara, você tem razão no que você falou, mas não é o meu caso. No meu caso, eu preciso que ele seja criado somente em ´csDesigning´, porque eu posso modificá-lo através da IDE. E não posso criá-lo novamente ao criar o meu TButton2, porque ele perderia as alterações que fiz posteriormente no Label1.

E no segundo caso, que você explicou, eu não coloquei o Top, e Left, porque é só um exemplo o que eu citei aqui, para ficar mais fácil para o pessoal entender o meu problema, mas o certo seria colocar mesmo.

De qualquer forma, obrigado pela força.


Responder

Gostei + 0

21/04/2005

Michael

Olá amigo!

Então eu não vejo outra saída senão vc não gastar um tempo entrando em todos os forms e usando o conversor fornecido pela DevExpress. Alterando de qualquer outra forma vc corre o risco de atribuir uma propriedade inexistente na nova classe, ou mesmo eventos, e começar a ter problemas sem fim.

Se, por exemplo, vc trocar via edição do DFM a classe de um componente, e no código do formulário houver alguma propriedade da classe anterior q não existe na nova, irá gerar um erro q impedirá o form de ser aberto. Daí vc vai ter q manobrar de algum jeito para desfazer as alterações. Ou seja, problemas a mais.

Antes do desespero total, tente isso: entre na unit q define o componente TEDBGrid e declare a classe abaixo:

TEDBGrid = class(cxGrid)


Não se esqueça de excluir a antiga. Reinstale o componente e veja se as alterações são refletidas. Mas aviso q pode acontecer o problema abordado acima, de existirem propriedades da classe anterior q não o são na nova.

Abraços!


Responder

Gostei + 0

21/04/2005

Giordanok

Poisé, os problemas que você comentou realmente aconteceram pra mim, mas eu os contornei, fazendo com que todas as propriedades que existem no DBGrid se tornem existentes no cxGrid, coloquei Columns, DataSource, e outras que não existem no cxGrid, ou existem mas são de classes diferentes. Deu um certo trabalho de algumas horinhas, mas valiam a pena, pois tenho muitas telas em nosso sistema, chegando a umas 2000 telas com grid. Por isso que para nós se torna inviável entrar tela a tela.

Em tempo de desenvolvimento, eu consegui todo o resultado que eu obtinha através de um DBGrid se tornar igual no cxGrid, mas o problema ocorre mesmo quando eu vou rodar o form, por causa do assunto da minha primeira pergunta, do class not found.

Só falta resolver esse probleminha de criar a instância do objeto na interface section do meu form, se conseguisse isso, estaria finalizado o meu problema.

Obrigado mais uma vez.

T+


Responder

Gostei + 0

19/10/2007

J12leonardo

olá sou leonardo..
seguinte desculpa ta postando como resposta pra vc é q achei q vc poderia não olhar s eu criase um novo tópico...
to com o seguinte problema

estou trabalhando com um cxgrid de 3 niveis onde um depende do outro...
eu quero saber como faço pra verificar se o 3° ou o 2° nivel tem valor...ou seja se tem algum item mostrando...
por exemplo

nivel 1
nivel 2.1
{em branco nivel3}
nivel 2.2
nivel 3.1
nivel 3.2

então se eu selecionar o ´nivel 3.1´ ou o ´nivel2.2´ num popupMenu habilita os botões de alteração e exclusão do nivel 3, se o nivel 2.1 for selecionado só deixo habilitado o botão de inclusão no popupmenu do nivel 3

espero ter sido claro...por favor s puder m encaminha a resposta por email...j12leoanrdo@gmail.com

valeu


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar