Объект "Поле ввода"

 

Здравствуйте уважаемые господа.

У меня проблема с написанием кода для объекта  "Поле ввода". Само поле выводится на графике. Но мне нужно, что бы по умолчанию в нем был введен текст. С помощью ObjectSetString я вставляю туда текст по умолчанию. Но когда я хоче изменить значение, значение меняется, но с поступлением нового тика, значение по умолчанию возвращается, и введенное значение сбрасывается.

Например, мне нужно в поле ввода LOT, значение по умолчанию было 0,1. Это значение ставится в форму, как только эксперт стает на график. Далее я хочу поменять значение лота на 0,01. Значение в поле меняется, но с приходом нового тика возвращается 0,1. Вот код:

void LotEntry(){ 
   lot=ObjectGetString(0,"LotEntry",OBJPROP_TEXT);
   lot=DoubleToString(Lots,3);
//--- создадим поле ввода 
   ObjectCreate(0,"LotEntry",OBJ_EDIT,0,0,0); 
//--- установим координаты объекта 
   ObjectSetInteger(0,"LotEntry",OBJPROP_XDISTANCE,5); 
   ObjectSetInteger(0,"LotEntry",OBJPROP_YDISTANCE,105); 
   ObjectSetInteger(0,"LotEntry",OBJPROP_CORNER,Cor); 
//--- установим размеры объекта 
   ObjectSetInteger(0,"LotEntry",OBJPROP_XSIZE,205); 
   ObjectSetInteger(0,"LotEntry",OBJPROP_YSIZE,20); 
//--- установим текст 
   ObjectSetString(0,"LotEntry",OBJPROP_TEXT,lot); 
//--- установим шрифт текста 
   ObjectSetString(0,"LotEntry",OBJPROP_FONT,"Tahoma"); 
//--- установим размер шрифта 
   ObjectSetInteger(0,"LotEntry",OBJPROP_FONTSIZE,10); 
//--- установим способ выравнивания текста в объекте 
   ObjectSetInteger(0,"LotEntry",OBJPROP_ALIGN,ALIGN_CENTER);  
//--- установим цвет текста 
   ObjectSetInteger(0,"LotEntry",OBJPROP_COLOR,clrNavy); 
//--- установим цвет фона 
   ObjectSetInteger(0,"LotEntry",OBJPROP_BGCOLOR,clrDodgerBlue); 
//--- установим цвет границы 
   ObjectSetInteger(0,"LotEntry",OBJPROP_BORDER_COLOR,clrCornflowerBlue);    
//--- установим (true) или отменим (false) режим только для чтения 
   ObjectSetInteger(0,"LotEntry",OBJPROP_READONLY,false); 
}

Если меняю местами первые 2 строки, тогда при выводе поля значение остается пустым по умолчанию. После его заполнения оно не сбрасывает.

   lot=DoubleToString(Lots,3);
   lot=ObjectGetString(0,"LotEntry",OBJPROP_TEXT);

Как сделать так, что бы при выводе поля ввода в нем было значение по умолчанию 0,1, и его можно было бы изменять, и при новом тике оно бы не сбрасывалось на 0,1?

 
Надо разделить создание объекта и первоначальное заполнение - отдельно. И дальнейшая работа с объектом отдельно.
 
Alexey Viktorov:
Надо разделить создание объекта и первоначальное заполнение - отдельно. И дальнейшая работа с объектом отдельно.
Вся проблема в том, что я не знаю, как это сделать.
 
Vadim Kazakevich:
Вся проблема в том, что я не знаю, как это сделать.

Так этот код не сам писал?

   lot=ObjectGetString(0,"LotEntry",OBJPROP_TEXT);

Это основная строка. Полученное значение надо перевести в тип double и его использовать.

А всё остальное переместить в функцию int OnInit() 

Один раз объект создан и больше не надо. Разве что периодически проверять не грохнул-ли случайно. Но это уже тонкости программирования.

 
Alexey Viktorov:

Так этот код не сам писал?

 lot=ObjectGetString(0,"LotEntry",OBJPROP_TEXT);

Это основная строка. Полученное значение надо перевести в тип double и его использовать.

А всё остальное переместить в функцию int OnInit() 

Один раз объект создан и больше не надо. Разве что периодически проверять не грохнул-ли случайно. Но это уже тонкости программирования.

Да! Код писал сам, и дальше я его перевожу в тип double.  А идея остальное перевести в int OnInit()  решила проблему! Спасибо!

 

А вот вопрос: можно ли каким-то образом сделать так, чтобы поле для ввода объекта OBJ_EDIT при вводе в него значения не мигало?

Т.е при этом было бы просто выделение значения или даже без выделения.

Для пояснения - на картинке ниже:



 

В каждом отдельном случае

все может быть по-своему, поэтому, конечно. В две строчки не обойтись, получилось в 16.

Может кому-то и пригодится такой вариант при схожей задаче.


bool edit_changing;
datetime time_edit_changing;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
//--- если есть использование функции OnTimer()
void OnTimer()
  {
//--- return, если редактирование OBJ_EDIT не завершено
        if (edit_changing==true) return;
        ...
  }

void OnTick() 
  {
//--- через 15 сек после начала редактирования, если курсор остался в OBJ_EDIT, сброс переменной edit_changing
        if (((TimeCurrent()-time_edit_changing>15)&&(time_edit_changing!=0))) {
            edit_changing=false;
            time_edit_changing=0;
         } 
//--- return, если редактирование OBJ_EDIT не завершено
        if (edit_changing==true) return;
        ...
  }

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- сброс переменной edit_changing, если произошло событие CHARTEVENT_OBJECT_ENDEDIT
   if ((id==CHARTEVENT_OBJECT_ENDEDIT)&&(edit_changing==true)) edit_changing=false;
//--- return, если редактирование OBJ_EDIT не завершено
   if (edit_changing==true) return;
   
   TradePanel.OnEvent(id,lparam,dparam,sparam);

//--- событие CHARTEVENT_OBJECT_CLICK на объекте типа OBJ_EDIT - по части имени объекта 
   if (id==CHARTEVENT_OBJECT_CLICK) {
      
      if ((StringSubstr(sparam,5,4)=="Edit")) {
         edit_changing=true;
         time_edit_changing=TimeCurrent();
      }
    }
        ...
  }
 
Vyacheslav Nekipelov:

В каждом отдельном случае

все может быть по-своему, поэтому, конечно. В две строчки не обойтись, получилось в 16.

Может кому-то и пригодится такой вариант при схожей задаче.


Изобретательство похвально. Но если прочесть документацию

CHARTEVENT_OBJECT_ENDEDIT

Окончание редактированиятекста в графическом объекте Edit

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

 
Alexey Viktorov:

Изобретательство похвально. Но если прочесть документацию

CHARTEVENT_OBJECT_ENDEDIT

Окончание редактированиятекста в графическом объекте Edit

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

 Можно, но неудобно, так данное событие проходит после потери фокуса у поля ввода. Например если задача онлайн отсекать неправильные символы - то это событие негодится.
 
Vladimir Karputov:
 Можно, но неудобно, так данное событие проходит после потери фокуса у поля ввода. Например если задача онлайн отсекать неправильные символы - то это событие негодится.

Что-то мои очки сломались... Солнце вижу, а контроль вводимых символов не вижу...

 
Alexey Viktorov:

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

Да, было бы можно. Но "мигание" поля ввода происходит, если нет флага до строки 

TradePanel.OnEvent(id,lparam,dparam,sparam);

и плюс с поступлением нового тика.

Запоминание редактируемого поля и начала времени его редактирования используются как раз для контроля времени ввода. На случай, если курсор так и останется в поле, то через эти 15 сек флаг редактирования принудительно будет обнулен. И OnTick() сможет выполняться полностью, не дожидаясь события CHARTEVENT_OBJECT_ENDEDIT.

Причина обращения: