Skip to content
ModernUI A DaneTrades developer library

Recommended EA Structure

ModernUI EAs should read like application code, not library plumbing.

Use one main panel class that owns the UI, state, lifecycle, creation methods, helper methods, user actions, and event routing.

File order

Keep files in this order:

  1. File header and #property values
  2. #include statements
  3. Enums and constants
  4. Main EA/panel class declaration
  5. Global instance of the main class
  6. Constructor/destructor
  7. EA lifecycle methods: OnInitEvent, OnDeinitEvent, OnTimerEvent, OnChartEvent
  8. UI creation methods
  9. Helper/calculation/update methods
  10. User action methods
  11. OnMuiEvent
  12. Native MQL5 entry points

Class shape

Reference excerpt
class CTradePanel : public MuiEventSink
  {
private:
   MuiRoot          m_ui;
   MuiWindow       *m_wWindow;
   MuiButtonAction *m_bBuy;
   MuiSpinEditHost *m_seRisk;
   double           m_riskPct;

public:
   ENUM_INIT_RETCODE OnInitEvent(void);
   void              OnDeinitEvent(const int reason);
   void              OnTimerEvent(void);
   void              OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);

   void              CreateGUI(void);
   void              CreateHeader(MuiContainer *parent);
   void              CreateInputs(MuiContainer *parent);

   void              Recalculate(void);
   void              OnBuy(MuiRoot &root);

   virtual void      OnMuiEvent(MuiRoot &root,const MuiEventData &event);
  };

Naming rules

Use m_ for class member variables.

Reference excerpt
MuiRoot          m_ui;
MuiWindow       *m_wWindow;
MuiContainer    *m_cHeader;
MuiButtonAction *m_bBuy;
MuiCheckbox     *m_cbConfirm;
MuiSpinEditHost *m_seRisk;
MuiSlider       *m_sRiskReward;
MuiLabel        *m_lRisk;
MuiBadge        *m_bdSymbol;
MuiDrawer       *m_dSettings;

Common prefixes:

Prefix Meaning
m_w Window
m_c Container
m_b Button
m_cb Checkbox
m_se Spin edit
m_tb Text box
m_ta Text area
m_l Label
m_bd Badge
m_s Slider
m_d Drawer
m_dlg Dialog
m_sb Status bar

Event IDs

Use enums to name UI intent.

Reference excerpt
enum TRADE_PANEL_ACTION
  {
   TP_ACTION_OPEN_SETTINGS,
   TP_ACTION_BUY,
   TP_ACTION_SELL,
   TP_ACTION_INPUT_CHANGED,
   TP_ACTION_CONFIRM_TRADES
  };

Assign IDs directly after creating interactive controls.

UI build fragment
m_bBuy=Mui::Button(row,"BUY");
m_bBuy.Id(TP_ACTION_BUY);

MuiLabeledSpinEdit risk=Mui::LabeledSpinEdit(row,"Risk %",0.01,5.0,0.05,1.0,2);
m_seRisk=risk.control;
m_seRisk.Id(TP_ACTION_INPUT_CHANGED);

Event routing

Connect the event sink once after m_ui.Init(...) succeeds.

Reference excerpt
if(!m_ui.Init(ChartID(),0,"TradePanel_",512,16))
   return INIT_FAILED;

m_ui.SetEventSink((MuiEventSink*)GetPointer(this));

Handle UI events in one method.

Reference excerpt
void CTradePanel::OnMuiEvent(MuiRoot &root,const MuiEventData &event)
  {
   if(event.EventId()==MUI_EVENT_CLICK)
     {
      if(event.ControlId()==TP_ACTION_BUY)
         OnBuy(root);
      else if(event.ControlId()==TP_ACTION_SELL)
         OnSell(root);
      return;
     }

   if(event.EventId()==MUI_EVENT_VALUE_CHANGED && event.ControlId()==TP_ACTION_INPUT_CHANGED)
      Recalculate();
  }

Do not write one custom handler class per control in normal EAs.

UI creation rules

Split UI creation into section methods.

Reference excerpt
void CreateGUI(void);
void CreateHeader(MuiContainer *parent);
void CreateRiskInputs(MuiContainer *parent);
void CreateExecutionButtons(MuiContainer *parent);
void CreateSettingsDrawer(void);

Each creation method should create one section, store important controls in m_ members, assign IDs to interactive controls, and keep layout settings near creation.

Native entry points

Native MQL5 entry points should stay thin.

Reference excerpt
CTradePanel Panel;

int OnInit()
  {
   return Panel.OnInitEvent();
  }

void OnDeinit(const int reason)
  {
   Panel.OnDeinitEvent(reason);
  }

void OnTimer()
  {
   Panel.OnTimerEvent();
  }

void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   Panel.OnChartEvent(id,lparam,dparam,sparam);
  }

Related pages