MessageBox

Создает и отображает окно сообщений, а также управляет им. Окно сообщений содержит сообщение и заголовок, любую комбинацию предопределенных значков и командных кнопок.

int  MessageBox(
   string  text,             // текст сообщения
   string  caption=NULL,     // заголовок окна
   int     flags=0           // определяет набор кнопок в окне
   );

Параметры

text

[in]  Текст, содержащий сообщение для отображения.

caption=NULL

[in]  Необязательный текст для отображения в заголовке окна сообщения. Если этот параметр пустой, в заголовке окна будет отображено название эксперта.

flags=0

[in]  Необязательные флаги, определяющие вид и поведение диалогового окна. Флаги могут быть комбинацией специальной группы флагов .

Возвращаемое значение

Если функция успешно выполняется, возвращаемое значение - одно из значений кодов возврата MessageBox().

Примечание

Функция запрещена в пользовательских индикаторах, так как вызов MessageBox() приостанавливает работу потока исполнения на всё время ожидания ответа пользователя. А так как все индикаторы по каждому символу выполняются в едином потоке, то такая остановка сделает невозможной работу всех графиков на всех таймфреймах по данному символу.

При работе в тестере стратегий функция MessageBox() не выполняется.

 

Пример:

//+------------------------------------------------------------------+
//| Советник выводит окно MessageBox с запросом о дальнейшей работе  |
//| при достижении указанного  количества серии убыточных сделок     |
//| Ожидает заданное количество баров и выводит окно MessageBox      |
//| с запросом о продолжении работы.                                 |
//| Для проверки достаточно вручную открыть и закрыть с убытком      |
//| несколько позиций, так как для упрощения советник не контролирует|
//| "свои" позиции по магику.                                        |
//+------------------------------------------------------------------+
 
//--- input parameters
input uint InpMaxLossDeals      =  3;    // Max Loss deals
input uint InpInactivityNumBars =  5;    // Number of bars of advisor inactivity
 
//--- global variables
bool     ExtFirstStart=true;             // Флаг первого запуска
bool     ExtFlag=true;                   // Флаг разрешения работы советника
uint     ExtNumLoss;                     // Количество убыточных сделок подряд
datetime ExtTimeLastLoss;                // Время последней сделки закрытия убыточной позиции
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- получаем количество убыточных сделок подряд и время последней сделки закрытия позиции
   ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- определяем, сколько прошло баров после последней закрытой убыточной позиции в серии
   int bars_remaining=iBarShift(Symbol(),PERIOD_CURRENT,ExtTimeLastLoss);
 
//--- если это первый запуск
   if(ExtFirstStart)
     {
      //--- Если уже прошло заданное количество баров после серии убыточных позиций - устанавливаем флаг работы советника
      if(bars_remaining>(int)InpInactivityNumBars)
         ExtFlag=true;
      ExtFirstStart=false;
     }
 
//--- если флаг работы советника снят
   if(!ExtFlag)
     {
      Comment(StringFormat("The advisor is stopped for %d bars. Num Loss positions: %u, Time last loss: %s",
                          (InpInactivityNumBars-bars_remaining),ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS)));
      //--- если прошло заданное количество баров после серии убыточных позиций
      if(bars_remaining>(int)InpInactivityNumBars)
        {
         //--- выводим окно MessageBox с заданным текстом и заголовком окна
         //--- окно запроса имеет две кнопки Yes/No и иконку со знаком вопроса.
         //--- кнопка Yes выбрана по умолчанию.
         string mb_text="The specified number of bars of EA inactivity have passed.\n Continue its work?";
         string mb_caption="Please note";
         int    mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1);
         //--- если код возврата от MessageBox - нажатая кнопка Yes - устанавливаем флаг работы советника
         if(mb_id==IDYES)
           {
            ExtFlag=true;
            return;
           }
        }
      //--- флаг работы советника снят - выходим из OnTick()
      return;
     }
 
//---  флаг работы советника установлен - работает советник, как предусмотрено кодом, следующим ниже
   Comment(StringFormat("The advisor is working. Num Loss positions: %u, Time last loss: %s, Elapsed Bars: %d",
           ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS),bars_remaining));
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransactiontrans,
                        const MqlTradeRequestrequest,
                        const MqlTradeResultresult)
  {
//--- если тип транзакции - добавление сделки в историю
   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      //--- Получаем тикет сделки и выбираем сделку из списка по тикету
      ulong deal_ticket=trans.deal;
      if(HistoryDealSelect(deal_ticket))
        {
         //--- если это сделка на выход из рынка - получаем количество убыточных сделок подряд и время последней сделки
         ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         if(entry==DEAL_ENTRY_OUT || entry==DEAL_ENTRY_INOUT || entry==DEAL_ENTRY_OUT_BY)
            ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
        }
     }
 
//--- если количество убыточных сделок, идущих подряд, больше заданного значения и установлен флаг работы советника
   if(ExtNumLoss>=InpMaxLossDeals && ExtFlag)
     {
      //--- выводим окно MessageBox с заданным текстом и заголовком окна
      //--- окно запроса имеет две кнопки Yes/No и иконку с восклицательным знаком.
      //--- кнопка No выбрана по умолчанию.
      string mb_text="The number of losing trades has reached the specified maximum. The advisor is stopped.\n Continue its work?";
      string mb_caption="Attention!";
      int    mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
      //--- если код возврата от MessageBox - нажатая кнопка No - снимаем флаг работы советника
      if(mb_id==IDNO)
         ExtFlag=false;
     }
  }
//+------------------------------------------------------------------+
//| Возвращает количество убыточных сделок подряд                    |
//| и время последней сделки закрытия убыточной позиции              |
//+------------------------------------------------------------------+
uint GetNumLosingTradesInRow(datetime &time_last_deal)
  {
//--- Выбираем всю историю
   if(!HistorySelect(0,TimeCurrent()))
      return(0);
 
//--- в цикле по списку исторических сделок получаем тикет очередной сделки
   uint res=0;
   uint total=HistoryDealsTotal();
   for(int i=(int)total-1i>=0i--)
     {
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0)
        {
         //--- если сделка не на выход из позиции - идём к следующей
         ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         if(entry!=DEAL_ENTRY_OUT && entry!=DEAL_ENTRY_OUT_BY && entry!=DEAL_ENTRY_INOUT)
            continue;
         //--- если результат закрытия позиции имеет положительный профит - прерываем цикл
         if(!IsClosePositionWithLoss(deal_ticket))
            break;
         //--- увеличиваем счётчик идущих подряд сделок с отрицательной прибылью
         res++;
         //--- записываем в переменную максимальное время сделки (ищем последнюю)
         datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         if(deal_time>time_last_deal)
            time_last_deal=deal_time;
        }
     }
 
//--- Возвращаем количество идущих подряд убытков
   return(res);
  }
//+------------------------------------------------------------------+
//| Возвращает флаг закрытия позиции с убытком                       |
//+------------------------------------------------------------------+
bool IsClosePositionWithLoss(const ulong deal_ticket)
  {
//--- получаем из сделки значения свойств, влияющих на прибыль
   double profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
   double comission=HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
   double swap=HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
   double fee=HistoryDealGetDouble(deal_ticket,DEAL_FEE);
 
//--- возвращаем флаг того, что суммарное значение полученных свойств отрицательно
   return(profit+comission+swap+fee<0);
  }