Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

problema de concepto

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: problema de concepto Responder citando

Tengo un problema de concepto y de conocimiento sobre los objetos y componentes de Builder.

Mi intencion es crear un objeto que derive de TButton, pero que en apariencia sea un TShape. Mas bien dicho quiero que un TShape tenga la posibilidad de utilizar el evento 'click'.
Para esto defino un objeto llamado BotonLuz, como sigue:

BotonLuz.h

Código:

#include <SysUtils>
#include <Controls>
#include <Classes>
#include <Forms>
#include <StdCtrls>

class TBotonLuz:public TButton
{
private:
  int identificador;
  int estado;
  TShape *luz;
protected:
public:
  TBotonLuz(TComponent* Owner, int ident);
//  ~TBotonLuz();       Por que no me deja crear el destructor del objeto?
  int getEstado(void);
  void setEstado(int est);
};


No me deja generar el destructor. Porque?

BotonLuz.cpp
Código:

#include <vcl>
#pragma hdrstop
#include "TBotonLuz.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TBotonLuz::TBotonLuz (TComponent* Owner,int ident) : TButton(Owner)
{
   this->identificador = ident;
   TShape *shape = new TShape(this);
   this->luz = shape;
   shape->Parent = this;
   shape->Name = "BotonLuz";
   shape->Shape = stCircle;
   shape->Brush->Style = stCircle;
   shape->Visible = true;
}

/*TBotonLuz::~TBotonLuz()
{
   delete []luz;
}
*/
int TBotonLuz::getEstado(void)
{
return this->estado;
}

void TBotonLuz::setEstado(int est)
{
   this->estado = est;
}


Unit1.cpp
Código:

#include "Unit1.h"
#include "TBotonLuz.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   TBotonLuz *bluz1 = new TBotonLuz(Owner,1);
   bluz1->Top = 0;
   bluz1->Left = 0;
   bluz1->Width = 50;
   bluz1->Height = 50;
   bluz1->Visible = true;
   bluz1->//no me deja acceder a la propiedad luz de tipo TShape de TBotonLuz
}


Imagino que no puedo acceder a las propiedades del objeto TShape, por que son privadas para una clase exterior. Alguien me puede explicar, en que me equivoco? como podria enfocar el problema?

Gracias foro.
_________________
Be water my friend.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

He visto que si aplico
Código:

TShape *shape = new TShape (Owner);


me estoy refiriendo al Formulario, corregidme si me equivoco.

Posteriormente he puesto el objeto TShape como publico y puedo acceder a *luz.

Pero no consigo que el objeto me aparezca en pantalla, me podeis ayudar? he probado con enables, visibles... y nada.
_________________
Be water my friend.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

best_guitar escribió:
Por que no me deja crear el destructor del objeto?

Te falta anteponer "__fastcall" a su declaración igual que el destructor base.
best_guitar escribió:
no me deja acceder a la propiedad luz de tipo TShape de TBotonLuz

Tendrías que declararlo en el apartado public para que sea accesible desde fuera de la clase..
best_guitar escribió:
Pero no consigo que el objeto me aparezca en pantalla, me podeis ayudar? he probado con enables, visibles... y nada.

Te falta especificar quien es el padre visual del control, con "Parent".

Si lo único que quieres es un TShape que al pulsar encima cambie de estado yo lo haría así:
Código:
class TBotonLuz : public TShape
{
private:
    bool _estado;
    TNotifyEvent _cambioDeEstado;

public:
    __fastcall TBotonLuz(TComponent* owner) : TShape(owner)
    {
        // Deshabilitamos el doble-click para que
        //  el efecto al pulsar rapido sea mejor
        ControlStyle >> csDoubleClicks;
        _estado = false;
        Shape = stCircle;
        Width = 16;
        Height = 16;
        Brush->Color = clGray;
        OnClick = Clicked;
    }

    // Al pulsar sobre el shape cambiamos al estado contrario al que tenia
    void __fastcall Clicked(TObject* sender)
    {
        SetEstado(!_estado);
    }

    // Cuando el estado sea true lo mostramos "encendido"
    void __fastcall SetEstado(bool est)
    {
        if (_estado != est)
        {
            _estado = est;
            Brush->Color = _estado ? clLime : clGray;
            if (_cambioDeEstado)
                OnCambioDeEstado(this);
        }
    }

__published:
    __property bool Estado = {read=_estado, write=SetEstado, default=false};
    __property TNotifyEvent OnCambioDeEstado = {read=_cambioDeEstado, write=_cambioDeEstado};
};

Y para mostrarlo:
Código:
TBotonLuz* bluz = new TBotonLuz(this);
bluz->Parent = this;
bluz->Top = 10;
bluz->Left = 10;

Luego tienes la propiedad "Estado" para ver el estado o cambiarlo y el evento opcional "OnCambioDeEstado" que saltaría cuando cambie de estado el control.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola _Leo, ante todo gracias por la respuesta, aunque debo confesar que necesito un rato más para asimilar el codigo, ya que, utilizas construcciones que no estoy acostumbrado, por mi falta de manejo.

decias...
Te falta especificar quien es el padre visual del control, con "Parent".

En el código que tenia al principio, quien era el parent?

Otra pregunta...
Porque al derivar el objeto de TShape se le permite usar la función 'OnClick'?

Y la última...
Como debería tratar el evento 'OnCambioDeEstado'? Quiero decir, que parametros debo pasarle?

Muchas gracias. Estudiaré el código.
_________________
Be water my friend.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

best_guitar escribió:
decias... Te falta especificar quien es el padre visual del control, con "Parent".

Me refería a que debes usar la propiedad "Parent" para especificar el contenedor visual de tu objeto. Cambiando la línea innecesaria:
Código:
bluz1->Visible = true;

por:
Código:
bluz1->Parent = Form1;


best_guitar escribió:
Porque al derivar el objeto de TShape se le permite usar la función 'OnClick'?

“TShape” tiene como ancestro a “TControl”, donde se define este evento.


best_guitar escribió:
Como debería tratar el evento 'OnCambioDeEstado'? Quiero decir, que parametros debo pasarle?

Para esto solo tienes que pasarle el puntero de la función que quieres que se llame cuando se produzca un cambio utilizando la propiedad "OnCambioDeEstado". Por ejemplo:

(Observa la declaraciones para saber que argumentos se esperan en cada caso, tanto mirando las cabeceras, como en la propia ayuda)

Código:

// Creamos la función que queremos enlazar con el evento
//  (añade la correspondiente declaración en la cabecera...)
void __fastcall TForm1::BotonLuzCambioDeEstado(TObject* sender)
{
    ShowMessage("Se ha producido un cambio de estado.");
}


Y a la creación del objeto añadimos la siguiente línea:
Código:
bluz->OnCambioDeEstado = BotonLuzCambioDeEstado;


Espero que se haya entendido bien..
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Estoy viendo que tengo mucho que aprender, y me voy a pillar un libro de Builder. ¿Me recomendais alguno en especial?

_Leo decia...
'"TShape" tiene como ancestro a "TControl" donde se define este evento (OnClick)'

Entonces, ¿porqué si agrego un componente al formulario de tipo TShape no puedo acceder a esta función?


Tendré en cuenta los consejos, Gracias.
_________________
Be water my friend.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

best_guitar escribió:
Entonces, ¿porqué si agrego un componente al formulario de tipo TShape no puedo acceder a esta función?

Porque en la clase "TControl", "OnClick" está declarado en el apartado protegido, por tanto accesible internamente a las clases descendientes.

Por ejemplo si quisieras crear una clase "TShape" con el OnClick visible en tiempo de diseño, solo tendrías que crear un componente descendiente de esta y añadir bajo el apartado "__published" el "OnClick":

class TShapeX : public TShape
{
private:
protected:
public:
    __fastcall TShapeX(TComponent* Owner);
__published:
    __property OnClick;
};

best_guitar escribió:
me voy a pillar un libro de Builder. ¿Me recomendais alguno en especial?

En cuanto a libros, yo creo que cualquier libro de Francisco Charte esta bien, suelen dar un repaso general, empezando por conceptos generales de C++ y acabar con temas un poco más avanzados de creación de componentes. Y luego ya un poco más avanzado, para mi uno de los mejores es el "C++Builder 5/6 Developer's Guide".
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias _Leo has sido de gran ayuda y además he visto un poco el camino que debo seguir para aprender sobre este magnifico compilador de C++.
_________________
Be water my friend.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.