Hola, han transcurrido nueve largos años, pero creo que vale la pena agregar un mensaje más a este hilo. Recientemente experimenté el mismo problema de subcomponentes en herencia visual; me decidí a intentar el encuentro de una solución y creo que he tenido suerte.
Primero decir que en el mismo 2004 se reportó esta anomalía en QualityCentral, es el
reporte 7991. Se trata de un defecto de fábrica que fue corregido en Delphi 2007. Lo que ahí comentó el autor del reporte no es del todo exacto, pero me sirvió para indagar más.
El siguiente código es una versión simplificada del componente con subcomponente que planteó
rastafarey, pero ya sin ocurrir excepciones al expandir el subcomponente en el inspector de objetos. La solución es básicamente volver "no guardables" las propiedades que disparan el error, y guardarlas por nuestra cuenta.
Código Delphi
[-]Unit BotonLookup;
Interface
Uses
Buttons, Classes, StdCtrls, Controls;
Type
TBotonPosition = (bpArriba, bpAbajo, bpIzquierda, bpDerecha);
TBoton = Class (TSpeedButton)
Protected
Procedure DefineProperties (Filer :TFiler); Override;
Public
Constructor Create (Owner :TComponent); Override;
Published
Property Glyph Stored False;
Property NumGlyphs Stored False;
End;
TBotonLookup = Class (TComboBox)
Protected
FBoton :TBoton;
FBotonEspacio :Integer;
FBotonPosition :TBotonPosition;
Procedure InstalarBotonInterno;
Procedure SetBotonPosition (Const Value :TBotonPosition);
Procedure SetParent (AParent :TWinControl); Override;
Public
Constructor Create (Owner :TComponent); Override;
Procedure SetBounds (ALeft, ATop, AWidth, AHeight :Integer);
Override;
Published
Property Boton :TBoton Read FBoton;
End;
Procedure Register;
Implementation
Uses
TypInfo, Types;
Constructor TBoton.Create (Owner :TComponent);
Begin
Inherited Create (Owner);
Name := 'Subboton';
SetSubComponent (True);
End;
Type
TWriterAccess = Class (TWriter);
Procedure TBoton.DefineProperties (Filer :TFiler);
Begin
Inherited DefineProperties (Filer);
If Filer Is TWriter Then
Begin
TWriterAccess (Filer).WriteProperty (
Self, GetPropInfo (Self, 'Glyph'));
TWriterAccess (Filer).WriteProperty (
Self, GetPropInfo (Self, 'NumGlyphs'));
End;
End;
Constructor TBotonLookup.Create (Owner :TComponent);
Begin
Inherited Create (Owner);
FBotonPosition := bpDerecha;
FBotonEspacio := 3;
InstalarBotonInterno;
End;
Procedure TBotonLookup.InstalarBotonInterno;
Begin
If Assigned (FBoton) Then
Exit;
FBoton := TBoton.Create(Self);
End;
Procedure TBotonLookup.SetBotonPosition (Const Value :TBotonPosition);
Var
P :TPoint;
Begin
If FBoton = Nil Then
Exit;
FBotonPosition := Value;
Case Value Of
bpArriba : P := Point (Left, Top - FBoton.Height - FBotonEspacio);
bpAbajo : P := Point (Left, Top + Height + FBotonEspacio);
bpIzquierda : P := Point (Left - FBoton.Width - FBotonEspacio, Top +
((Height - FBoton.Height) div 2));
bpDerecha : P := Point (Left + Width + FBotonEspacio, Top +
((Height - FBoton.Height) div 2));
End;
FBoton.SetBounds (P.X, P.Y, FBoton.Width, FBoton.Height);
End;
Procedure TBotonLookup.SetParent (AParent :TWinControl);
Begin
Inherited SetParent (AParent);
If FBoton <> Nil Then
FBoton.Parent := AParent;
End;
Procedure TBotonLookup.SetBounds (ALeft, ATop, AWidth, AHeight :Integer);
Begin
Inherited SetBounds (ALeft, ATop, AWidth, AHeight);
SetBotonPosition (FBotonPosition);
End;
Procedure Register;
Begin
RegisterComponents ('MisComponentes', [TBotonLookup]);
End;
End.
Creo que podría servirle a otros programadores de componentes que estén usando versiones anteriores a la 2007.
Saludos.