DoEasy. 控件 (第 20 部分): SplitContainer WinForms 对象·进阶篇
🧩

DoEasy. 控件 (第 20 部分): SplitContainer WinForms 对象·进阶篇

(2/3)· 从透明容器派生出带 Fixed3D 边框的辅助面板,把 WinForms 布局能力往前推一步

实战向进阶 第 2/3 篇
很多人直接在图表上堆控件,却从没想过用可分隔面板统一管理子元素,结果布局一改就全乱。把 SplitContainer 当成静态装饰而非结构容器,是这类自定义库最常见的误用。本篇要做的,是给它补上真正的面板对象与边框逻辑。

「SplitContainer 面板的折叠与最小尺寸属性」

在 MT5 的 Canvas 图形库里,SplitContainer 控件用两个枚举常量控制子面板状态:MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED 与 PANEL2_COLLAPSED 分别对应面板 1、面板 2 的折叠标志位,MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE 与 PANEL2_MIN_SIZE 则限定各自最小像素尺寸。 这类属性在源码里以俄英双语字符串表登记,例如「Флаг свёрнутости панели 1」映射为「Flag to indicate that panel 1 is collapsed」,调试时若界面面板异常消失,优先查这两个 collapsed 标志。 实际写 EA 面板时,给 Panel1 设最小尺寸 30、Panel2 设 60,可避免拖拽分隔条把图表挤没;外汇与贵金属图表叠加多面板时波动行情下易误触,属高风险操作环境,参数需留余量。

MQL5 / C++
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED,   class=class="str">"cmt">// Flag for collapsed panel class="num">1
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE,  class=class="str">"cmt">// Panel class="num">1 minimum size
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_COLLAPSED,   class=class="str">"cmt">// Flag for collapsed panel class="num">1
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_MIN_SIZE,  class=class="str">"cmt">// Panel class="num">2 minimum size

class=class="str">"cmt">//--- Real properties of graphical elements
class=class="str">"cmt">//--- String properties of graphical elements
  MSG_CANV_ELEMENT_PROP_NAME_OBJ,                      class=class="str">"cmt">// Graphical element object name
  MSG_CANV_ELEMENT_PROP_NAME_RES,                      class=class="str">"cmt">// Graphical resource name
  MSG_CANV_ELEMENT_PROP_TEXT,                          class=class="str">"cmt">// Graphical element text
  MSG_CANV_ELEMENT_PROP_DESCRIPTION,                   class=class="str">"cmt">// Graphical element description
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
  {"Поле вкладки элемента управления \"TabControl\"","Tab field of the Control element \"TabControl\""},
  {"Элемент управления \"TabControl\"","Control element \"TabControl\""},
  {"Панель элемента управления \"SplitContainerPanel\"","Panel of the Control element \"SplitContainerPanel\""},
  {"Элемент управления \"SplitContainer\"","Control element \"SplitContainer\""},
  {"Элемент управления \"ArrowButton\"","Control element \"ArrowButton\""},
  {"Элемент управления \"UpArrowButton\"","Control element \"UpArrowButton\""},
class=class="str">"cmt">//--- CTabControl
  {"Не удалось получить вкладку элемента управления TabControl","Failed to get tab of TabControl"},
class=class="str">"cmt">//--- CSplitContainer
  {"Не удалось получить панель элемента управления SplitContainer","Failed to get panel of SplitContainer control"},
class=class="str">"cmt">//--- Integer properties of graphical elements
  {"Номер столбца вкладки","Tab column number"},
  {"Местоположение объекта внутри элемента управления","Location of the object inside the control"},
  {"Панель, сохраняющая свои размеры при изменении размера контейнера","Panel that retains its size when the container is resized"},
  {"Флаг перемещаемости разделителя","Separator relocatability flag"},
  {"Расстояние от края до разделителя","Distance from edge to separator"},
  {"Толщина разделителя","Separator Width"},
  {"Флаг свёрнутости панели class="num">1","Flag to indicate that panel class="num">1 is collapsed"},
  {"Минимальный размер панели class="num">1","Min size of Panel class="num">1"},
  {"Флаг свёрнутости панели class="num">2","Flag to indicate that panel class="num">2 is collapsed"},
  {"Минимальный размер панели class="num">2","Min size of Panel class="num">2"},
class=class="str">"cmt">//--- String properties of graphical elements
  {"Имя объекта-графического элемента","The name of the graphic element object"},
  {"Имя графического ресурса","Image resource name"},
  {"Текст графического элемента","Text of the graphic element"}

◍ 图形元素类型描述的查表写法

在 MT5 自定义指标或 EA 的界面层里,常需要把一个枚举 ENUM_GRAPH_ELEMENT_TYPE 转成可读字符串。上面这段来自图形基类的实现,用嵌套三元运算符一口气覆盖了从标准图元到 WinForms 容器的十余种类型。 这种写法把类型与文案的映射压进一个返回表达式,编译后就是一次线性比较,运行时几乎没有查表开销。如果你自己写面板库,直接抄这个结构比弄个 switch 更易维护,新增类型只在问号表达式里加一行。 注意被高亮的 GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER 分支:它对应可拆分布局容器,很多第三方面板用它做左右可调区域,但标准控件枚举里容易漏掉,导致描述回退成空串。开 MT5 在 CGBaseObj::TypeElementDescription 里断点跑一遍,就能确认你用的图形库版本是否带这条。

MQL5 / C++
class="type">class="kw">string CGBaseObj::TypeElementDescription(class="kw">const ENUM_GRAPH_ELEMENT_TYPE type)
  {
   class="kw">return
     (
      type==GRAPH_ELEMENT_TYPE_STANDARD                    ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD)              :
      type==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED           ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)     :
      type==GRAPH_ELEMENT_TYPE_ELEMENT                    ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_ELEMENT)              :
      type==GRAPH_ELEMENT_TYPE_SHADOW_OBJ                 ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ)           :
      type==GRAPH_ELEMENT_TYPE_FORM                       ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_FORM)                 :
      type==GRAPH_ELEMENT_TYPE_WINDOW                     ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WINDOW)               :
      class=class="str">"cmt">//--- WinForms
      type==GRAPH_ELEMENT_TYPE_WF_UNDERLAY                ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_UNDERLAY)          :
      type==GRAPH_ELEMENT_TYPE_WF_BASE                    ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BASE)              :
      class=class="str">"cmt">//--- Containers
      type==GRAPH_ELEMENT_TYPE_WF_CONTAINER               ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CONTAINER)         :
      type==GRAPH_ELEMENT_TYPE_WF_GROUPBOX                ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_GROUPBOX)          :
      type==GRAPH_ELEMENT_TYPE_WF_PANEL                   ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_PANEL)             :
      type==GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL             ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL)       :
      type==GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER         ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER)   :
      class=class="str">"cmt">//--- Standard controls
      type==GRAPH_ELEMENT_TYPE_WF_COMMON_BASE             ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_COMMON_BASE)       :
      type==GRAPH_ELEMENT_TYPE_WF_LABEL                   ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LABEL)             :
      type==GRAPH_ELEMENT_TYPE_WF_CHECKBOX                ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKBOX)          :

WinForm 控件类型与属性描述的分发写法

在 MT5 的自定义图形库里,CWinFormBase 用了一长串三元运算符把图形元素类型映射成可读文本。上面那段代码覆盖了从单选按钮、列表框到上下/左右箭头盒、分割容器面板等约 17 种 WF 控件类型,命中失败后回退到 "Unknown" 字符串。 这种写法把 type==GRAPH_ELEMENT_TYPE_WF_XXX 逐个比对,再调用 CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_XXX) 取本地化文案。最后一行高亮的 GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL 是分割布局面板,若你自己的面板没显示名称,先确认这个枚举是否进了映射链。 另一个函数 GetPropertyDescription 处理整型属性,比如 CANV_ELEMENT_PROP_ID。它用 only_prop 参数决定只回属性名还是连值一起回;不支持的属性会拼上 MSG_LIB_PROP_NOT_SUPPORTED 提示。开 MT5 把这两段塞进你的窗体基类,断点看一下返回的字符串,就能确认控件树里每个节点叫什么。

MQL5 / C++
   type==GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON           ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON)             :
   type==GRAPH_ELEMENT_TYPE_WF_BUTTON                 ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON)                   :
   type==GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX      ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX)        :
   type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX               ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX)                 :
   type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM          ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM)            :
   type==GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX       ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX)         :
   type==GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX        ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX)          :
   class=class="str">"cmt">//--- Auxiliary control objects
   type==GRAPH_ELEMENT_TYPE_WF_TAB_HEADER             ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_HEADER)               :
   type==GRAPH_ELEMENT_TYPE_WF_TAB_FIELD              ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_FIELD)                :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON           ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON)             :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP        ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP)          :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN      ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN)        :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT      ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT)        :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT     ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT)       :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX   ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX)     :
   type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX   ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX)     :
   type==GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL  ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL) :
   "Unknown"
   );
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Return the description of the control integer class="kw">property              |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">string CWinFormBase::GetPropertyDescription(ENUM_CANV_ELEMENT_PROP_INTEGER class="kw">property,class="type">bool only_prop=class="kw">false)
  {
   class="kw">return
     (
      class="kw">property==CANV_ELEMENT_PROP_ID                                      ?   CMessage::Text(MSG_CANV_ELEMENT_PROP_ID)+
      (only_prop ? "" : !this.SupportProperty(class="kw">property)      ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
         ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
      )  :
      class=class="str">"cmt">//---...
class=class="str">"cmt">//---...

「拆分容器属性的字符串拼装逻辑」

在 MT5 的 Canvas 界面库里,拆分容器(Split Container)有一组专属属性,代码用三元嵌套把属性枚举映射成可读文本。 对齐属性走的是特殊分支:如果是 CANV_ELEMENT_PROP_ALIGNMENT,会调用 AlignmentDescription 把枚举转成文字;其余拆分容器属性(如固定面板、分割条宽度、面板折叠状态等)统一用 (string)this.GetProperty(property) 直接转型输出。 当 only_prop 为 true 时只返回属性名,不附带值;若当前元素不支持该属性,则追加 MSG_LIB_PROP_NOT_SUPPORTED 提示。这套写法覆盖了至少 9 个拆分容器相关枚举,改界面调试输出时可以直接复用。 外汇与贵金属图表上挂这类自定义面板属于高风险操作,参数误设可能导致 EA 界面异常,建议在策略测试器先验证。

MQL5 / C++
class="kw">property==CANV_ELEMENT_PROP_ALIGNMENT ? CMessage::Text(MSG_CANV_ELEMENT_PROP_ALIGNMENT)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+AlignmentDescription((ENUM_CANV_ELEMENT_ALIGNMENT)this.GetProperty(class="kw">property))
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_FIXED_PANEL ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_FIXED_PANEL)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_FIXED ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_FIXED)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_COLLAPSED ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_COLLAPSED)+
     (only_prop ? "" : !this.SupportProperty(class="kw">property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
       ": "+(class="type">class="kw">string)this.GetProperty(class="kw">property)
     ) :
class="kw">property==CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_MIN_SIZE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_MIN_SIZE)+

◍ 分隔容器结构体的字段布局

在 MQL5 图形库底层,SData 结构体承担了图形元素序列化与状态还原的载体角色。它先放整型字段:id 标记元素编号,type 区分图形类别,visible_area_h 控制可视区域高度,displayed 决定控件是否在非隐藏态绘制。 被高亮的那一组字段专门服务于分隔容器(split container)。split_container_fixed_panel 指定缩放时保持尺寸的面板;split_container_splitter_fixed 控制分隔条是否可拖动;split_container_splitter_distance 是边缘到分隔条的距离,split_container_splitter_width 为其像素宽度。 split_container_panel1_collapsed 与 split_container_panel2_collapsed 是两个面板的折叠标志,配套最小尺寸字段 panel1_min_size / panel2_min_size 限制拖拽下限。字符串侧用 uchar name_obj[64] 与 uchar name_res[64] 存对象名和资源名,定长 64 字节避免动态分配。 开 MT5 在自定义指标里打印 sizeof(SData) 可验证该结构体内存占用;改 split_container_splitter_width 从默认 2 调到 5,面板分隔条会明显变粗,便于触屏点按。外汇与贵金属图表挂 EA 改 UI 参数属高风险操作,应先在策略测试器跑通。

MQL5 / C++
class="kw">struct SData
  {
   class=class="str">"cmt">//--- Object integer properties
   class="type">int               id;                                     class=class="str">"cmt">// Element ID
   class="type">int               type;                                   class=class="str">"cmt">// Graphical element type
   class=class="str">"cmt">//---...
   class=class="str">"cmt">//---...
   class="type">int               visible_area_h;                        class=class="str">"cmt">// Visibility scope height
   class="type">bool              displayed;                             class=class="str">"cmt">// Non-hidden control display flag
   class="type">int               split_container_fixed_panel;           class=class="str">"cmt">// Panel that retains its size when the container is resized
   class="type">bool              split_container_splitter_fixed;        class=class="str">"cmt">// Separator moveability flag
   class="type">int               split_container_splitter_distance;     class=class="str">"cmt">// Distance from edge to separator
   class="type">int               split_container_splitter_width;        class=class="str">"cmt">// Separator width
   class="type">bool              split_container_panel1_collapsed;      class=class="str">"cmt">// Flag for collapsed panel class="num">1
   class="type">int               split_container_panel1_min_size;       class=class="str">"cmt">// Panel class="num">1 minimum size
   class="type">bool              split_container_panel2_collapsed;      class=class="str">"cmt">// Flag for collapsed panel class="num">2
   class="type">int               split_container_panel2_min_size;       class=class="str">"cmt">// Panel class="num">2 minimum size
   class=class="str">"cmt">//--- Object real properties
   class=class="str">"cmt">//--- Object class="type">class="kw">string properties
   class="type">uchar             name_obj[class="num">64];                           class=class="str">"cmt">// Graphical element object name
   class="type">uchar             name_res[class="num">64];                           class=class="str">"cmt">// Graphical resource name
  };

图形元素的构造函数落地

把前面定义的 SData 结构真正用起来,靠的是 CGCnvElement 的带参构造函数。它一口气收下了元素类型、ID、编号、图表 ID、子窗口号,以及坐标、宽高、颜色、透明度等十几个参数,等于把画布上一个可交互控件的全部静态属性在实例化时一次性固化。 注意两个默认参数:movable 默认 true 代表用户可拖拽,redraw 默认 false 意味着除非主动调用否则不重绘。在外汇或贵金属这类高频跳动品种上,滥用 redraw=true 可能让主图卡顿,建议保持默认并在必要时手动触发。 构造函数体里先置 m_shadow 为 false,再设元素类型与 m_type=OBJECT_DE_TYPE_GELEMENT,最后把 m_element_main 和 m_element_base 置空。这意味着基类只搭骨架,具体图形指针留给后续绑定,你开 MT5 新建一个 CGCnvElement 对象时若没挂主图对象,这两个指针就会是 NULL,调试时别漏看。

MQL5 / C++
class="type">uchar text[class="num">256]; class=class="str">"cmt">// Graphical element text
 class="type">uchar descript[class="num">256]; class=class="str">"cmt">// Graphical element description
 };
 SData m_struct_obj; class=class="str">"cmt">// Object structure
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Parametric constructor                                           |
class=class="str">"cmt">//+------------------------------------------------------------------+
CGCnvElement::CGCnvElement(class="kw">const ENUM_GRAPH_ELEMENT_TYPE element_type,
                           class="kw">const class="type">int      element_id,
                           class="kw">const class="type">int      element_num,
                           class="kw">const class="type">long     chart_id,
                           class="kw">const class="type">int      wnd_num,
                           class="kw">const class="type">class="kw">string   descript,
                           class="kw">const class="type">int      x,
                           class="kw">const class="type">int      y,
                           class="kw">const class="type">int      w,
                           class="kw">const class="type">int      h,
                           class="kw">const class="type">color    colour,
                           class="kw">const class="type">uchar    opacity,
                           class="kw">const class="type">bool     movable=true,
                           class="kw">const class="type">bool     activity=true,
                           class="kw">const class="type">bool     redraw=class="kw">false) : m_shadow(class="kw">false)
  {
  this.SetTypeElement(element_type);
  this.m_type=OBJECT_DE_TYPE_GELEMENT;
  this.m_element_main=NULL;
  this.m_element_base=NULL;
把重复劳动交给小布
这些控件结构梳理和边界判定,小布盯盘的 AIGC 已内置辅助视图,打开对应品种页即可对照自己的面板参数是否合理,你只管决定怎么排布交易信息。

常见问题

SplitContainer 基于 Container 透明容器派生,内部放置两个 SplitContainerPanel 辅助对象,都是 CContainer 的后代,职责从单纯容纳变为可分隔双面板。
Studio 默认是 Fixed3D 缩进场位观感,Stamp 最接近;Bevel 等其它边框类型计划在后续篇补充,本篇先跑通静态结构。
目前小布内置的是标准品种页视图,自定义库的面板需自行编译进 EA;但小布可帮你核对边框类型与间距参数是否偏离常见视觉规范。
本篇是第 2 篇,仅做静态双面板与边框;水平隔板和拖动改尺寸会在第 3 篇实现,完整操控讨论见《DoEasy 控件·完结篇》。