Discussion of article "Graphical Interfaces X: Text selection in the Multiline Text box (build 13)" - page 7

 
Konstantin:

methods X(const int x) and Y(const int y) do not affect the position of the table in the form in any way, it is always located in the upper left corner

Relative coordinates are set when creating elements in a custom class:

//--- Create a control
   if(!m_canvas_table.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);

//---

What is the task?

 
Anatoli Kazharski:

Relative coordinates are set when elements are created in a custom class:

//---

What is the task?

to place two tables horizontally, x_gap,y_gap changes the location of horizontal scrolling and that's it ((.

PS. so, it seems to have shifted, but for some reason two tables are shifted ))

and in the method:

CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

if there are two tables, the first parameter is always 0 or is it a serial number of identical objects?

For some reason the first table moves persistently under the second table.

 
Konstantin:

...

PS. so, it seems to have shifted, but for some reason two tables have shifted ))

and in the method:

CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

if there are two tables, the first parameter is always 0 or is it a serial number of identical objects?

The first parameter is the number of the form to which the item is attached. Perhaps you add one and the same table to the common list of elements.
 
Anatoli Kazharski:
The first parameter is the number of the form to which the element is attached. Perhaps you are adding the same table to the common list of items.


what do you mean in the common list? where is it separated?

here is the method of creation in the form class:

/*!
 \brief Create object
 \param const string a_name - programme name
 \param const uint a_pause - pause for status line update
 \return true if successful, otherwise false
*/
bool CMainForm::Create(const string a_name,const uint a_pause) {
   m_counter500.SetParameters(16, a_pause);
   m_counter16.SetParameters(16, 16);

   if(!CreateForm(m_form, a_name))
      return false;

   if(!CreateStatusBar(m_status_bar, m_form, 1, STATUS_SIZE_HEIGHT))
      return false;

   if(!m_table_sign.Create(m_form, m_chart_id, m_subwin, 1, 20))
      return false;

   if(!m_table_pair.Create(m_form, m_chart_id, m_subwin, 450, 20))
      return false;
   //--- add the table object to the common array of object groups
   CWndContainer::AddToElementsArray(0, m_table_sign.GetTbl());
   CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

   m_chart.Redraw();
//---
   return true;
}

GetTbl method returns a pointer to CCanvasTable m_table

 
Konstantin:

...

Is this the result you want?

//---

I have attached an example in the archive:

Files:
 
Konstantin:

here is the create method in the form class:

GetTbl method returns a pointer to CCanvasTable m_table

//--- Create a control
   if(!m_canvas_table2.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);
//--- Add the object to the common array of object groups
   CWndContainer::AddToElementsArray(0,m_canvas_table2);
 
Anatoli Kazharski:

Do you want a result like this?

//---

Attached an example in the archive:


I did it like this:

/*!
 \brief Create object
 \param const string a_name - programme name
 \param const uint a_pause - pause for status line update
 \return true if successful, otherwise false
*/
bool CMainForm::Create(const string a_name,const uint a_pause) {
   m_counter500.SetParameters(16, a_pause);
   m_counter16.SetParameters(16, 16);

   if(!CreateForm(m_form, a_name))
      return false;

   if(!CreateStatusBar(m_status_bar, m_form, 1, STATUS_SIZE_HEIGHT))
      return false;

   if(!m_table_sign.Create(m_form, m_chart_id, m_subwin, 1, 20))
      return false;

   //--- add the table object to the common array of object groups
   CWndContainer::AddToElementsArray(0, m_table_sign.GetTbl());

   if(!m_table_pair.Create(m_form, m_chart_id, m_subwin, 450, 20))
      return false;
   //--- add the table object to the common array of object groups
   CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

   m_chart.Redraw();
//---
   return true;
}

and everything worked, it turns out that immediately after creating an object it should be placed in a container and only then create another object ))


 
Anatoli Kazharski:

No, I have tables in other classes, I use modular programming )) so it is more convenient to manage functionality - main form class, table class 1, table class 2, etc. in the end all elements are assembled in the main form class as separate ready-made objects.
 
Konstantin:

No, I have tables in other classes, I use modular programming )) so it is more convenient to manage functionality - main form class, table class 1, table class 2, etc. in the end all elements are collected in the main form class as separate ready-made objects.
Agreed. Many users of this library do this, but I can't get my hands on it. )
 
Anatoli Kazharski:
I agree. Many users of this library do that, but I just can't get my hands on it. )


By the way, there is a problem:

CWndEvents::CWndEvents(void) : m_chart_id(0),
                               m_subwin(0),
                               m_active_window_index(0),
                               m_indicator_shortname(""),
                               m_program_name(PROGRAM_NAME),
                               m_subwindow_handle(INVALID_HANDLE),
                               m_subwindow_shortname(""),
                               m_subwindows_total(1)

  {
//--- Start the timer
   if(!::MQLInfoInteger(MQL_TESTER))
      ::EventSetMillisecondTimer(TIMER_STEP_MSC);
//--- Get the ID of the current chart
   m_chart.Attach();
//--- Enable mouse event tracking
   m_chart.EventMouseMove(true);
//--- Disable command line invocation for Space and Enter keys
   m_chart.SetInteger(CHART_QUICK_NAVIGATION,false);
//--- Determine subwindow number
   DetermineSubwindow();
  }

The selected line does not allow to work in the tester. It is better to make a choice like this:

enum ENUM_GRAPHICS {
   GRAPHICS_NO    = 0,  // no need for graphics
   GRAPHICS_REAL  = 1,  // charts for real trading
   GRAPHICS_TEST  = 2   // graphics for tests
};

/*!
 Gets an indication of running programme
*/
ENUM_GRAPHICS CCheck::GetGraphics(void) { return m_graphics; }
//-----------------------------------------------------------------------------+
/*!
 Sign of graphics display
 \return sign of programme operation from the ENUM_GRAPHICS enumeration
*/
ENUM_GRAPHICS CCheck::CheckGraphicsDisplay(void) {
   if(MQLInfoInteger(MQL_OPTIMIZATION) || (MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE)))
      m_graphics = GRAPHICS_NO;
   else if(!MQLInfoInteger(MQL_OPTIMIZATION) && !MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE))
      m_graphics = GRAPHICS_REAL;
   else if(MQLInfoInteger(MQL_VISUAL_MODE))
      m_graphics = GRAPHICS_TEST;
//---
   return m_graphics;
}

and in the programme make a choice like this:

   //--- setting for OnTimer()
   uint _pause = 0;
   if(in_param.graphics == GRAPHICS_REAL)
      _pause = 500;                       // 500 ms
   else if(in_param.graphics == GRAPHICS_TEST)
      _pause = 60000;                     // 1 minute

   if(!main_form.Create(name_mts, _pause)) {
      ::Print(__FUNCTION__," > Failed to create a GUI!");
      return INIT_FAILED;
   }

or just use flags to make a selection