Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-12-2004
Aprendiz Aprendiz is offline
Miembro
 
Registrado: may 2003
Posts: 78
Poder: 21
Aprendiz Va por buen camino
Creación de Componente basado en DBImage

Hola a todos de nuevo,

Estoy creando un componente para solucionar un problema que ya planteé en otro hilo. Es un TDBImage al que le fuerzo a su Bitmap las propiedades TransparentMode=tmFixed, Transparent=True y TransparentColor=Color especificado por el programador.

La cosa es que no me coge el cambio de valores que le hago en el componente que he creado y no se si es que he hecho algo mal. Les dejo el código para ver si ven algo que yo no haya visto.

Saludos y Gracias.

Código:
unit DBImageSinFondo;

interface

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

type
  TDBImageSinFondo = class(TDBImage)
  private
    FTransparent: boolean;                      //Bitmap Transparente
    FTransparentColor: TColor;                  //Color del Bitmap Transparente
    FTransparentMode: TTransparentMode;         //Modo de captación del color transparente
    procedure SetTransparent (Value: boolean);
    function GetTransparent: boolean;
    procedure SetTransparentColor (Value: TColor);
    function GetTransparentColor: TColor;
    procedure SetTransparentMode (Value: TTransparentMode);
    function GetTransparentMode: TTransparentMode;
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property TransparenteMode: TTransparentMode read GetTransparentMode write SetTransparentMode;
    property Transparente: boolean read GetTransparent write SetTransparent;
    property TransparenteColor: TColor read GetTransparentColor write SetTransparentColor;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('RapidSoft', [TDBImageSinFondo]);
end;

constructor TDBImageSinFondo.Create(AOwner: TComponent);
begin
  inherited Create (AOwner);
  //Valores por defecto
  FTransparentMode  := Picture.Bitmap.TransparentMode;
  FTransparent      := Picture.Bitmap.Transparent;
  FTransparentColor := Picture.Bitmap.TransparentColor;
end;

destructor TDBImageSinFondo.Destroy;
begin
  inherited Destroy;
end;

function TDBImageSinFondo.GetTransparent: Boolean;
begin
  Result := FTransparent;
end;

procedure TDBImageSinFondo.SetTransparent (Value: Boolean);
begin
  FTransparent:=Value;
  Picture.Bitmap.Transparent := FTransparent;
end;

function TDBImageSinFondo.GetTransparentColor: TColor;
begin
  Result := FTransparentColor;
end;

procedure TDBImageSinFondo.SetTransparentColor (Value: TColor);
begin
  FTransparentColor := Value;
  Picture.Bitmap.TransparentColor:=FTransparentColor;
end;

function TDBImageSinFondo.GetTransparentMode: TTransparentMode;
begin
  Result := FTransparentMode;
end;

procedure TDBImageSinFondo.SetTransparentMode(Value: TTransparentMode);
begin
  FTransparentMode := Value;
  Picture.Bitmap.TransparentMode:=FTransparentMode;
end;

end.
__________________
[Aprendiz]: Por que siempre hay algo nuevo que aprender.
Responder Con Cita
  #2  
Antiguo 16-12-2004
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola:

Mirando el código fuente del TDBImage veo que cuando se cambia de registro y por lo tanto se dispara el método DataChanged, en éste se hace Picture.Graphic := nil, lo cual seguramente anula las propiedades de transparencia que tenías.

Se me ocurre que crees un método MiPictureChanged que sustituya al que ya hay, PictureChanged (al no ser virtual no te sirve heredar de éste sino crear otro nuevo) y en el Create se lo asignas al objeto Picture:

Picture.OnChange := MiPictureChanged;

Y en dicho método es donde le asignas al Bitmap los valores de transparencia que tienes almacenados. Me queda la duda de si al asignar esos valores se volverá a lanzar el mismo método (MiPictureChanged) por lo que quizás debas usar un semáforo.

Saludos
__________________
Guía de Estilo
Responder Con Cita
  #3  
Antiguo 16-12-2004
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola:

Lo acabo de volver a mirar y la cosa no es tan fácil. Pensaba que se podría pegar alegremente todo el código de PictureChanged a MiPictureChanged pero no es así por culpa de unas variables privadas (FPictureLoaded y FDataLink) que no podemos alterar.

Bueeeno, se me ocurre algo quizás estrambótico: teniendo en cuenta que al asignar el evento MiPictureChanged al Picture (Picture.OnChange := MiPictureChanged;), dicha asignación ya está hecha en el constructor Create heredado, podríamos almacenar la referencia al método asignado en una variable del tipo TNotifyEvent:

Código Delphi [-]
FAnteriorNotify : TNotifyEvent;
FCambiando : Boolean;

constructor TMiDBImage.Create;
begin
  inherited Create;
  ...
  FAnteriorNotify := Picture.OnChange;
  Picture.OnChange := MiPictureChanged;
  ...
end;

procedure TMiDBImage.MiPictureChanged;
begin
  if FCambiando then EXIT;
  FCambiando := TRUE;
  try
    Picture.Bitmap.TransparentColor:=FTransparentColor;
    ... 
    ...
    FAnteriorNotify(Picture);
  finally
    FCambiando := FALSE;
  end;
end;

No sé si esto servirá ...

Saludos
__________________
Guía de Estilo
Responder Con Cita
  #4  
Antiguo 16-12-2004
Aprendiz Aprendiz is offline
Miembro
 
Registrado: may 2003
Posts: 78
Poder: 21
Aprendiz Va por buen camino
Funciona a medias

Hoa Andres, ante todo gracias por responder.

Pues funciona a medias. Te explico en un DBImage puesto sobre el formulario parece ser que lo hace bien y finalmente el color de fondo no aparece.

La verdad es que he puesto una pequeña rutina que me devuelve estos tres valores que estamos intentando cambiar del Bitmap y los cambia todos menos el TransparentColor. Con el debugger puedo ver que cuando hace la asignación del TransparentColor, no se produce ningún error pero el valor del TransparentColor no varia, se queda con el mismo valor inicial que ya tenía.

Además cuando coloco el DBImage alterado sobre un DBCtrlGrid se va todo al traste y muestra una sola imagen, la del panel que tiene el foco, transparente y el resto aparece con el desagradable fondo verde.

Sigo investigando...

Saludos.
__________________
[Aprendiz]: Por que siempre hay algo nuevo que aprender.
Responder Con Cita
  #5  
Antiguo 16-12-2004
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola Aprendiz:

Mirando la implementación de los métodos SetTransparentMode y SetTransparentColor de TBitmap, veo que ambos alteran la otra propiedad mutuamente dependiendo del valor asignado, por lo que quizás estés asignando primero el TransparentColor y si luego asignas un TransparentMode = tmAuto, el TransparentColor vuelve a clDefault.

Míralo a ver.

Saludos
__________________
Guía de Estilo
Responder Con Cita
  #6  
Antiguo 16-12-2004
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
¡¡ Ufff !! Más cosas.

Ahora veo un fallo aquí, puesto que cada vez que el usuario altere una propiedad "Transparente" de tu componente, este cambio desencadenará inevitablemente un Picture.Changed que a su vez llamará a MiPictureChanged que reasigna todas, por lo que en los métodos SetTransparent, SetTransparentColor y SetTransparentMode tendrías que poner a TRUE el semáforo FCambiando (al terminar lo dejas en FALSE) para que no se dispare cada vez el PictureChanged, seguramente éso es lo que motiva ese comportamiento tan raro.

Saludos
__________________
Guía de Estilo

Última edición por andres1569 fecha: 16-12-2004 a las 19:17:30.
Responder Con Cita
  #7  
Antiguo 17-12-2004
Aprendiz Aprendiz is offline
Miembro
 
Registrado: may 2003
Posts: 78
Poder: 21
Aprendiz Va por buen camino
Hola,

No tranquilo, ese error no se produce, recuerda que hemos sacado las asignaciones al Bitmap de los Setters y lo pusimos directamente en MiPictureChanged con lo cual solo se ejecuta, gracias a los semáforos, una sola vez.

Saludos.

PD: De todas formas ya te digo que funciona, ahora el problema es ponerlo en un DBCtrlGrid y que también funcione para todas las fotos que carga. Esto del Replicate me está volviendo loco.
__________________
[Aprendiz]: Por que siempre hay algo nuevo que aprender.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 00:42:31.


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