Возможно ли сохранить положение кнопки посредством mq4 ??? - страница 2

 
Dmitry Ivkin:
Здравствуйте, возможно ли сохранить положение кнопки при закрытии терминала?
т.е если кинуть индюк на график и нажать 2 (справа на клавиатуре) покажется число, при повторном нажатии это число удалится
так вот, если нажать 2 --> число отобразится, далее если закрыть терминал и открыть его заного это число будет в первоначальном положении т.е его не будет!
Возможно ли сохранить/запомнить что перед закрытие число было показано, короче я думаю вы поняли о чем я. Такое возможно сделать или же нет? Если да то как!? 
Спасибо

А не надо ничего сохранять. Графические объекты сами сохраняют свое состояние. Достаточно не удалять объекты с графика. 

Надо в функции Deinint() в зависимости от причины закрытия удалять или не удалять кнопку:

void OnDeinit(const int r){
   if(r!=REASON_REMOVE){//удаление индиктара/эксперта с графика пользователем
      // удалить кнопку, и все остальные графические объекуты созданные этим индикатором
   }
   else{
      
   }
}

В справке почитайте при причины деинициализации, определитесь в каких случаях будете оставлять кнопку, в каких удалять.

В OnInit() проверять, существует ли кнопка на графике. Если существует - считать ее значение, для этого используется функция ObjectGetInteger() с идентификатором OBJPROP_STATE.

 
Dmitry Fedoseev:

А не надо ничего сохранять. Графические объекты сами сохраняют свое состояние. Достаточно не удалять объекты с графика. 

Надо в функции Deinint() в зависимости от причины закрытия удалять или не удалять кнопку:

В справке почитайте при причины деинициализации, определитесь в каких случаях будете оставлять кнопку, в каких удалять.

В OnInit() проверять, существует ли кнопка на графике. Если существует - считать ее значение, для этого используется функция ObjectGetInteger() с идентификатором OBJPROP_STATE.

Спасибо что отписались,
подскажите что не правильно я сделал в OnInit()

int OnInit()
  {
   if (ObjectFind(0,"L")>=0 || ObjectGetInteger(0, "L", OBJPROP_STATE)==0)
      draw=false;
   else
      draw=true;
   return(INIT_SUCCEEDED);
  }

Весь код теперь выглядит так:

#property copyright "Copyright 2018"
#property link      "http://www.ya.biz"
#property version   "1.00"
#property strict
#property indicator_chart_window


input int Shift=0;
int atr=0;
bool draw;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  
   if (ObjectFind(0,"L")>=0 || ObjectGetInteger(0, "L", OBJPROP_STATE)==0)
      draw=false;
   else
      draw=true;
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int r){
   if(r!=REASON_REMOVE)
   {
           ObjectDelete("L");
   }
   Comment("");
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   atr=(int)((iHigh(NULL,PERIOD_MN1,Shift)-iLow(NULL,PERIOD_MN1,Shift))/_Point);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+ 
//| ChartEvent function                                              | 
//+------------------------------------------------------------------+ 
void OnChartEvent(const int id,         // идентификатор события   
                  const long& lparam,   // параметр события типа long 
                  const double& dparam, // параметр события типа double 
                  const string& sparam  // параметр события типа string 
                  )
  {
//--- нажатие кнопки на клавиатуре 
   if(id==CHARTEVENT_KEYDOWN)
     {   
// ЭТО ТЕКСТ
      if(lparam==40)
           {
           if(draw)
              {
              PutLabel((string)atr);
              draw=false;
              }
           else
              {
              ObjectDelete(0,"L");
              draw=true;
              }
           } 
// ЭТО ТЕКСТ       
     }
  }

//+------------------------------------------------------------------+
void PutLabel(string text)
  {
   ObjectDelete(0,"L");
//--- создадим текстовую метку
   ObjectCreate(0,"L",OBJ_LABEL,0,0,0);
//--- установим координаты метки
   ObjectSetInteger(0,"L",OBJPROP_XDISTANCE,55);
   ObjectSetInteger(0,"L",OBJPROP_YDISTANCE,10);
   //--- вернем кнопку в ненажатое состояние
   ObjectSetInteger(0,"L",OBJPROP_STATE,true);
//--- установим угол графика, относительно которого будут определяться координаты точки
   ObjectSetInteger(0,"L",OBJPROP_CORNER,1);
//--- установим текст
   ObjectSetString(0,"L",OBJPROP_TEXT,text);
//--- установим шрифт текста
   ObjectSetString(0,"L",OBJPROP_FONT,"Arial");
//--- установим размер шрифта
   ObjectSetInteger(0,"L",OBJPROP_FONTSIZE,12);
//--- установим цвет
   ObjectSetInteger(0,"L",OBJPROP_COLOR,Red);
   
  }
 
Dmitry Ivkin:

я говорил про кнопку, подразумеваю то что, чтобы получить это текстовую метку нужно нажать на кнопку на клавиатуре! у меня затруднения в том что при выключении терминала текстовая метка пропадает, как я думаю т.к она не создана в калькуляторе! вот и спрашиваю что в данном случае можно сделать, я не прошу за меня написать, как выразились выше, я хочу понять почему именно так происходит!

В калькуляторе это где???

Если метку надо удалять только по нажатию на кнопку, то зачем в OnDeinit поставлено удаление??? Здесь и решение всех ваших проблем.

Кнопку нажал, проверил наличие метки, нету - метка создана.

Кнопку нажал, метка есть её надо удалить.

При закрытии терминала ничего не удаляется.

При загрузке терминала в OnInit проверка наличия метки: Есть\нету, следующее нажатие кнопки выполняет определённое условие.

 
Alexey Viktorov:

В калькуляторе это где???

Если метку надо удалять только по нажатию на кнопку, то зачем в OnDeinit поставлено удаление??? 

Чтобы при удаление индикатора всё удалялось!

 
Alexey Viktorov:

При загрузке терминала в OnInit проверка наличия метки: Есть\нету, следующее нажатие кнопки выполняет определённое условие.

У меня есть проверка в OnInit, есть текст или нет, но при закрытии терминала, и новом открытии текста нету! только если опять нажать кнопку, вот так, код приложил выше

 

Дмитрий вы вообще когда нибудь программировали? 

Попробуйте словами рассказать что вы делаете в OnInit и  OnDeinit.

Внимательно прочитайте в документации к каким объектам относится OBJPROP_STATE.

В процедуре PutLabel вы удаляете и сразу создаёте такой же объект. Просто проверьте на наличие объекта, а потом поменяйте необходимые параметры или если объекта нет создайте его. Привыкайте писать код сразу грамотно. 

 
Dmitry Ivkin:

Спасибо что отписались,
подскажите что не правильно я сделал в OnInit()

Весь код теперь выглядит так:

Кажется вы показываете не то, что делаете на самом деле. В показанном коде нет смысле в переменной draw. Проще в OnChartEvent проверять есть объект или нет, и удалять его или создавать,

 

Вот здесь что-то неправильное:

if (ObjectFind(0,"L")>=0 || ObjectGetInteger(0, "L", OBJPROP_STATE)==0)
      draw=false;
   else
      draw=true;

Если объект существует или у объекта какое-то свойство чему-то там равно. Хот я бы не || надо, а && - объект существует и его свойство такое-то. Но тогда draw долно быть true, а после else - false.

 

Дмитрий Федосеев обрати внимание на тип объекта OBJ_LABEL, свойство OBJPROP_STATE относиться к объекту типа OBJ_BUTTON, второе условие всегда будет возвращать ошибку неправильный тип объекта.

Ну а если попытаться словами рассказать весь OnInit то получиться полная ерунда.

Проверяем существует ли объект Л, допустим терминал вернул нет не существует, но заодно проверим, а есть ли у не существующего объекта некие свойства которые заранее известно что эти свойства не могут быть у данного объекта! Ну даже не знаю смеяться или плакать.

 
Vitaly Gorbunov:

Дмитрий Федосеев обрати внимание на тип объекта OBJ_LABEL, свойство OBJPROP_STATE относиться к объекту типа OBJ_BUTTON, второе условие всегда будет возвращать ошибку неправильный тип объекта.

Ну а если попытаться словами рассказать весь OnInit то получиться полная ерунда.

Проверяем существует ли объект Л, допустим терминал вернул нет не существует, но заодно проверим, а есть ли у не существующего объекта некие свойства которые заранее известно что эти свойства не могут быть у данного объекта! Ну даже не знаю смеяться или плакать.

Это здесь распространенная практика - у себя пишут одно, что-то не получается, хотят задать вопрос, но полностью код не показывают, считают его секретным. Поэтому код как-то видоизменяют, выдирают куски и только их показывают. Здесь требуется особый эвристический подход))

Был вопрос - "подскажите что не правильно я сделал в OnInit()"... а то, что там несуразица... мы же не думаем плохо о людях... это не несуразица, это режим секретности)))