Buscar

Criando um componente skin

Código

Criando um componente Skin
Aqui iremos tratar da criação de um componente SKIN como os do WINAMP. Para montar os SKINS devemos utilizar um Bitmap e deixar as bordas do formulários transparentes (ocultas).

A solução é bem simples, utilizando o componente Timage, dê uma olhado no fonte:

unit SkinImage;
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
  ExtCtrls;
 
type
  TSkinImage = class(TImage)
  private
 
  protected
  { Protected declarations }
  function BitmapToRegion(bmp: TBitmap) : dword;
  procedure OwnerShow(Sender : TObject);
  public
  constructor Create(AOwner : TComponent); override;
  published
  { Published declarations }
  end;
 
procedure Register;
 
var
  Ready : Boolean;
 
implementation
 
procedure Register;
begin
  RegisterComponents('CLINICA DELPHI', [TSkinImage]);
end;
 
{ TSkinImage }
 
constructor TSkinImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  if NOT (csDesigning in ComponentState) then
  with TForm(AOwner) do
  begin
  BorderStyle := bsNone;
  Self.Top := 0;
  Self.Left := 0;
  OnShow := OwnerShow;
  end;
end;
 
function TSkinImage.BitmapToRegion(bmp: TBitmap) : dword;
var ix,iy : integer; // loop nas variáveis
  tc : TColor; // transparentColor
  b1 : boolean; // está olhando o "real"
pixels (no transparent pixels)
  c1 : cardinal; // ajusta a variável na região
  i1 : integer; // primeira posição real em pixel
begin
  Result := 0;
  i1 := 0;
  // memória do transparent color
  tc := bmp.transparentColor and $FFFFFF;
  with bmp.canvas do
  // enquadrilhe por todas as linhas
  for iy := 0 to bmp.height - 1 do
  begin
  b1 := False;
  // esquadrinhe por todo o pixels nesta linha
  for ix:=0 to bmp.Width - 1 do
  // feito nós acharmos o começo/final seguidos em pixel
  if (pixels[ix, iy] and $FFFFFF <> tc) <> b1 then begin
  // sim, e foi o último pixel,
  // so nós podemos somar uma região de estilo de linha. . .
  if b1 then begin
  c1:=CreateRectRgn(i1,iy,ix,iy+1);
  if result<>0 then
  begin
  // Esta não é a primeira região
  CombineRgn(Result, Result, c1, RGN_OR);
  DeleteObject(c1);
  // Esta é a primeira região
  end
  else
  Result := c1;
  end else i1 := ix;
  // mude o modo e procura o primeiro ou último pixel?
  b1:=not b1;
  end;
  // o último pixel nesta fila era um pixel real?
  if b1 then begin
  c1:=CreateRectRgn(i1, iy, bmp.width-1, iy+1);
  if (Result <> 0) then
  begin
  CombineRgn(Result, Result, c1, RGN_OR);
  DeleteObject(c1);
  end
  else
  Result := c1;
  end;
  end;
end;
 
procedure TSkinImage.OwnerShow(Sender: TObject);
var
  Region : HRGN;
begin
  if NOT Ready then
  begin
  Ready := True;
  Region := BitmapToRegion(Picture.Bitmap);
  SetWindowRgn(TForm(Owner).Handle, Region, True);
  DeleteObject(Region);
  end;
end;
 
initialization
  Ready := False;
end.
 

" Digamos a primeira linha de nosso bitmap se parece:

000XXXXX00XXXXX000000XXXX000

0 -> Pixel Trasparente; X -> Pixel Colorido

 

Agora minha função passa por esta linha e cria uma região de janela para cada fila de pixels. No exemplo, nós adquiriríamos 3 regiões (4-8, 11-15, 22-25).

Nós fizemos o mesmo para todas as outras linhas no Bitmap, e todas essas regiões.

Publicidade

Vote na dica




Quantidade de votos: 0 votos
Aceitação: 0%


Detalhes da dica

Categoria: Componentes
Adicionada dia: 03/02/05
Por: Ricardo L. S.
Visualizada: 10606 vezes

Planeta Delphi - Tudo sobre programação Delphi Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009