PDA

Ver la Versión Completa : error al colocar un componente propio a un form


mauqu
14-09-2007, 21:06:38
Estimados, estoy tratando de programar un componente propio y el código resultante es este.

//Inicio

type
TProducto = class(TPanel)
protected
procedure SetHeight(Value:integer);
procedure SetWidth(Value:integer);
procedure SetForma(Value:TShapeType);
procedure SetEtiqueta(Value:String);
procedure SetColorForma(Value:TColor);
procedure SetOnMouseDown(Value:TMouseEvent);

function GetForma:TShapeType;
function GetHeight:integer;
function GetWidth:integer;
function GetEtiqueta:string;
function GetColorForma:TColor;
function GetOnMouseDown:TMouseEvent;

published
sForma:TShape;
lEtiqueta:TLabel;

constructor PanelCreate(Sender: Tcomponent);
procedure PanelMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ShapeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
property Height:integer read GetHeight write SetHeight default 0;
property Width:integer read GetWidth write SetWidth default 0;
property Forma:TShapeType read GetForma write SetForma default stRoundRect;
property Etiqueta:string read GetEtiqueta write SetEtiqueta;
property ColorForma:TColor read GetColorForma write SetColorForma default clGreen;
property OnMouseDown:TMouseEvent read GetOnMouseDown write SetOnMouseDown;
//property PopUpMenu:TPopUpMenu read GetPopUpMenu write SetPopUpMenu;

public
procedure MostrarMensaje; virtual; abstract;
private

end;
//Fin

Obviamente despues de implementation esta el código necesario para todos los procesos y funciones declarados para la clase, no lo escribo acá por que ya es mucho :S.

El tema es que cuando registro esta clase y la instalo como un nuevo componente, aparece el la barra de componentes todo muy lindo, pero cuando la ubico en un form me sale un error "Acces violation in module productos.bpl" y luego "stack overflow save your work and restart delphi" cuac :SSS.

por que se puede dar esto.

sludos.

maeyanes
14-09-2007, 21:15:15
Hola...

Veo que ya tienes algunos mensajes en el foro, por lo cual ya deberías haber leido la Guía de Estilo (http://www.clubdelphi.com/foros/guiaestilo.php) de los foros...

También te recomiendo que uses las etiquetas (sin los espacios en blanco) para mostrar tu código:

var
A, I: Integer;

begin
A := 3;
for I := A to 10 do
ShowMessage(IntToStr(I))
end;


var
A, I: Integer;

begin
A := 3;
for I := A to 10 do
ShowMessage(IntToStr(I))
end;


Ves la diferencia?

Ahora, sobre tu problema, algo me dice que el error se encuentra en el código del constructor CreatePanel, pero sin ver el código no te puedo decir más...


Saludos...

mauqu
14-09-2007, 21:23:50
Este es el código del constructor



Código delphi [-]



constructor TProducto.PanelCreate(Sender:Tcomponent);
begin
inherited Create(Sender);

lEtiqueta:=TLabel.Create(Sender);
lEtiqueta.Caption:=''+#13#10+'';
lEtiqueta.Font.Size:=10;
lEtiqueta.Font.Style:=[fsBold];
lEtiqueta.Top:=0;
lEtiqueta.AutoSize:=false;
lEtiqueta.OnMouseDown:=ShapeMouseDown;
lEtiqueta.Font.Name:='Optima';

sForma:=TShape.Create(Sender);
sForma.Brush.Style:=bsClear;
sForma.Pen.Style:=psClear;
sForma.OnMouseDown:=ShapeMouseDown;

BevelInner:=bvNone;
BevelOuter:=bvNone;
Color:=clWhite;
ParentShowHint:=false;
ShowHint:=true;
AutoSize:=true;
OnMouseDown:=PanelMouseDown;
InsertControl(sForma) ;
InsertControl(lEtiqueta);
end;


saludos.

maeyanes
14-09-2007, 21:27:48
No veo nada raro en tu código...

Podrás subir la unidad del código en un archivo zip para que le eche un vistazo?


Saludos...

mauqu
14-09-2007, 21:33:21
ahí lo subi, espero que se entienda :S

gracias.

maeyanes
14-09-2007, 21:34:37
Ahí donde? :p

mauqu
14-09-2007, 21:38:36
Ahora si :D

maeyanes
14-09-2007, 21:57:39
El error de Stack Overflow se da en este método:


function TProducto.GetOnMouseDown:TMouseEvent;
begin
Result := OnMouseDown;
end;


Por que, por que estas haciendo llamadas recursivas del mismo método GetOnMouseDown...

Solucion:


function TProducto.GetOnMouseDown:TMouseEvent;
begin
Result := sForma.OnMouseDown
end;


Ahora, como estás creando un componente visual, te recomiendo que en lugar de crear un constructor propio, redefinas el de TPanel:


TProducto = class(TPanel)
// ...
public
constructor Create(AOwner: TComponent); override;
end;

implementation

constructor TProducto.Create(AOwner: TComponent);
begin
inherited;
// Inicializas tu componente...
end;


Por cierto, los métodos para asignar propiedades deben ser siempre privados, a menos que quieras hacerlos virtuales para que futuros descendientes los puedan redefinir...

Otra observación, el método MostrarMensaje lo declaras como un método abstracto, y al ser un componente visual, esto no es aconsejable, ya que para poder hacer buen uso del componente, tendrías que crear un descendiente que implementara la funcionalidad de MostrarMensaje...


Saludos....

mauqu
14-09-2007, 22:40:50
compañero, muchas gracias, el problema del overflow se debía a eso y a las propiedas height y width que las estaba asignando igual que la de onmousedown, cambié tambien el constructor y todo esta perfecto, muchas gracias.

slds.