文章 "图形界面 X: 在多行文本框中选择文本 (集成构建 13)" - 页 11

 
Anatoli Kazharski:

在创建元素前添加标签。请参考文章中有关该元素或该元素的示例。如果未提及某些内容,则表示该功能尚不存在。

现在,在创建元素后添加和删除标签只适用于列表和表格。

也就是说,在该类中,CreateTabs 方法是创建标签的基本方法?如果我们使用Delete 方法,然后再使用CreateTabs 方法,那么在更改标签页数量时是否正确?还是说,在使用Delete 方法后,必须像初始创建时那样再次指定所有属性?
 
Konstantin:
也就是说,在这个类中,CreateTabs 方法是创建标签页的基本方法?在更改标签页数量时,使用Delete 方法,然后再使用CreateTabs 方法是否正确?还是必须在删除 方法之后再次指定所有属性,就像初始创建时那样?

是的,我们先指定属性,然后创建项目。

目前还没有在运行时 正确删除元素的机制。它们将保留在元素的总列表中。不过可以按照你在问题中描述的方式试试。我还没有测试过这种方式。

 
Anatoli Kazharski:

是的,我们首先指定属性,然后创建元素。

目前还没有在运行时 正确删除元素的机制。它们将保留在元素总列表中。不过你可以试试你在问题中描述的方法。我还没有测试过这种方式。

))) 我已经在尝试了,如果一切顺利,我会发布一个示例。
 

就是这样工作的:

#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,     // 创建对象
                              const int a_x,const int a_y);
   void              OnLinkProgram(CList &a_pair);                                        // 与计划沟通
   CTabs*            GetTbl(void) { return &m_tabs; }

private:
   void              UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]);   // 更新表值
   bool              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);
  };
//+------------------------------------------------------------------+
/*!
 \brief Designer
*/
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 Creating an object
 \param CWindow &a_form - form object
 \param const long a_chart_id - chart ID
 \param const int a_subwin - chart subwindow \param const int a_x - X coordinate \param const int a_y - Y coordinate \return true if successful(如果成功).const int a_subwin - 图表子窗口
 \param const int a_x - X 坐标
 \param const int a_y - 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;

   //--- 包含文本和标签宽度的数组
   //::ArrayResize(m_text, 1);
   //m_text[0] = "NULL_NULL";
   //::ArrayResize(m_width, 1);
   //m_width[0] = 65;

   m_tabs.WindowPointer(a_form);       // 保存指向表格的指针

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

   //--- 尺寸
   m_tabs.XSize(400);
   m_tabs.YSize(200);

   //--- 属性
   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());


   //--- 添加具有指定属性的选项卡
   //for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
   // m_tabs.AddTab(m_text[i], m_width[i]);

   //--- 创建一个控件
   //if(!m_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
   //   return false;

//---
   return true;
}
/*!
 \brief Connection with the program
 \param CList &a_pair -指向有信号的交易对列表的指针
*/
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 Update tab values
 \param CList &a_pair -指向有信号的交易对列表的指针
 \param CTabs &a_tabs - 表对象
 \param string &a_text[] - 包含标签名称的数组
 \param int &a_width[] - 包含标签宽度大小的数组
*/
void CTblTabs::UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]) {
   int _total = a_tabs.TabsTotal();
   //--- 将数据分解成表格
   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 重新初始化对象标签
 \param CWindow &a_form - 表格对象
 \param CList &a_pair - 带有信号的交易对列表指针 \param CTabs &a_tabs - 表格对象 \param string &a_text[] - 字符串。a_pair - 指向有信号的交易对列表的指针
 \param CTabs &a_tabs - 表格对象
 \param string &a_text[] - 标签名称数组
 \param int &a_width[] - 标签宽度大小的数组
 \param const long a_chart_id - 图表 ID
 \param const int a_subwin - 图表子窗口
 \param const int a_x - X 坐标
 \param const int a_y - 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();     // 清除对象中的标签

   //--- 重新初始化数值数组
   int _total = a_pair.Total();
   ::ArrayResize(a_text, _total);
   ::ArrayResize(a_width, _total);

   //--- 用制表符名称填充数组
   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;
   }

   //--- 添加具有指定属性的选项卡
   for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
      a_tabs.AddTab(a_text[i], a_width[i]);

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

   //--- 创建一个控件
   if(!a_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
      return false;
//---
   return true;
}
//+------------------------------------------------------------------+

#endif // __tbltabs_mqh__

我用颜色标出了类创建 方法中不再需要的内容,因为这些内容主要用于ReInit 方法

所有事件和交互机制都在程序的主窗体类中描述。


 
Konstantin:

就是这样工作的:

谢谢你的例子。真有意思

 
Anatoli Kazharski:

谢谢你的举例。很有意思。


我发现了一个错误--如果没有标签,当改变图表(表格)的大小时,程序会崩溃,出现"Tabs.mqh"(821,21)中数组超出范围的 错误。

 
Konstantin:

发现一个错误--如果没有标签,那么在改变图表(表格)的大小时,程序会崩溃,并在"Tabs.mqh"(821,21)中出现数组超出范围的 错误

下一次更新将修复这个问题。
 

创建对象(表单元素)时,使用了CWndContainer::AddToElementsArray(0, m_object); 方法,是否有任何机制可以正确地从该容器中删除给定对象?

在使用上述添加/删除选项卡的机制时,创建/删除图表时需要这样做。

 
Konstantin:

创建对象(表单元素)时,使用了CWndContainer::AddToElementsArray(0, m_object); 方法,是否有任何机制可以正确地从该容器中删除给定对象?

使用上述添加/删除选项卡的机制时,在创建/删除图表时需要这样做。

这一点尚未实现。

 
Anatoli Kazharski:

这一点尚未实现。

在我的任务中,我将根据股票对 数量输入图表的数量,但由于我有 702 个基于 27 个股票的股票对,因此不难计算出如果您进入另一个有更多股票的市场,会有多少刹车)。

顺便说一下,我还将检查这样多的股票对将消耗多少内存 ))