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 20-02-2004
Avatar de rastafarey
rastafarey rastafarey is offline
Miembro
 
Registrado: nov 2003
Posts: 927
Poder: 21
rastafarey Va por buen camino
Error de herencia en diseño con subcomponente

Mi problema es el siguiente tengo un componente(el codigo al final) que tiro en una forma(form1) y todo funciona perfecto luego creo una nueva forma que herede de la anterior(tform2 = class(Tform1)) y cuando trato de acceder a la propiedad boton(es un sub componente) me arroja un error de diseño("Access violation at address 007C7B16 in module 'vcl70.bpl'. Read of address 00000004.") no se cuan es el problema y por que no me da el error en la forma1 y en form2 si .

Gracias de antenmano

A continuacion el codigo fuente.

unit Boton_lookup;

interface

uses
SysUtils, Classes, Controls, StdCtrls, Buttons, Messages, Types;

type
TBoton = class(TSpeedButton)
Public
Constructor Create(Padre: TComponent); Override;
End;

TBotonPosition = (bpArriba, bpAbajo, bpIzquierda, bpDerecha);

TBoton_lookup = class(TComboBox)
private
FBotonEspacio: Integer;
FBoton: TBoton;
FBotonPosition: TBotonPosition;
procedure SetBotonEspacio(const Value: Integer);
procedure SetBotonPosition(const Value: TBotonPosition);
protected
procedure SetParent(Padre: TWinControl); override;
procedure Notification(Componente: TComponent; Operacion: TOperation); override;
procedure SetName(const Value: TComponentName); override;
procedure CMVisiblechanged(var Message: TMessage); message CM_VISIBLECHANGED;
procedure CMEnabledchanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMBidimodechanged(var Message: TMessage); message CM_BIDIMODECHANGED;
public
{ Public declarations }
constructor Create(Padre: TComponent); override;
procedure SetBounds(ALeft,ATop,AWidth,AHeight: Integer); override;
procedure InstalarBotonInterno;
Published
property Boton: TBoton read FBoton;
property BotonPosition: TBotonPosition read FBotonPosition write SetBotonPosition;
property BotonEspacio: Integer read FBotonEspacio write SetBotonEspacio;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('MisComponentes', [TBoton_lookup]);
end;

{ TBoton_lookup }

procedure TBoton_lookup.CMBidimodechanged(var Message: TMessage);
begin
inherited;
FBoton.BiDiMode := BiDiMode;
end;

procedure TBoton_lookup.CMEnabledchanged(var Message: TMessage);
begin
inherited;
FBoton.Enabled := Enabled;
end;

procedure TBoton_lookup.CMVisiblechanged(var Message: TMessage);
begin
inherited;
FBoton.Visible := Visible;
end;

constructor TBoton_lookup.Create(Padre: TComponent);
begin
inherited Create(Padre);
FBotonPosition := bpDerecha;
FBotonEspacio := 3;
InstalarBotonInterno;
end;

procedure TBoton_lookup.InstalarBotonInterno;
begin
If Assigned(FBoton) Then exit;
FBoton := TBoton.Create(Self);
FBoton.FreeNotification(Self);
//FBoton.FocusControl := Self;
end;

procedure TBoton_lookup.Notification(Componente: TComponent;
Operacion: TOperation);
begin
inherited Notification(Componente, Operacion);
If (Componente = FBoton) and (Operacion = opRemove) Then
FBoton := Nil;
end;

procedure TBoton_lookup.SetBotonEspacio(const Value: Integer);
begin
FBotonEspacio := Value;
SetBotonPosition(FBotonPosition);
end;

procedure TBoton_lookup.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 TBoton_lookup.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
SetBotonPosition(FBotonPosition);
end;

procedure TBoton_lookup.SetName(const Value: TComponentName);
begin
If (csDesigning In ComponentState) And ((FBoton.GetTextLen = 0) Or (CompareText(FBoton.Caption, Name) = 0)) Then
FBoton.Caption := Value;
inherited SetName(Value);
If csDesigning In ComponentState Then
Text := '';
end;

procedure TBoton_lookup.SetParent(Padre: TWinControl);
begin
inherited SetParent(Padre);
If FBoton = Nil Then exit;
FBoton.Parent := Padre;
FBoton.Visible := True;
end;

{ TBoton }

constructor TBoton.Create(Padre: TComponent);
begin
inherited Create(Padre);
Name := 'Subboton';
SetSubComponent(True);
end;

end.

Última edición por rastafarey fecha: 20-02-2004 a las 18:02:47. Razón: Pegue dos palabras
Responder Con Cita
  #2  
Antiguo 20-02-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Hola rastafarey...

En realidad esperas que alguien lea todo este código?... y sin indentar?

Te sugiero que aprendas a utilizar la etiqueta code (link en mi firma).

Además, no explicas si para heredar del form, en tiempo de diseño, estas utilizando herencia visual, o simplemente estas sustituyendo el TForm por TForm1 en la declaración de la clase?

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #3  
Antiguo 26-02-2004
Avatar de rastafarey
rastafarey rastafarey is offline
Miembro
 
Registrado: nov 2003
Posts: 927
Poder: 21
rastafarey Va por buen camino
No espero que lean todo el codigo symplemente que intalen el conponente y vean lo que pasa.

Ha al respecto la herencia es en tiempo de diseño osea herencia viasual.

Si me sugieres que uses las etiqueta CODE no se de que manera las uso por que no se donde esta lo que hay que resaltar o subrrayar o algo asi por que no se cual es el problema.

Si me das una idea de como enviar el mensaje te lo agradesco.

Gracias de antemano.
Responder Con Cita
  #4  
Antiguo 26-02-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por rastafarey
Si me sugieres que uses las etiqueta CODE no se de que manera las uso
¿Y el enlace "Aprendé a usar la etiqueta CODE" en la firma del compañero jachguate no te dice algo?

// Saludos
Responder Con Cita
  #5  
Antiguo 06-03-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Buen día a todos!

Rastafarey: Había leído antes tu mensaje, pero como no estaba muy claro, dejé su análisis para un día más desahogado.

Es probable que sólo te falte llamar al método SetSubComponent del componente botón enseguida de su creación. Es decir:
Código:
...
FBoton := TBoton.Create (Self);
FBoton.SetSubComponent (True);
...
Espero esto sea de utilidad. Seguimos en contacto.

Al González .
Responder Con Cita
  #6  
Antiguo 12-05-2013
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
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
        { Overridden methods }
        Procedure DefineProperties (Filer :TFiler); Override;
      Public
        Constructor Create (Owner :TComponent); Override;
      Published
        { Navegando en las propiedades mostradas por el inspector de
          objetos, podemos notar que Glyph y NumGlyphs causan excepción
          "access violation".  Pero tal error ya no ocurre si les agregamos
          la directiva "Stored False".  El inconveniente de esto es que el
          IDE ya no guarda por sí mismo el valor de esas propiedades en el
          DFM, así que resulta necesario redefinir el método
          DefineProperties para encargarnos de ello (ver más abajo). }
        Property Glyph Stored False;
        Property NumGlyphs Stored False;
    End;

    TBotonLookup = Class (TComboBox)
      Protected
        FBoton :TBoton;
        FBotonEspacio :Integer;
        FBotonPosition :TBotonPosition;

        { Static methods }
        Procedure InstalarBotonInterno;
        Procedure SetBotonPosition (Const Value :TBotonPosition);

        { Overridden methods }
        Procedure SetParent (AParent :TWinControl); Override;
      Public
        Constructor Create (Owner :TComponent); Override;

        { Overridden methods }
        Procedure SetBounds (ALeft, ATop, AWidth, AHeight :Integer);
          Override;
      Published
        Property Boton :TBoton Read FBoton;
    End;

  { Functions and procedures }

  Procedure Register;

Implementation

  Uses
    TypInfo, Types;

  { TBoton }

  Constructor TBoton.Create (Owner :TComponent);
  Begin
    Inherited Create (Owner);
    Name := 'Subboton';
    SetSubComponent (True);
  End;

  { Protected overridden methods }

  Type
    TWriterAccess = Class (TWriter);
  Procedure TBoton.DefineProperties (Filer :TFiler);
  Begin
    Inherited DefineProperties (Filer);

    { Si el IDE acaba de escribir en el DFM las propiedades "formalmente"
      guardables, añadimos de forma manual las propiedades Glyph y
      NumGlyphs.  NOTA: TWriter.WriteProperty verifica si hay diferencia
      respecto al "ancestor", así se evita guardar lo mismo que ya está en
      la plantilla padre). }
    If Filer Is TWriter Then
    Begin
      TWriterAccess (Filer).WriteProperty (
        Self, GetPropInfo (Self, 'Glyph'));
      TWriterAccess (Filer).WriteProperty (
        Self, GetPropInfo (Self, 'NumGlyphs'));
    End;
  End;

  { TBotonLookup }

  Constructor TBotonLookup.Create (Owner :TComponent);
  Begin
    Inherited Create (Owner);
    FBotonPosition := bpDerecha;
    FBotonEspacio := 3;
    InstalarBotonInterno;
  End;

  { Protected static methods }

  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;

  { Protected overridden methods }

  Procedure TBotonLookup.SetParent (AParent :TWinControl);
  Begin
    Inherited SetParent (AParent);

    If FBoton <> Nil Then
      FBoton.Parent := AParent;
  End;

  { Public overridden methods }

  Procedure TBotonLookup.SetBounds (ALeft, ATop, AWidth, AHeight :Integer);
  Begin
    Inherited SetBounds (ALeft, ATop, AWidth, AHeight);
    SetBotonPosition (FBotonPosition);
  End;

  { Functions and procedures }

  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.
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 14:09:51.


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