GARANTIR DESCONTO

Fórum Desenhando componentes em delphi: Como se faz isso? #264875

11/01/2005

0

Eae!

Jah que ultimamente esse site tem falado bastante sobre componentes, entao eu acho q a minha duvida é a de muitas outras pessoas!

Como se desenha um componente?

Por exemplo, se eu quiser desenhar um outro botao! Um botao com a aparencia de um botao do Mac antigo, ou do KDE, ou do Windows XP! Ou um outro que ninguem nunca tenha visto igual! Onde que eu faco o desenho? Como funciona?
Posso fazer herança? Se naum puder, como responder aos cliques do windows? E etc, etc, etc... :D

Tah ae uma boa dica pra quem quer postar um bom artigo pro UpLoader Master!

Valeuz :D


_chiappone_

_chiappone_

Responder

Posts

11/01/2005

Bruno_fantin

Qualquer componente visual você tem que herdar basicamente de duas classes...

TWinControl - Para componentes que vão receber focus...
TGraphicControl - Para componentes que não vão receber focus...

Uma vez feito isso basta você sobreescrever o metodo paint... E nesse metodo fazer os desenhos usando Canvas...

Em exemplo simples...

unit Botao;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TBotao = class(TGraphicControl) // Herdei de TGraphicControl... Esse componente não pode receber o focus
  private
    { Private declarations }
  protected
    procedure Paint; override; // Metodo Paint reescrito
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; // Mensagem que pega quando o botão esquerdo do mouse é clicado
  public
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

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

{ TBotao }

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

   Self.Height := 25;
   Self.Width  := 75;

   Invalidate; // Chamando o metodo paint manualmente... Sempre chama ele pelo Invalidade...
end;

procedure TBotao.Paint;
begin
   // Aqui que eu desenho tudo o que eu quero...
   // O ideal aqui é usar doublebuffering

   Canvas.Rectangle(0,0,75,25);

   Canvas.TextOut(22,6, ´Botão´);

   inherited;
end;

procedure TBotao.WMLButtonDown(var Message: TWMLButtonDown);
begin
   showmessage(´Clicou´);
end;

end.



Responder

Gostei + 0

11/01/2005

_chiappone_

Q massa, kra!

Mas, algumas perguntas :D

A Message WMLButtonDown seria usada na verdade para ´afundar o botao´, ok? E eu teria algo como ´WMLButtonUp´ para voltar ele ao normal, correto?

Outra coisa... O que é DoubleBuffering?

Vlwz! :D


Responder

Gostei + 0

11/01/2005

Bruno_fantin

procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;

Para você saber todas as mensagem que pode usar abre a unit Controls e veja a declaração da TControl...

DoubleBuffering???

Canvas é um buffer... DoubleBuffering é usar dois Canvas em vez de um...

O primeiro é o do proprio componente que será usado para desenhar o resultado final...

O segundo é um canvas criando em run-time aonde será feito cada um dos passos do desenho...

Por exemplo...

Você tem varios processos de desenho...
* Desenhar a Bordar...
* Desenhar o Glyphs...
* Desenhar o Texto....
* Desenhar a Sobra...

Ai você faz cada um deles na segunda canvas... No final a segunda canvas vai estar com o desenho que era visto pelo usuario... Ai nessa hora você copia ela para a primeira canvas...

Pra que tudo isso??? Para evitar aquelas piscadas na tela...


Responder

Gostei + 0

11/01/2005

_chiappone_

Legal!...

O Canvas que voce exemplificou no Paint eh o proprio Canvas do componente, ok?
Eu criaria uma variavel do tipo TCanvas e faria o processo lah...

Mas...

eu colocaria o Canvas novo no private desse componente e faria qualquer alteracao lah dentro, usando esse Canvas?

Canvas2.metodo
Canvas2.metodo

isso?

E pra aplicar as alteracoes no segundo Canvas? jogo no primeiro?
Como?

Voce, ou alguem mais aqui, tem algum componente que exemplifique o DoubleBuffering?

Valewz!!! :D


PS: Como voces podem ver, eu nunca mexi com canvas :D


Responder

Gostei + 0

11/01/2005

Bruno_fantin

unit Botao;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TBotao = class(TGraphicControl) // Herdei de TGraphicControl... Esse componente não pode receber o focus
  private
    OffScreen: TBitmap; // O segundo canvas aqui chamado de OffScreen...
  protected
    procedure Paint; override; // Metodo Paint reescrito
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; // Mensagem que pega quando o botão esquerdo do mouse é clicado
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

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

{ TBotao }

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

   OffScreen := TBitmap.Create; // Crie o OffScreen...

   OffScreen.Height:= 25; //Defini o tamanho do OffScreen...
   OffScreen.Width := 75;

   Self.Height := 25;
   Self.Width  := 75;

   Invalidate; // Chamando o metodo paint manualmente... Sempre chama ele pelo Invalidade...
end;

destructor TBotao.Destroy;
begin
   OffScreen.Free; // Matei o OffScreen...

   inherited Destroy;
end;

procedure TBotao.Paint;
begin
   // Aqui que eu desenho tudo o que eu quero...
   // O ideal aqui é usar doublebuffering

   OffScreen.Canvas.FillRect(Rect( 0, 0, 75, 25)); // Limpei o OffScreen...

   OffScreen.Canvas.Rectangle(0,0,75,25);

   OffScreen.Canvas.TextOut(22,6, ´Botão´);

   Canvas.Draw(0, 0, OffScreen); //Copiei tudo do OffScreen para o canvas...

   inherited;
end;

procedure TBotao.WMLButtonDown(var Message: TWMLButtonDown);
begin
   showmessage(´Clicou´);
end;

end.



Responder

Gostei + 0

11/01/2005

Massuda

O Canvas que voce exemplificou no Paint eh o proprio Canvas do componente, ok? Eu criaria uma variavel do tipo TCanvas e faria o processo lah... [...]

Se o seu componente precisar ter foco de entrada, você pode partir de um TWinControl... nesse caso, o double buffering está embutido no TWinControl, você não precisa implementar nada.


Responder

Gostei + 0

11/01/2005

_chiappone_

Entendi...


Colei esse codigo em um componente novo, e funcionou.

Soh que ae eu tentei implementar ele, usando a message WM_LBUTTONUP;

fiz assim:

procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUp;


logo abaixo do WMLButtonDown

e alterei mais isso:

procedure TBotao.WMLButtonDown(var Message: TWMLButtonDown);
begin
  OffScreen.Canvas.Brush.Color := clRed;
  Invalidate;
end;

procedure TBotao.WMLButtonUp(var Message: TWMLButtonUp);
begin
  OffScreen.Canvas.Brush.Color := clWhite;
  Invalidate;
end;

Funcionou também. Quando voce clica, ele de branco passa a ser vermelho, e quando solta, ele fica branco.

Soh que, a partir do momento em que eu der clique duplo nele, ele passa a alterar a cor em qualquer lugar do form que eu clicar!
Sem contar que ele naum deixa eu fechar o form, pq, ao invez de dexecutar qualquer outra coisa, ele pinta o botao.

Porque?

Valeuz denovo :D


Responder

Gostei + 0

11/01/2005

_chiappone_

[quote:92e7bf5488=´_chiappone_´]O Canvas que voce exemplificou no Paint eh o proprio Canvas do componente, ok? Eu criaria uma variavel do tipo TCanvas e faria o processo lah... [...]

Se o seu componente precisar ter foco de entrada, você pode partir de um TWinControl... nesse caso, o double buffering está embutido no TWinControl, você não precisa implementar nada.[/quote:92e7bf5488]

e como funcionaria?

Ele espera eu chamar o Draw para aplicar as alteracoes?


Responder

Gostei + 0

11/01/2005

Bruno_fantin

Como você não está tratando a mensagem de doubleclick então o componente fica louco...

Faz assim... Declara...

procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;

E no codigo só faz assim...

procedure TBotao.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin

end;


Responder

Gostei + 0

11/01/2005

_chiappone_

Ae, funcionou!

Eh, nao eh tao simples assim... agora eu preciso tratar o Drag and Drop...
pq qndo eu clico, e solto o mouse fora do botao, ele nao volta a cor pra branco....

Mas agora acho q dah pra mim seguir adiante....

Valeu mesmo rapaziada!!! Quando tiver pronto o que eu quero, eu posto aqui denovo!

Outra coisa... eu tava mostrando pro pessoal aqui, e eles deram a ideia:

[b:3bd3260c6c]´Pq vcs do forum naum criam uma paleta de componentes?´[/b:3bd3260c6c]

Tipo... uma ´Jedi Lib´ feita por brasileiros!

Nos temos fama de criativos (e realmente somos, sem duvida)... dah pra fazer umas coisas mto feras, e aprender muito!

Fica a ideia ae... qq vcs acham?


Responder

Gostei + 0

12/01/2005

Massuda

[quote:f9c4a57960=´Massuda´]Se o seu componente precisar ter foco de entrada, você pode partir de um TWinControl... nesse caso, o double buffering está embutido no TWinControl, você não precisa implementar nada.

e como funcionaria? Ele espera eu chamar o Draw para aplicar as alteracoes?[/quote:f9c4a57960]
Num componente derivado de TWinControl, você controla o uso de double buffering através da propriedade DoubleBuffered.

Quando DoubleBuffered é True, o processo de desenho do componente (a procedure Paint) é redirecionado (pela VCL) para um canvas que na verdade é um bitmap, não a tela. Assim, você não precisa fazer nada de especial para ´aplicar as alterações´.

O default é ter TWinControl.DoubleBuffered = False.


Responder

Gostei + 0

12/01/2005

Bruno_fantin

´Pq vcs do forum naum criam uma paleta de componentes?´

No meu caso falta de tempo...

Mas se alguém começar a fazer alguma pode contrar com a minha ajuda..


Responder

Gostei + 0

12/01/2005

_chiappone_

Beleza!

Nos temos alguns componentes prontos jah... estamos esperando terminar o ultimo, e dpois eu posto um outro topico... ms quem quizer fazer isso antes, e jah bolar um lugar pra deixar os componentes :D


Flw!


Responder

Gostei + 0

04/02/2005

Rcoltrane

Olá,

Estive lendo os tópicos acima sobre criação de componentes e talvez vcs. possam me ajudar. É o seguinte: eu tenho uma TreeView e coloquei uma imagem em seu background para que a mesma ficasse com um visual mais bacana. Contudo, os canvas dos itens da Treeview ficam brancos (ou de qq. cor que vc. quiser) mas eu preciso que os canvas fiquem transparentes, para que eu possa ver na integra a imagem do background. Vcs sabem como fazer isto? Ou tenho que desenvolver uma nova treeview com as propriedades de transparencia?

Obrigado.
RC.


Responder

Gostei + 0

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

Aceitar