Buscar

Criando um componente skin

Código

{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: Imagens
Adicionada dia: 11/06/03
Por: Felipe Monteiro
Visualizada: 5489 vezes

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