| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
best_guitar Lt


Registrado: 12 Nov 2005Mensajes: 92
|
Publicado: Lun 26 Nov, 2007 9:23 pm Asunto: problema de concepto |
|
|
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 |
|
 |
best_guitar Lt


Registrado: 12 Nov 2005Mensajes: 92
|
Publicado: Lun 26 Nov, 2007 9:50 pm Asunto: |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Lun 26 Nov, 2007 11:12 pm Asunto: |
|
|
| 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 |
|
 |
best_guitar Lt


Registrado: 12 Nov 2005Mensajes: 92
|
Publicado: Mar 27 Nov, 2007 9:09 pm Asunto: |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mie 28 Nov, 2007 2:06 am Asunto: |
|
|
| 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 |
|
 |
best_guitar Lt


Registrado: 12 Nov 2005Mensajes: 92
|
Publicado: Mie 28 Nov, 2007 6:54 pm Asunto: |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mie 28 Nov, 2007 8:00 pm Asunto: |
|
|
| 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 |
|
 |
best_guitar Lt


Registrado: 12 Nov 2005Mensajes: 92
|
Publicado: Jue 29 Nov, 2007 6:45 pm Asunto: |
|
|
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 |
|
 |
|