Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Gráficos (https://www.clubdelphi.com/foros/forumdisplay.php?f=8)
-   -   Ventana con forma personalizada (https://www.clubdelphi.com/foros/showthread.php?t=57420)

Cecil 14-06-2008 12:52:39

Ventana con forma personalizada
 
Hola a todos, tengo una duda que hace tiempo que quiero solucionar, y es la siguiente:

Primero mirad la imagen: http://www.usuarios.lycos.es/gatoray...io-ejemplo.JPG

Bueno, si os fijais, lo que quiero es un formulario personalizado, pero el gran problema es el de las esquinas, que son redondeadas y transparentes. He encontrado un par de ejemplos, pero no funcionan bien, porque lo que quiero esque la ventana funcione normalmente, que se pueda ampliar el formulario, maximizar, etc. Bueno y otro problema es el dichoso parpadeo de las imagenes al redimensionarlas... Agradezco toda ayuda, un saludo.

coso 14-06-2008 13:59:29

Una sencilla busqueda por el foro ... me dio este resultado entre otros.

Cecil 14-06-2008 14:22:43

Ya realice esa sencilla búsqueda, y encontre ese ejemplo, pero, los bordes se ven demasiado pixelados, y yo necesito poner una imagen con la esquina transparente como en la imagen de mi ejemplo. Muchas gracias por tu respuesta, pero necesito más ayuda. Un saludo!

coso 14-06-2008 15:06:32

Bueno el antialias es un poquillo mas complicado en delphi 5 y me va bastante lento : / pero el degradado es sencillo. Te pongo un ejemplo y espero q encuentres alguna funcion de antialias con buen rendimiento.

Código Delphi [-]
unit degradado;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject); 
var 
  f: HRGN; 
begin 
  Form1.Borderstyle := bsNone; 
  f := CreateRoundRectRgn(
          0,            // x-coordinate of the region's upper-left corner
          0,            // y-coordinate of the region's upper-left corner
          clientwidth,  // x-coordinate of the region's lower-right corner
          clientheight, // y-coordinate of the region's lower-right corner
          40,           // height of ellipse for rounded corners
          40);          // width of ellipse for rounded corners
  SetWindowRgn(Handle,f,True);
end;

procedure TForm1.FormPaint(Sender: TObject);
var
        ri,gi,bi : integer;
        rf,gf,bf : integer;
        pr,pg,pb : double;
        r,g,b    : integer;
        x : integer;
        c : TColor;
begin
        inherited;

        ri := $3F;
        gi := $4F;
        bi := $70;

        rf := 255;
        gf := 255;
        bf := 255;

        pr := (rf - ri) / (2*Width/3);
        pg := (gf - gi) / (2*Width/3);
        pb := (bf - bi) / (2*Width/3);

        c := 0;
        for x := 0 to (2*Width div 3) - 1 do
        begin
          r := ri + round(pr * x);
          g := gi + round(pg * x);
          b := bi + round(pb * x);

          c := RGB(r,g,b);

          Canvas.Pen.Color := c;
          Canvas.MoveTo(x,0);
          Canvas.LineTo(x,Height);
        end;

        for x := (2*Width div 3) to Width do
        begin
          Canvas.Pen.Color := c;
          Canvas.MoveTo(x,0);
          Canvas.LineTo(x,Height);
        end;
end;
end.

Saludos

coso 14-06-2008 16:07:16

Te dejo aqui la ventana con fondo degradado, esquinas redondeadas y antialiasing. De antialias seguro q hay funciones mas buenas por internet. Lo dejo por si alguien quiere cojer la idea.

Código Delphi [-]
unit antialias;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure Antialias(Rt : TRect);
    procedure Degradado;
    procedure FormPaint(Sender: TObject);
    function Red(c : TColor) : integer;
    function Green(c : TColor) : integer;
    function Blue(c : TColor) : integer;
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
        Desktop : TControlCanvas;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  f: HRGN;
begin
        Desktop := TControlCanvas.Create;

        try
                Desktop.Handle := GetDC(0);
        except
        end;

  Form1.Borderstyle := bsNone;
  f := CreateRoundRectRgn(
          0,            // x-coordinate of the region's upper-left corner
          0,            // y-coordinate of the region's upper-left corner
          clientwidth,  // x-coordinate of the region's lower-right corner
          clientheight, // y-coordinate of the region's lower-right corner
          40,           // height of ellipse for rounded corners
          40);          // width of ellipse for rounded corners
  SetWindowRgn(Handle,f,True);
  Left := 40;
  Top := 200;
end;

procedure TForm1.Degradado;
var
        ri,gi,bi : integer;
        rf,gf,bf : integer;
        pr,pg,pb : double;
        r,g,b    : integer;
        x : integer;
        c : TColor;
begin
        ri := 255;
        gi := 255;
        bi := 255;

        rf := $8B;
        gf := $9B;
        bf := $D1;

        pr := (rf - ri) / (2*Height/3);
        pg := (gf - gi) / (2*Height/3);
        pb := (bf - bi) / (2*Height/3);

        c := 0;
        for x := 0 to (2*Height div 3) - 1 do
        begin
          r := ri + round(pr * x);
          g := gi + round(pg * x);
          b := bi + round(pb * x);

          c := RGB(r,g,b);

          Canvas.Pen.Color := c;
          Canvas.MoveTo(0,x);
          Canvas.LineTo(Width,x);
        end;

        for x := (2*Height div 3) to Height do
        begin
          Canvas.Pen.Color := c;
          Canvas.MoveTo(0,x);
          Canvas.LineTo(Width,x);
        end;
end;

procedure TForm1.Antialias(Rt : TRect);
var
        x,y,i : integer;
        r,g,b : longint;
        cl : array [0..8] of TColor;
begin
        for x := Rt.Left -1 to Rt.Right + 1 do
        for y := Rt.Top - 1 to Rt.Bottom + 1 do
        begin
              r := 0;
              g := 0;
              b := 0;

              cl[0] := desktop.Pixels[Left + x-1,Top + y-1];
              cl[1] := desktop.Pixels[Left + x-1,Top + y];
              cl[2] := desktop.Pixels[Left + x-1,Top + y+1];

              cl[3] := desktop.Pixels[Left + x,Top + y-1];
              cl[8] := desktop.Pixels[Left + x,Top + y];
              cl[4] := desktop.Pixels[Left + x,Top + y+1];

              cl[5] := desktop.Pixels[Left + x+1,Top + y-1];
              cl[6] := Desktop.Pixels[Left + x+1,Top + y];
              cl[7] := Desktop.Pixels[Left + x+1,Top + y+1];

                for i := 0 to 7 do
                begin
                        r := r + Red(cl[i]);
                        g := g + Green(cl[i]);
                        b := b + Blue(cl[i]);
                end;

                r := (r div 8);
                g := (g div 8);
                b := (b div 8);

                Canvas.Pixels[x,y] := RGB(r,g,b);
        end;
end;

function TForm1.Red(c : TColor) : integer;
begin
        Red := c and $FF;
end;

function TForm1.Green(c : TColor) : integer;
begin
        Green := (c and $FF00) div $100;
end;

function TForm1.Blue(c : TColor) : integer;
begin
        Blue := (c and $FF0000) div $10000;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
        inherited;
        Degradado;
        Antialias(Rect(0,0,30,30));
        Antialias(Rect(Width-30,0,Width,30));
        Antialias(Rect(0,Height - 30,30,Height));
        Antialias(Rect(Width-30,Height - 30, Width, Height));
        Antialias(Rect(0,0,Width,2));
        Antialias(Rect(0,0,2,Height));
        Antialias(Rect(Width-2,0,Width,Height));
        Antialias(Rect(0,Height-2,Width,Height));

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
        Desktop.Free;
end;

end.

Saludos

Cecil 14-06-2008 20:07:27

Mil gracias por tu ayuda, pero el ejemplo del antialiasing no me gusta del todo como realiza el suavizado del borde, pero lo ire tocando hasta dejarlo a mi gusto.
Y bueno, otra cuestión, ¿no existe ninguna forma de poner un pixel en concreto semitransparente?. Un saludo.

coso 14-06-2008 22:07:20

Bueno, la funcion de antialias que he escrito es una chapucilla rapida :D asi como la del gradiente (bueno esta la uso :), seguro que hay de mejores y mas rapidas (este es un tema ya muy tocado). Si usas mas arriba de delphi 5, deberias tener la propiedad alphablend para conseguir el translucido. Si no, lo que deberias hacer entonces es, tal y como se hace en el antialias, hacer la media aritmetica del color de fondo y del color que quieras pintar. (puedes tb dar un 'peso' a cada valor, el de fondo y el de la form y luego dividir por el total : ej; (3*fondo + 7*form) / 10) . Lo q no se es como conseguir el pixel de fondo, pues el GetDC(0) me da el desktop una vez pintado...y si sustraigo la region no me deja pintar en ella X/ bueno lo dicho seguro q si lo buscas por alla lo encuentras...

saludos


La franja horaria es GMT +2. Ahora son las 21:46:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi