Discusión sobre el artículo "Interfaces gráficas X: Selección del texto en el campo de edición multilínea (build 13)" - página 11

 
Anatoli Kazharski:

Añada pestañas antes de crear un elemento. Consulte los ejemplos en los artículos sobre tal o cual elemento. Si algo no se menciona, significa que esta característica aún no existe.

Añadir y borrar después de crear un elemento funciona ahora sólo en listas y tablas.

Es decir, ¿en esta clase el método CreateTabs es fundamental para crear pestañas? ¿Y será correcto al cambiar el número de pestañas, si usamos el método Delete y después de él usamos el método CreateTabs? ¿O es necesario volver a especificar todas las propiedades después del método Delete como en la creación inicial?
 
Konstantin:
Es decir, ¿en esta clase el método CreateTabs es fundamental para crear pestañas? Al cambiar el número de pestañas, ¿sería correcto utilizar el método Delete y después utilizar el método CreateTabs? ¿O es necesario volver a especificar todas las propiedades después del método Delete como en la creación inicial?

Sí. Primero especificamos las propiedades y luego creamos el elemento.

Por el momento no existe ningún mecanismo para eliminar correctamente los elementos en tiempo de ejecución. Permanecerán en la lista general de elementos. Pero pruébalo como lo describes en tu pregunta. Todavía no he probado esta forma.

 
Anatoli Kazharski:

Sí. Primero especificamos las propiedades y luego creamos el elemento.

Por el momento no existe ningún mecanismo para la eliminación correcta de elementos en tiempo de ejecución. Permanecerán en la lista general de elementos. Pero pruébalo como lo describes en tu pregunta. Todavía no lo he probado de esta manera.

))) Ya lo estoy probando, si todo va correctamente, postearé un ejemplo.
 

Así es como funciona:

#ifndef __TBLTABS_MQH__
#define __TBLTABS_MQH__

#include "..\\..\\..\\v1.00\\lib\\define.mqh"

#include <Arrays\List.mqh>
#include <EasyAndFastGUI\WndEvents.mqh>

//+------------------------------------------------------------------+
class CTblTabs
  {
private:
   int      m_x;
   int      m_y;
   long     m_chart_id;
   int      m_subwin;
   string   m_text[];
   int      m_width[];
   CTabs    m_tabs;
   CWindow  *m_form;

public:
                     CTblTabs(void);
                    ~CTblTabs(void);
   bool              Create(CWindow &a_form,const long a_chart_id,const int a_subwin,     // creación de objetos
                              const int a_x,const int a_y);
   void              OnLinkProgram(CList &a_pair);                                        // comunicación con el programa
   CTabs*            GetTbl(void) { return &m_tabs; }

private:
   void              UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]);   // actualizar los valores de la tabla
   bool              ReInit(CWindow &a_form,CList &a_pair,CTabs &a_tabs,string &a_text[],       // reinicialización de las fichas de los objetos
                              int &a_width[],const long a_chart_id,const int a_subwin,const int a_x,const int a_y);
  };
//+------------------------------------------------------------------+
/*!
 \brief Diseñador
*/
CTblTabs::CTblTabs(void) : m_x(0), m_y(0), m_chart_id(0), m_subwin(0), m_form(NULL) { }
/*!
 \brief Destructor
*/
CTblTabs::~CTblTabs(void) {
   m_form = NULL;
}
¡/*!
 \brief Creación de un objeto
 \param CWindow &a_form - objeto formulario
 \param const long a_chart_id - ID del gráfico
 \param const int a_subwin - subventana del gráfico
 \param const int a_x - coordenada X
 \param const int a_y - coordenada Y
 \return true if successful, otherwise false
*/
bool CTblTabs::Create(CWindow &a_form,const long a_chart_id,const int a_subwin,const int a_x,const int a_y) {
   m_x = a_x;
   m_y = a_y;
   m_chart_id = a_chart_id;
   m_subwin   = a_subwin;
   m_form     = &a_form;

   //--- arrays con texto y anchura para las pestañas
   //::ArrayResize(m_text, 1);
   //m_text[0] = "NULL_NULL";
   //::ArrayResize(m_ancho, 1);
   //m_ancho[0] = 65;

   m_tabs.WindowPointer(a_form);       // guardar el puntero al formulario

   //--- coordenadas
   int _x = a_form.X() + m_x;
   int _y = a_form.Y() + m_y;

   //--- dimensiones
   m_tabs.XSize(400);
   m_tabs.YSize(200);

   //--- propiedades
   m_tabs.TabYSize(20);
   m_tabs.PositionMode(TABS_TOP);
   m_tabs.AutoXResizeMode(true);
   m_tabs.AutoYResizeMode(true);
   m_tabs.AutoXResizeRightOffset(200);
   m_tabs.AutoYResizeBottomOffset(23);
   m_tabs.TabBorderColor(clrLightSteelBlue);
   m_tabs.SelectedTab((m_tabs.SelectedTab() == WRONG_VALUE) ? 0 : m_tabs.SelectedTab());


   //--- añadir pestañas con las propiedades especificadas
   //for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
   // m_tabs.AddTab(m_text[i], m_width[i]);

   //--- crear un control
   //if(!m_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
   //   return false;

//---
   return true;
}
/*!
 \brief Conexión con el programa
 \param CList &a_pair - puntero a la lista de pares comerciales con señales
*/
void CTblTabs::OnLinkProgram(CList &a_pair) {
   if(a_pair.Total() != m_tabs.TabsTotal())
      this.ReInit(m_form, a_pair, m_tabs, m_text, m_width, m_chart_id, m_subwin, m_x, m_y);
   else
      this.UpdateTabs(a_pair, m_tabs, m_text, m_width);
}
//+------------------------------------------------------------------+
¡/*!
 \brief Actualizar valores de pestañas
 \param CList &a_pair - puntero a la lista de pares de negociación con señales
 \param CTabs &a_tabs - objeto de tabla
 \param string &a_text[] - matriz con el nombre de las pestañas
 \param int &a_width[] - matriz con el tamaño del ancho de las pestañas
*/
void CTblTabs::UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]) {
   int _total = a_tabs.TabsTotal();
   //--- descomponer los datos en una tabla
   int _count = 0;
   for(CWrapUnitPair *_unit = a_pair.GetFirstNode(); _unit != NULL; _count++, _unit = a_pair.GetNextNode())
      a_tabs.Text(_count, _unit.data_tt[0].ticker + " " + _unit.data_tt[1].ticker);

}
¡/*!
 \brief Reinicialización del objeto pestañas
 \param CWindow &a_form - objeto formulario
 \param CList &a_pair - puntero a la lista de pares de negociación con señales
 \param CTabs &a_tabs - objeto tabla
 \param string &a_text[] - array con el nombre de las pestañas
 \param int &a_width[] - matriz con el tamaño del ancho de las pestañas
 \param const long a_chart_id - ID del gráfico
 \param const int a_subwin - subventana del gráfico
 \param const int a_x - Coordenada X
 \param const int a_y - Coordenada Y
 \return true if successful, otherwise false
*/
bool CTblTabs::ReInit(CWindow &a_form,CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[],const long a_chart_id,
                                                                                  const int a_subwin,
                                                                                  const int a_x,
                                                                                  const int a_y) {

   a_tabs.Delete();     // borrar las pestañas del objeto

   //--- reinicializar matrices de valores
   int _total = a_pair.Total();
   ::ArrayResize(a_text, _total);
   ::ArrayResize(a_width, _total);

   //--- rellenar las matrices con los nombres de las pestañas
   int _count = 0;
   for(CWrapUnitPair *_unit = a_pair.GetFirstNode(); _unit != NULL; _count++, _unit = a_pair.GetNextNode()) {
      a_text[_count]  = _unit.data_tt[0].ticker + " " + _unit.data_tt[1].ticker;
      a_width[_count] = 65;
   }

   //--- añadir pestañas con las propiedades especificadas
   for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
      a_tabs.AddTab(a_text[i], a_width[i]);

   //--- coordenadas
   int _x = a_form.X() + a_x;
   int _y = a_form.Y() + a_y;

   //--- crear un control
   if(!a_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
      return false;
//---
   return true;
}
//+------------------------------------------------------------------+

#endif // __TBLTABS_MQH__

He resaltado en color lo que ya no es necesario en el método de creación de la clase, ya que se utiliza esencialmente en el método ReInit.

Todos los mecanismos de eventos e interacción se describen en la clase de formulario principal del programa.


 
Konstantin:

así es como funciona:

Gracias por el ejemplo. Interesante.

 
Anatoli Kazharski:

Gracias por el ejemplo. Interesante.


He encontrado un fallo - si no hay pestañas, al cambiar el tamaño del gráfico (formulario), el programa se bloquea con el error array out of range in 'Tabs.mqh' (821,21)

 
Konstantin:

He encontrado un error - si no hay pestañas, al cambiar el tamaño del gráfico (formulario), el programa se bloquea con el error array out of range en 'Tabs.mqh' (821,21).

Se corregirá en la próxima actualización.
 

Cuando se crean objetos (elementos de formulario), se utiliza el método CWndContainer::AddToElementsArray(0, m_object); ¿existe algún mecanismo para eliminar correctamente un objeto dado de este contenedor?

Esto es necesario al crear / eliminar gráficos, cuando se utiliza el mecanismo anterior de añadir / eliminar pestañas.

 
Konstantin:

Cuando se crean objetos (elementos de formulario), se utiliza el método CWndContainer::AddToElementsArray(0, m_object); ¿existe algún mecanismo para eliminar correctamente un objeto dado de este contenedor?

Esto es necesario al crear/eliminar gráficos, cuando se utiliza el mecanismo anterior de añadir/eliminar pestañas.

Esto no se ha implementado todavía.

 
Anatoli Kazharski:

Esto aún no está implementado.

seria mas logico hacer el borrado a peticion del usuario de la clase, ya que al trabajar con objetos en dinamica se anima mas la interfaz, para mi tarea voy a introducir el numero de graficos por el numero de pares de ticker, pero como tengo 702 pares de ticker basados en 27 tickers, no es dificil calcular cuales serian los frenos si se va a otro mercado donde hay muchos mas tickers ))

por cierto, también comprobaré cuanta memoria consumirá tal número de pares de tickers ))