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 

Referencia a un formulario

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Referencia a un formulario Responder citando

A ver si soy capaz de explicarme. Tengo una función definida para un formulario concreto Form1 pero me he dado cuenta que exactamente la misma función me valdría para el resto de formularios del proyecto y me gustaría ahorrarme un montón de código y poder llamar a esa funcióndesde todos los formularios. La función sirve para pintar un LMDProgressBar dentro de un panel; ya sé que puede parece una tontería, pero es un sistema que uso hace tiempo y me funciona muy bien; es así:
Código:
void __fastcall TForm1::CreaBarra(int nOpcion)
{
     Barra = new TLMDProgressFill(this);
     Barra->Parent                   = Panel2;
     Barra->Align                    = alClient;
     Barra->Bevel->Mode              = bmStandard;
     Barra->Bevel->StandardStyle     = lsNone;
     Barra->FillObject->Style        = sfBrush;
     Barra->FillObject->TileMode     = tmCenter;
     Barra->FillObject->Alignment    = agTopCenter;
     Barra->FillObject->Brush->Color = clHighlight;
     Barra->ParentFont               = true;
     Barra->>MinValue                 = 0;
     Barra->OptionsText              = Opcion;
     Barra->UserValue                = 0;
     Barra->UseFontColor             = True;
     Panel2->Visible = true;
     Form1->Repaint();
}
//---------------------------------------------------------------------------

Mi pregunta es: ¿Qué parámetros y como debería pasarle a la función para que la usar por ejemplo un teórico Form2? Supongo que debería indicarle el formulario (Form2) y el panel donde la voy a pintar, pero no se me ocurre como.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Con una función global, no de la clase.

Código:
void __fastcall CreaBarra(TForm* Form, TLMDProgressFill* Barra, int nOpcion)
{
     Barra = new TLMDProgressFill(Form);
     Barra->Parent                   = Panel2;
     Barra->Align                    = alClient;
     Barra->Bevel->Mode              = bmStandard;
     Barra->Bevel->StandardStyle     = lsNone;
     Barra->FillObject->Style        = sfBrush;
     Barra->FillObject->TileMode     = tmCenter;
     Barra->FillObject->Alignment    = agTopCenter;
     Barra->FillObject->Brush->Color = clHighlight;
     Barra->ParentFont               = true;
     Barra->MinValue                 = 0;
     Barra->OptionsText              = Opcion;
     Barra->UserValue                = 0;
     Barra->UseFontColor             = true;
     Panel2->Visible                 = true;
     Form->Repaint();
}


Saludos.


Ultima edición por escafandra el Sab 01 May, 2010 10:16 am, editado 1 vez
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Angel, lo mismo que tu quieres yo lo hago haciendo un formulario PADRE y después HEREDO el resto de los formularios donde requiero las mismas funciones y demás. De esta manera es mucho más sencilla la reultilización del código siguiendo las bondades de la POO.

Saludos
_________________
ISC
Dobermannmx
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

dobermannmx escribió:
Angel, lo mismo que tu quieres yo lo hago haciendo un formulario PADRE y después HEREDO el resto de los formularios donde requiero las mismas funciones y demás. De esta manera es mucho más sencilla la reultilización del código siguiendo las bondades de la POO.

Saludos

Ahí me tenéis que ayudar, por que el tema de padres e hijos y herencias prácticamente no lo he usado.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Hacerlo con una función global como te insinué es sencillo pero es mas ortodoxo crear una clase base que tenga la Barra, elementos que quieras que sean comunes en las derivadas y funciones.

Si estamos hablando de un formulario, lo creas en tu proyecto como quieras sin mas. Luego, cuando quieres un formulario derivado de éste le das NEW buscas una pestaña con el nombre de tu proyecto y en ella encontraras los formularios de to proyecto. Elije el que va a ser la case madre y marca inherit. De este de derivará tu nuevo formulario y tendrá las funciones y miembros de su madre. Deberás leer algo sobre herencia y los tipos public, protected y private.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Por si no te animas a abordarlo desde el punto de vista de la herencia, que sería lo mas ortodoxo, he revisado la función global ya que como estaba no podía compilar.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

escafandra escribió:
Por si no te animas a abordarlo desde el punto de vista de la herencia, que sería lo mas ortodoxo, he revisado la función global ya que como estaba no podía compilar.

Saludos.

Gracias a los dos. Probaré antes que nada con una función global, que me parece más sencillo.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

escafandra escribió:
Con una función global, no de la clase.

Bien, ahora tengo otro problema. La forma que me sugirió escafandra es buena y se crean todos los elementos de ella; pero ¿cómo le asigno a esa barra de progreso creada el valor máximo que puede alcanzar? No se me ocurre como devolver el puntero de la barra (o lo que haga falta) al sitió donde la llamo para poder indicar MaxValue.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Tienes tres formas. La primera que la función CrearBarra te devuelva un puntero a la barra creada. La segunda que a la función CrearBarra le pases un puntero a un puntero (TLMDProgressFill** Barra) y la tercera y a mi modo de ver mas elegante, pasar una referencia a un puntero (TLMDProgressFill* &Barra)

Código:
void __fastcall CreaBarra(TForm* Form, TLMDProgressFill* &Barra, int nOpcion)
{
     Barra = new TLMDProgressFill(Form);
     Barra->Parent                   = Panel2;
     Barra->Align                    = alClient;
     Barra->Bevel->Mode              = bmStandard;
     Barra->Bevel->StandardStyle     = lsNone;
     Barra->FillObject->Style        = sfBrush;
     Barra->FillObject->TileMode     = tmCenter;
     Barra->FillObject->Alignment    = agTopCenter;
     Barra->FillObject->Brush->Color = clHighlight;
     Barra->ParentFont               = true;
     Barra->MinValue                 = 0;
     Barra->OptionsText              = Opcion;
     Barra->UserValue                = 0;
     Barra->UseFontColor             = true;
     Panel2->Visible                 = true;
     Form->Repaint();
}


Código:
TLMDProgressFill* Barra;
CreaBarra(this, Barra, 0);
Barra->MaxValue = 500;


Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

escafandra escribió:
Tienes tres formas. La primera que la función CrearBarra te devuelva un puntero a la barra creada. La segunda que a la función CrearBarra le pases un puntero a un puntero (TLMDProgressFill** Barra) y la tercera y a mi modo de ver mas elegante, pasar una referencia a un puntero (TLMDProgressFill* &Barra)

¡Perfecto! Muchísimas gracias.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

En la cabecera del .h del formulario que contine la funcion
Código:

void __fastcall CreaBarra(int nOpcion, bool Padre = true);

En el .cpp padre tienes que controlar que "Panel2" siempre exista para que sea el contendor en los otros formularios que haces la llamada. Tambien tienes que elininar el objeto Barra una vez ya lo necesites.
Código:

void __fastcall TForm1::CreaBarra(int nOpcion, bool Padre)
{
     if(Padre)
           Barra = new TLMDProgressFill(this);
     else
           Barra = new TLMDProgressFill(Owner);
              
     Barra->Parent                   = Panel2;
     Barra->Align                    = alClient;
     Barra->Bevel->Mode              = bmStandard;
     Barra->Bevel->StandardStyle     = lsNone;
     Barra->FillObject->Style        = sfBrush;
     Barra->FillObject->TileMode     = tmCenter;
     Barra->FillObject->Alignment    = agTopCenter;
     Barra->FillObject->Brush->Color = clHighlight;
     Barra->ParentFont               = true;
     Barra->>MinValue                 = 0;
     Barra->OptionsText              = Opcion;
     Barra->UserValue                = 0;
     Barra->UseFontColor             = True;
     Panel2->Visible = true;
     if(Padre)
           Form1->Repaint();
}

La llamada desde otro formulario:
Código:

#include "Form1.h"


//codigo..................

//Hecha un vistazo a "Owner", puede que lo necesites para
//la creación de "Barra = new TLMDProgressFill"
//llamada
 Form1->CreaBarra(Opcion, false);

//Llamada desde el formulario padre
Código:

CreaBarra(Opcion);


NOTA:
Si utilizas como contenedor un TFrame para la Barra de progreso el codigo te quedará disponible para cualquier Formulario sin tanta historia.
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Ciertamente lo mejor y mas ortodoxo es que la función sea de la clase y luego derivar de esta los formularios que necesites pero al parecer Angel prefiere una función global Smile

Saludos
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Esto ya es un poco de pijotería y curiosidad. Antes de usar el método que me ha explicado escafandra, tenía definida una TLMDProgressFill de manera que podía llamarla desde cualquier formulario sin necesidad de usar el típico Form1->, pero al incluir las líneas en la sección private, ¿Es imprescindible que esa definición esté DENTRO de la sección public? Me explico. Antes tenía así el include del Form1:
Código:
class TForm1 : public TForm
{
__published:   // IDE-managed Components
     [...]
private:   // User declarations
public:      // User declarations
     [...]
};
TLMDProgressFill *Barra;
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Pero al incluir lo de la barra he tenido que ponerlo así:
Código:
class TForm1 : public TForm
{
__published:   // IDE-managed Components
     [...]
private:   // User declarations
     void __fastcall CmQrProgressUpdate(TMessage& msg)
     {
          Barra->Position = msg.WParamLo;
          inherited::Dispatch(&msg);
     }

     BEGIN_MESSAGE_MAP
          MESSAGE_HANDLER(CM_QRPROGRESSUPDATE, TMessage, CmQrProgressUpdate)
     END_MESSAGE_MAP(inherited)
public:      // User declarations
     [...]
};
TLMDProgressFill *Barra;
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

De otra forma me da error en la compilación (E2451 Undefined symbol 'identifier') ¿se puede evitar. Ya digo que es más que nada por curiosidad.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Tal como lo muestras en tu código, Barra es una variable global y solo una. Es decir cada formulario que pretenda usarla serla la misma barra. Yo incluiría la variable Barra como un puntero público del formulario, así podrás acceder desde fuera del mismo. Al ser miembro de la clase Form en cuestión, tiene una barra por formulario, que creo que es lo que pretendes.

Private, protected o public se refieren al ámbito de visualización de un miembro. Los miembros públicos son visibles desde fuera de una clase, los privados no. Protected tiene su aplicación en la herencia.

En principio harás privates los miembros (variables o funciones) que no quieras que puedan ser accedidos por elementos que no son la misma clase.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Perdón por el retraso en contestar. He estado unos días fuera de mi domicilio y con follones de papeles y hasta ahora no he podido ver la respuesta; gracias por ella.

Sobre lo que comentas de que Barra es una variable global y solo una, no me importa que siempre sea la misma ya que, al menos de momento, no me hacen falta dos a la vez y poniéndola como la tengo me ahorro andar declarando Form1->Barra cada vez: De momento el proyecto, que no está completo, tiene más de 40 formularios y en casi todos uso la barra en un momento u otro. Tendría que tocar todo el código y alguno se me escaparía seguro.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
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.