程序库: 用于创建图形界面的 EasyAndFastGUI 开发库 - 页 8

 

编译 ExampleEAF.mq5 就成功了。

我以为当我想用它创建自己的东西时,我必须编译一个库。

不过,还是非常感谢!

对了,我在大多数库文件的顶部偶然发现了这行代码:

class CWindow;

创建 "假类 "是否是避免 #include 恶梦的窍门?编译器以后如何才能链接到真正使用的正确类?

 

首先,我想最后确定我们所拥有的...毕竟还有很多不足之处。

关于架构,我有一些看法。 指定的对象属性 和显示的图片各过各的日子,互不相干。 而且必须 调用 Update(),否则它们将处于并行现实中。 考虑到我们有一个基于事件的模型,我认为这是错误的。手动更新(重绘)不应该是一个先决条件,它只能让你立即显示变化,但无论如何都应该显示所有的变化。 为此,应该发送一条消息(事件)来重绘这个对象,稍后再进行处理。

即大致如下

class CSomeControl
{
  int  m_property;
  bool m_changed;
  bool m_event_sent;
 public:
  void Property(int value)  { m_property= value;  m_changed=true;  if (!m_event_sent) m_event_sent= EventChartCustom(m_chart_id, ON_CHANGE, m_id, 0, 0); }  

  void Update()             { /*重新绘制......*/。  m_changed=false; }

  void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {  
    if (id==CHARTEVENT_CUSTOM+ON_CHANGE) { m_event_sent=false;  if (m_changed) Update(); }
  }                       
};
 

我使用 ChangeWindowWidth 更改了窗口宽度,使其超出当前图表。 之后,当我尝试移动该窗口时,它会自动粘在图表左侧边缘。 如何禁用此功能? 我在代码中找不到相关位置。

 
Alexey Navoykov:

我使用 ChangeWindowWidth 更改了窗口宽度,使其超出当前图表。 之后,当我尝试移动该窗口时,它会自动粘在图表左侧边缘。 如何禁用此功能? 我在代码中找不到相关位置。

您需要重写CWindow::UpdateWindowXY() 方法。目前的实现方式是,当移动窗口时,窗口边缘不能超出图表。

 

顺便说一下更改窗口宽度的问题

   m_window1.ChangeWindowWidth(NEW_WIDTH);
   m_window1.Update(true);

在 MT5 中一切正常,但在 MT4 中是这样的

点击标题后,按钮会移动到合适的位置。您能告诉我该怎么看吗?这些按钮的移动是在哪里实现的?

 
Oleksii Chepurnyi:

顺便说一下更改窗口宽度的问题

在 MT5 中一切正常,但在 MT4 中是这样的

点击页眉后,按钮会移动到合适的位置。您能告诉我该怎么看吗?这些按钮的移动是在哪里实现的?

请查看Moving() 方法。

尝试通过指针访问窗口按钮并调用该方法。

 
Alexey Navoykov:

最好是后者。

但在当前版本中,即使你自己实现也是有问题的,因为我没有在你的类中找到获取当前列宽的方法,而且所有字段都是私有的。 一般来说,至少应该添加这个方法。

您可以尝试用这种方法来实现您现在需要的功能:

//-- 窗口大小调整事件
   if(id==CHARTEVENT_CUSTOM+ON_WINDOW_CHANGE_YSIZE)
     {
      //-- 调整摘要表列的宽度
      if(m_table_symbols.RowsTotal()>(uint)m_table_symbols.VisibleRowsTotal())
        {
         int width[]={79};
         m_table_symbols.ColumnsWidth(width);
        }
      else
        {
         int width[]={95};
         m_table_symbols.ColumnsWidth(width);
        }
      //---
      m_table_symbols.Update(true);
      m_table_symbols.GetScrollVPointer().CurrentPos(0);
      m_table_symbols.GetScrollVPointer().Update(true);
      return;
     }
 
Anatoli Kazharski:

看看Moving() 方法。

尝试通过指针访问窗口按钮并调用该方法。

是的,就是这样:)谢谢!

我以为我已经看完了所有内容,却忽略了最明显的地方:)

 
Anatoli Kazharski:

这样,你就能努力实现你现在的需求:

这只是一个固定的列宽,但我们之前讨论的是根据列宽动态改变列宽。 不过,我已经在该类中添加了 int ColumnWidth(int i) 方法,从而完成了该类的构建

 

下午好。

问题比较大)

我们创建了一个动态对象,例如一个标签

   labels[i] = new CTextLabel;
   labels[i].MainPointer(m_window1);
   labels[i].XSize(SYMBOLS_COL_WIDTH);
   labels[i].YSize(HEAD_HIGHT);
   labels[i].Alpha(SYMBOLS_HEAD_BACK_ALPHA);
   labels[i].FontSize(SYMBOLS_HEAD_FONT_SIZE);
   labels[i].TextAlign(SYMBOLS_HEAD_TEXT_ALIGN,HORIZONTAL_SPACE,0);
   labels[i].FontStyle(SYMBOLS_HEAD_FONT_STYLE);
   labels[i].BackColor(SYMBOLS_HEAD_BACK_COLOR);
   labels[i].CreateTextLabel("0",x_gap,ProfitHeadGap);
   CWndContainer::AddToElementsArray(0,labels[i]);
   labels[i].Update(true);

但如何删除它?

我是这样删除的。

      labels[i].Delete();
      delete labels[i];

但删除后就会崩溃,提示访问指针不正确。

据我所知,CWndContainer::AddToElementsArray 会将对象添加到公共数组中,但 Delete() 并不能将其删除,而且窗口还会尝试访问该对象。我找不到与 Delete() 类似的其他方法。

如何正确删除对象?