欢迎光临散文网 会员登陆 & 注册

量化交易软件:图形界面 XI渲染控件 (统合构建14.2)

2023-07-20 16:56 作者:bili_45793681098  | 我要投稿

首篇文章 图形界面 I: 函数库结构的准备 (第 1 章) 详细研究了这个函数库。本系列每篇文章的最后, 提供了当前开发阶段的完整版函数库。文件必须放置于存档中所在的相同目录下。

在更新版的函数库中, 所有控件将在 OBJ_BITMAP_LABEL 类型的单独图形对象上绘制。此外, 赫兹量化将继续描述函数库代码的全局优化。此描述已在 以前的文章 中开始。现在赫兹量化来研究函数库中核心类的变化。新版本的函数库已经变得更加面向对象。代码变得更加简明易懂。这有助于用户根据自己的任务独立开发函数库。

编辑切换为居中


绘制控件的方法

已在 CElement 类已声明了一个 画布类的实例。其方法允许创建一个对象来绘制和删除它。若有必要, 可以获得它的指针。

class CElement : public CElementBase  { protected:   //--- 绘制控件的画布   CRectCanvas       m_canvas;   //--- public:   //--- 返回指向控件画布的指针   CRectCanvas      *CanvasPointer(void) { return(::GetPointer(m_canvas)); }  };

现在有一个通用的方法来创建一个用于绘制控件外观的对象 (画布)。它位于 CElement 基类中, 可以从函数库的所有控件类访问。CElement::CreateCanvas() 方法用于创建此类型的图形对象。作为参数, 必须传递 (1) 名称, (2) 坐标, (3) 维度和 (4) 颜色格式。省缺格式为 COLOR_FORMAT_ARGB_NORMALIZE, 这可令控件变得透明。如果传递了无效维度, 它们将在方法的开头被修正。一旦在运行 MQL 应用程序的图表上对象了创建并加载, 将会为其设置基本属性, 这在以前的所有控件类中不断重复。

class CElement : public CElementBase  { public:   //--- 创建画布   bool              CreateCanvas(const string name,const int x,const int y,                                  const int x_size,const int y_size,ENUM_COLOR_FORMAT clr_format=COLOR_FORMAT_ARGB_NORMALIZE);  }; //+------------------------------------------------------------------+ //| 创建绘制控件的画布                                                | //+------------------------------------------------------------------+ bool CElement::CreateCanvas(const string name,const int x,const int y,                            const int x_size,const int y_size,ENUM_COLOR_FORMAT clr_format=COLOR_FORMAT_ARGB_NORMALIZE)  { //--- 调整尺寸   int xsize =(x_size<1)? 50 : x_size;   int ysize =(y_size<1)? 20 : y_size; //--- 重置最后的错误   ::ResetLastError(); //--- 创建对象   if(!m_canvas.CreateBitmapLabel(m_chart_id,m_subwin,name,x,y,xsize,ysize,clr_format))     {      ::Print(__FUNCTION__," > 创建绘制控件的画布失败 ("+m_class_name+"): ",::GetLastError());      return(false);     } //--- 重置最后的错误   ::ResetLastError(); //--- 获取指向基类的指针   CChartObject *chart=::GetPointer(m_canvas); //--- 挂载到图表   if(!chart.Attach(m_chart_id,name,(int)m_subwin,(int)1))     {      ::Print(__FUNCTION__," > 将绘图画布挂载到图表失败: ",::GetLastError());      return(false);     } //--- 属性   m_canvas.Tooltip("\n");   m_canvas.Corner(m_corner);   m_canvas.Selectable(false); //--- 除窗体外, 所有控件的优先级高于主控件   Z_Order((dynamic_cast<CWindow*>(&this)!=NULL)? 0 : m_main.Z_Order()+1); //--- 坐标   m_canvas.X(x);   m_canvas.Y(y); //--- 大小   m_canvas.XSize(x_size);   m_canvas.YSize(y_size); //--- 距极点的偏移   m_canvas.XGap(CalculateXGap(x));   m_canvas.YGap(CalculateYGap(y));   return(true);  }

赫兹量化来转进到绘制控件的基本方法。它们都位于 CElement 类中, 并声明为 virtual

首先来绘制背景。在基本版中, 它只是简单地使用 CElement::DrawBackground() 方法填充颜色。如有必要, 可以启用透明度。为此, 请使用 CElement::Alpha() 方法, Alpha 通道值从 0 到 255 作为参数传递。零值意味着完全透明。在当前版本中, 透明度仅适用于背景填充和边框。文字和图像将保持完全不透明, 并清除所有 alpha 通道值。

class CElement : public CElementBase  { protected:   //--- alpha 通道值 (控件的透明度)   uchar             m_alpha;   //--- public:   //--- alpha 通道值 (控件的透明度)   void              Alpha(const uchar value)                        { m_alpha=value;                   }   uchar             Alpha(void)                               const { return(m_alpha);                 }   //--- protected:   //--- 绘制背景   virtual void      DrawBackground(void);  }; //+------------------------------------------------------------------+ //| 绘制背景                                                         | //+------------------------------------------------------------------+ void CElement::DrawBackground(void)  {   m_canvas.Erase(::ColorToARGB(m_back_color,m_alpha));  }

通常需要为特定的控件画一个边框。CElement::DrawBorder() 方法在画布对象的边缘周围绘制一个边框。Rectangle() 方法也可以用于此目的。它绘制一个未经填充的矩形。

class CElement : public CElementBase  { protected:   //--- 绘制边框   virtual void      DrawBorder(void);  }; //+------------------------------------------------------------------+ //| 绘制边框                                                         | //+------------------------------------------------------------------+ void CElement::DrawBorder(void)  { //--- 坐标   int x1=0,y1=0;   int x2=m_canvas.X_Size()-1;   int y2=m_canvas.Y_Size()-1; //--- 绘制一个未经填充的矩形   m_canvas.Rectangle(x1,y1,x2,y2,::ColorToARGB(m_border_color,m_alpha));  }

上一篇文章中已经提到可以将任意数量的图片组分配给任何控件。所以, 绘制控件的方法必须能够输出用户设置的所有图像。CElement::DrawImage() 方法即用于此目的。程序按顺序 遍历所有的组 和 其中的图片, 将它们逐像素输出到画布。在输出图像的循环开始之前, 检测组中当前所选的图片。参见此方法的代码:

class CElement : public CElementBase  { protected:   //--- 绘制图片   virtual void      DrawImage(void);  }; //+------------------------------------------------------------------+ //| 绘制图片                                                          | //+------------------------------------------------------------------+ void CElement::DrawImage(void)  { //--- 组的数量   uint group_total=ImagesGroupTotal(); //--- 绘制图片   for(uint g=0; g<group_total; g++)     {      //--- 所选图片的索引      int i=SelectedImage(g);      //--- 如果没有图片      if(i==WRONG_VALUE)         continue;      //--- 坐标      int x =m_images_group[g].m_x_gap;      int y =m_images_group[g].m_y_gap;      //--- 大小      uint height =m_images_group[g].m_image[i].Height();      uint width  =m_images_group[g].m_image[i].Width();      //--- 绘制      for(uint ly=0,p=0; ly<height; ly++)        {         for(uint lx=0; lx<width; lx++,p++)           {            //--- 如果没有颜色, 转至下一像素            if(m_images_group[g].m_image[i].Data(p)<1)               continue;            //--- 获取下层 (单元格背景) 的颜色, 和图标指定像素的颜色            uint background  =::ColorToARGB(m_canvas.PixelGet(x+lx,y+ly));            uint pixel_color =m_images_group[g].m_image[i].Data(p);            //--- 混合颜色            uint foreground=::ColorToARGB(m_clr.BlendColors(background,pixel_color));            //--- 绘制叠加图标的像素            m_canvas.PixelSet(x+lx,y+ly,foreground);           }        }     }  }

许多控件都有一个文本描述。可以使用 CElement::DrawText() 方法显示它。此方法中的若干字段允许根据控件的状态自定义文本的显示。控件有三个状态可用:


  • 锁定;

  • 按下;

  • 聚焦 (鼠标悬停)。


量化交易软件:图形界面 XI渲染控件 (统合构建14.2)的评论 (共 条)

分享到微博请遵守国家法律