对于OBJ_CHART 滚动,为什么要使用计时器?对于与界面的交互,也有类似的问题。看来使用鼠标事件就足够了。
您引用的内容并不是指OBJ_CHART,而是指整个库引擎的计时器。这就是为什么这个问题的解决方案被放在 "优化库引擎的定时器和事件处理程序 "一文的一个单独部分,作为主主题的补充。
定时器用于在鼠标移动时改变控件的颜色,以及加速滚动列表、表格、日历和输入字段中的值。
//---
附注: OBJ_CHART 的滚动只是通过鼠标光标移动事件CHARTEVENT_MOUSE_MOVE 来 实现的。下面列出的是 "标准图表 "元素(类CStandardChart)事件的处理程序(精简版)代码:
//+------------------------------------------------------------------+ //| 事件处理| //+------------------------------------------------------------------+ void CStandardChart::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- 处理光标移动事件 if(id==CHARTEVENT_MOUSE_MOVE) { //--- 如果项目被隐藏,则退出 if(!CElement::IsVisible()) return; //--- 如果处于调整子窗口大小模式,则退出 if(CheckDragBorderWindowMode()) return; //--- 如果子窗口编号不匹配,则退出 if(CElement::m_subwin!=CElement::m_mouse.SubWindowNumber()) return; //--- 如果表单被其他元素挡住,则退出 if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id()) return; //--- 重点检查 CElement::MouseFocus(m_mouse.X()>X() && m_mouse.X()<X2() && m_mouse.Y()>Y() && m_mouse.Y()<Y2()); //--- 如果有一个焦点 if(CElement::MouseFocus()) //-- 图表的水平滚动 HorizontalScroll(); //--- 如果没有焦点且鼠标左键被释放 else if(!m_mouse.LeftButtonState()) { //--- 隐藏水平滚动指针 m_x_scroll.Hide(); //--- 解锁表格 if(m_wnd.IdActivatedElement()==CElement::Id()) { m_wnd.IsLocked(false); m_wnd.IdActivatedElement(WRONG_VALUE); } } //--- return; } //... }
控制元素在鼠标移动时的定时颜色变化安排
为什么这里不能使用鼠标?
因为颜色的变化是平滑的(步数由用户设定)。
这也适用于列表的滚动。如果使用 SB 中实现的方法,则会出现锯齿状(不均匀)滚动。
在什么情况下(相对于文章中的测试智能交易系统)?
- 在滚动日历时?
- 在项目事件处理程序(CStandardChart) 中通过CHARTEVENT_MOUSE_MOVE 事件手动滚动时?
如果是前者,则图表滚动与日历滚动一样是定时的。也就是说,日历日期更改事件(ON_CHANGE_DATE) 的生成时间间隔为16 毫秒。
如果是第二种情况,则会计算出偏移量,但并不总是等于1 bar。因此,通过CHARTEVENT_MOUSE_MOVE 事件进行的手动滚动似乎才是流畅的。
明白了,谢谢!
阿纳托利,请告诉我错误的原因是什么?
更新前一切正常。现在,在创建CTable 表时却出现了这个错误。
请告诉我哪里出错了--我已经打印了每一行--界面是建好了,但在某个地方出了问题,....。错误。
归档文件中有一个示例。
找到了。
以 MQL4\Experts\Article07\TestLibrary02\TestLibrary02.mq4 为例。
从你上面的例子来看:
使列数和可见列数相同 ,编译,运行,然后出错。
//|| 创建表格|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
{
//#define COLUMNS1_TOTAL (100)
//#define ROWS1_TOTAL (1000)
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL (1000)
//--- 保存指向表单的指针
m_table.WindowPointer(m_window1);
//--- 坐标
int x=m_window1.X()+TABLE1_GAP_X;
int y=m_window1.Y()+TABLE1_GAP_Y;
//--- 可见列数和行数
int visible_columns_total =6;
int visible_rows_total =15;
//--- 创建前设置属性
m_table.XSize(600);
m_table.RowYSize(20);
m_table.FixFirstRow(true);
m_table.FixFirstColumn(true);
m_table.LightsHover(true);
m_table.SelectableRow(true);
m_table.TextAlign(ALIGN_CENTER);
m_table.HeadersColor(C'255,244,213');
m_table.HeadersTextColor(clrBlack);
m_table.CellColorHover(clrGold);
m_table.TableSize(COLUMNS1_TOTAL,ROWS1_TOTAL);
m_table.VisibleTableSize(visible_columns_total,visible_rows_total);
//--- 创建一个控件
if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
return(false);
//--- 让我们填写表格:
// 第一个单元格为空
m_table.SetValue(0,0,"-");
//--- 栏目标题
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=0; r<1; r++)
m_table.SetValue(c,r,"SYMBOL "+string(c));
}
//--- 行标题,文本对齐方式 - 向右
for(int c=0; c<1; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,"PARAMETER "+string(r));
m_table.TextAlign(c,r,ALIGN_RIGHT);
}
}
//--- 数据和表格格式化(背景颜色和单元格颜色)
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,string(c)+":"+string(r));
m_table.TextColor(c,r,(c%2==0)? clrRed : clrRoyalBlue);
m_table.CellColor(c,r,(r%2==0)? clrWhiteSmoke : clrWhite);
}
}
//-- 更新表格以显示变化
m_table.UpdateTable();
//--- 将对象添加到对象组的通用数组中
CWndContainer::AddToElementsArray(0,m_table);
return(true);
}
//+------------------------------------------------------------------+
新文章 图形界面 X: 标准图表控件 (集成编译 4)已发布:
这一次我们将研究标准图表控件。它可以创建具有同步水平滚动功能的子图表数组。此外, 我们将继续优化库代码以降低 CPU 负载。
以下的屏幕截图显示了最终结果。在这个示例中, 子图表数据可以水平地滚动, 类似于主图表那样的实现方式。此外, 子图表之间的导航通过日历操纵, 包括快速日期跳转。
图例. 2. 标准图表控件测试。
作者:Anatoli Kazharski