Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Problema al seleccionar en un TMainMenu (https://www.clubdelphi.com/foros/showthread.php?t=92476)

Angel.Matilla 09-11-2017 13:57:36

Problema al seleccionar en un TMainMenu
 
A ver si soy capaz de explicarme. Estoy trabajando con BCB 6 y tengo un TMainMenu con unas opciones que van al mismo evento OnCLick ya que las cuatro posibilidades son para generar un listado con diferentes opciones; en la definición del TMainMenu cada una de ellas tiene asignado un valor para Tag: 11, 12, 21 y 22.

Al entrar en el evento tengo puesto esto:
Código:

TMenuItem *mOpcionLis = new TMenuItem(this);
mOpcionLis = static_cast<TMenuItem *>(Sender);
mOpcMenu = mOpcionLis;

mOpcMenu->Tag = 10 * mOpcionLis->Tag + 2 - Mensaje(2, "¿Desea diferenciar situaciones?", "Sí\nNo");

mOpcMenu es un TMenuItem y Mensaje es una fución definida por mi como una mejora de un MessageDlg. Si por ejemplo selecciono la primera de las cuatro posibles opciones y al ejecutarse esa última línea si contesto con un a la pregunta el valor de mOpcMenu->Tag será 110 y a partir de aquí genero el listado que me interesa.

El problema lo tengo si el usuario selecciona luego cualquiera de las opciones otra vez. En ese caso mOpcLis->Tag se queda con el valor calculado antes; es decir: vale, para el ejemplo, 110 y tras ejecutar otra vez esa última línea pasaría a valer, por ejemplo 1100 y por lo tanto los listados ya no hacen lo que deben.

He probado haciendo delete mOpcionLis al completar el listado, pero he visto que si hago eso me borra la opción del menú definido en el formulario. He probado poniendo static_cast y dinamic_cast o haciendo mOpcionLis->Tag = 0 al terminar, pero da lo mismo. ¿ALguna idea?

ecfisa 09-11-2017 16:39:42

Hola.

Sinceramente no comprendí a fondo como es la situación pero si en algún punto alteras el valor de la propiedad Tag y luego deseas recuperarlo, tendrás que salvarlo antes.

Por ejemplo:
Código PHP:

void __fastcall TForm::Item1234Click(TObject *Sender)
{
  
TMenuItem *mOpcMenu static_cast<TMenuItem *>(Sender);

  
// Guardar valor de Tag
  
int oTag mOpcMenu->Tag;

  
mOpcMenu->Tag 10 mOpcMenu->Tag +  2
    
Mensaje(2"¿Desea diferenciar situaciones?""Sí\nNo");

  
/*
    Generar el listado
  */

  // Restaurar valor de Tag
  
mOpcMenu->Tag oTag;


Saludos :)

Angel.Matilla 09-11-2017 19:13:04

Gracias por tu respuesta ecfisa. Ya sabía yo que iba a ser difícil entender la pregunta. Lo cierto es que algo similar a eso lo he intentado.
Código:

void __fastcall TfPersona::RecLisClick(TObject *Sender)
{
    TMenuItem *mOpcionLis = new TMenuItem(this);
    mOpcionLis = static_cast<TMenuItem *>(Sender);
    mOpcMenu = mOpcionLis;

    mOpcMenu->Tag = 10 * mOpcionLis->Tag + 2 - Mensaje(2, "¿Desea diferenciar situaciones?", "Sí\nNo");  // Calculo Tag

    Application->CreateForm(__classid(TfLisRec), &fLisRec);

    [...]

    fLisRec->ShowModal();
    delete fLisRec;
    mOpcionLis->Tag = 0;
    this->SetFocus();
}

Sin embargo a pesar de esa línea, cuando vuelve a ejecutarse el evento porque el usuario selecciona una nueva opción no me pone a cero ese valor del Tag y me guarda no ya el del ítem seleccionada si no que guarda el que se ha calculado en Calculo Tag. Es decir si en el cálculo ha salido que mOpcMenu->Tag vale 110, ese valor me lo traslada a mOpcionLis->Tag. Y ahí si que me pierdo del todo. Y ese Tag, una vez calculado, no lo toco para nada y sólo lo empleo en bucles switch...case.

Otra de las cosas que he probado es, dado que cuando se entra en el evento hay un new TMenuItem, borrar (delete mOpcionLis) el objeto, pero me he encontrado que haciendo eso me borra también la opción que está definida en el formulario.

ecfisa 09-11-2017 21:01:48

Hola.

No entiendo cual es el motivo de crear una instancia de TMenuItem en el evento RecLisClick ¿ es para resguardar el objeto original ?

Por que cuando haces,
Código PHP:

   mOpcMenu mOpcionLis

ambos punteros están igualados, de manera que cualquier cambio en uno de ellos se reflejará en el otro.

Un ejemplo de lo que me refiero:
Código PHP:

// ( Button1 fue presionado )
void __fastcall TForm1::ButtonClick(TObject *Sender)
{
  
TButton *bt = new TButton(this);

  
bt static_cast<TButton*>(Sender);  // bt == Button1
  
bt->Caption "OTRA COSA"// ahora el caption de Button1 es "OTRA COSA"
  
... 

Hubiera sido lo mismo hacer:
Código PHP:

void __fastcall TForm1::ButtonClick(TObject *Sender)
{
  
TButton *bt static_cast<TButton*>(Sender);
  
bt->Caption "OTRA COSA"// ahora el caption de Button1 es "OTRA COSA"
  
... 

O simplemente:
Código PHP:

void __fastcall TForm1::ButtonClick(TObject *Sender)
{
  (
static_cast<TButton*>(Sender))->Caption "OTRA COSA"

Es por eso que pienso que la forma de salvaguardar el valor de la propiedad Tag se reduce a,
Código PHP:

void __fastcall TfPersona::RecLisClick(TObject *Sender)
{
  
TMenuItem *aux static_cast<TMenuItem*>(Sender);
  
int oTag aux->Tag;  // salvar el valor de la propiedad Tag en oTag

  
try {
  
/*
    Hacer todas las operaciones que puedan modificar
    el valor de la propiedad Tag, enviarlo como parámetro, etc, etc...
  */
  
}
  
__finally {
    
aux->Tag oTag// restaurar el valor previo en la propiedad Tag
  
}


ese código preservará el valor con que ingresa la propiedad Tag del TMenuItem enviado como parámetro .

Pero, como ya te comenté, no sé si entiendo bien la funcionalidad de tu código y la problemática que te está acarreando.

Saludos :)

Angel.Matilla 10-11-2017 11:02:53

Cita:

Empezado por ecfisa (Mensaje 522383)
No entiendo cual es el motivo de crear una instancia de TMenuItem en el evento RecLisClick ¿ es para resguardar el objeto original ?

Tienes razón punto por punto en todo lo que me dices. Y todo parte de un error de concepto mio: Estaba convencido que al crear esa nueva instancia, efectivamente, preservaba las propiedades del objeto original. Efectivamente la solución ha sido emplear una variable en la que guardo el valor de Tag. Muchas gracias npor tu ayuda.


La franja horaria es GMT +2. Ahora son las 11:10:20.

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