Тонкости работы графического интерфейса в MT4 - страница 3

 
TarasBY:


1) Почему не срабатывает с первого раза?

2) И как с этим бороться? 


1. потому что в МТ4 идет распределение загрузки терминала временными интервалами, где -то в документации есть инфа, что как часто передавать управление терминалу если код внутри ф-ции start() зациклен

2. если Вы работаете по приходу нового тика, тогда в одном тике одна проверка с выставление флага проверки на втором тике если есть флаг и еще проверка ... 

если код start() зациклен, тогда  

if (.....){
WindowRedraw();
Sleep(2000);
  if (........){

 

если после WindowRedraw(); вы сделаете Sleep(2000); то Вы передатите управление терминалу на 2 сек, за эти 2 сек терминал обработает действия которые он должен совержить с графическими обьектами
 

 
IgorM:


1. потому что в МТ4 идет распределение загрузки терминала временными интервалами, где -то в документации есть инфа, что как часто передавать управление терминалу если код внутри ф-ции start() зациклен

2. если Вы работаете по приходу нового тика, тогда в одном тике одна проверка с выставление флага проверки на втором тике если есть флаг и еще проверка ... 

если код start() зациклен, тогда  

if (.....){
WindowRedraw();
Sleep(2000);
  if (........){

 

если после WindowRedraw(); вы сделаете Sleep(2000); то Вы передатите управление терминалу на 2 сек, за эти 2 сек терминал обработает действия которые он должен совержить с графическими обьектами
 

Пока не могу вникнуть в смысл Вашей мысли. Код запуска всего советника:

int start()
{
    if (Timer == true)
    {
        while (IsExpertEnabled())    // Пауза для изменения параметров советника
        {
            if (main() == 1)
            {return (0);}
            Sleep (Delay);
            if (timer_set() == 1)
            {return (0);}
            migalka = IIFb ((timercolor == Lime), false, true); // делаем мигалку для якорей
            WindowRedraw();
        }
    } 
    else 
    {
        main(); 
        timer_set();
        migalka = IIFb ((timercolor == Lime), false, true); // делаем мигалку для якорей
    }
        fGetLastError ("start():");
//----
    return (0);   
}
Есть и один и другой вариант обработки команд, изложенные Вами. Но на результат это не влияет (опробованы оба варианта). Где ещё "покопать"???
 

Что-то РАЗРАБОТЧИКИ молчат...

Напрашиваются два наиболее рационально объяснимых предположения:

1) Пустой вопрос (до каждого пустого вопроса не снизойти)!
2) Такой он уродился - этот "графический интерфейс" MT4!

Я больше склоняюсь ко второму варианту... 

 
TarasBY:

Пока не могу вникнуть в смысл Вашей мысли. Код запуска всего советника:

   

мысль одна - если у Вас со второго раза происходит "попадание в цель" при работе с графическими объектами, то значит Вы не даете терминалу время совершить необходимые манипуляции с графическими объектами, не забывайте, что кроме Ваших задач у терминала собирается еще много задач которые он не выполнял, пока был занят Вашим кодом

т.е.

int start()
{    WindowRedraw();
     
    if (Timer == true)
    {
        while (IsExpertEnabled())    // Пауза для изменения параметров советника
        {
            if (main() == 1)
            {return (0);}
            Sleep (Delay);
            if (timer_set() == 1)
            {return (0);}
            migalka = IIFb ((timercolor == Lime), false, true); // делаем мигалку для якорей
            WindowRedraw();
            Sleep (2000);
        }
    } 
    else 
    {
        main(); 
        timer_set();
        migalka = IIFb ((timercolor == Lime), false, true); // делаем мигалку для якорей
    }
        fGetLastError ("start():");
//----
    return (0);   
}
попробуйте рисовать, обновлять график и дать паузу после обновления графика, потом проверять - наверно так - желтым цветом выделил
 
IgorM:

мысль одна - если у Вас со второго раза происходит "попадание в цель" при работе с графическими объектами, то значит Вы не даете терминалу время совершить необходимые манипуляции с графическими объектами, не забывайте, что кроме Ваших задач у терминала собирается еще много задач которые он не выполнял, пока был занят Вашим кодом

т.е.

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

 

Конкретное предложение - это КОНКРЕТНОЕ предложение!!!

Сделал всё, как предложили!

НО... может чуть-чуть чаще стали выполняться ответные действия на перемещение объектов... :(

Есть ещё один факт для меня не имеющий объяснения: после выделения объекта (не зависимо от того прошло ли выполнение действий на сдвиг объекта или безрезультатно), после его удаления, советник заново его рисует, но выделяться повторно этот объект отказывается!!!
"Судьба" этого объекта после выделения имеет два сценария исполнения:
1) если всё прошло успешно, выполены заложенные в коде действия, то объект удаляется програмно. И затем заново рисуется.
2) если прошёл сбой выполнения, то советник просто этому объекту возвращает его прежние координаты (через ObjectSet()).

Может здесь "собака порылась"??? 

 
TarasBY:

Конкретное предложение - это КОНКРЕТНОЕ предложение!!!



предложил я интуитивно - даже не читая кода :)

напишите с нуля код:

int start(){
while(true){

// нарисуйте обьект
//выполните WindowRedraw();
// сделайте паузу
// проверьте ObjectGet()
// удалите обьект
// WindowRedraw()
// сделайте паузу
// проверьте существование обьекта
Sleep(300);
}
return(0);
}

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

 
IgorM:


предложил я интуитивно - даже не читая кода :)

напишите с нуля код:

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

Сделал вот так:

    //---- Правило на выставление корзин (Basket_Conditions)
    if (FindObject ("rule") && ObjectGet ("rule", OBJPROP_XDISTANCE) != 120)
    //|| ObjectGet ("rule", OBJPROP_YDISTANCE) != 140))
    {
        Print ("FindObject = ", CheckBOOL (FindObject ("rule")), "; Координата X = ", ObjectGet ("rule", OBJPROP_XDISTANCE), "; КООРДИНАТА Y = ", ObjectGet ("rule", OBJPROP_YDISTANCE));
        Sleep (2000);
        DelObj ("rule");
        WindowRedraw();
        Sleep (1000);
        if (confirm ("ИЗМЕНЯЕМ ПРАВИЛО. \nПродолжить?", "Подтверждение операции", MB_YESNO) == IDYES)
        {
            Sleep (3000);
            Basket_Conditions = IIFi ((Basket_Conditions == 0), 1, IIFi ((Basket_Conditions == 1), 2, 0));
        }
        return (1);
    }
    else
        {fGetLastError ("obj_check(): Find (rule)");}

Также м\у рисование объекта и его выделением тоже поставил перерисовку и паузу:

    draw_objects();
    draw_orest();
    draw_field();
    WindowRedraw();
    Sleep (300);
    if (obj_check() == 1)
    {return (1);}

Не помогло!... :(

Заметил интересную штуку!!! Выделяю объект, затем двигаю его, снимаю выделение, объект исчезает, затем появляется на прежнем месте. На прежнем месте объект выделяться повторно отказывается, но если щёлкнуть дважы в то место куда объект был передвинут, то он ВЫДЕЛИТСЯ!!!

Чудеса да и только!!! Стоит отметить, что везде стоят WindowRedraw()!!! 

 

РЕЗУЛЬТАТ. Код, выполняющий задуманное:

    //---- Правило на выставление корзин (Basket_Conditions)
    if (GetObject ("rule", OBJPROP_XDISTANCE) != 120)
    //|| ObjectGet ("rule", OBJPROP_YDISTANCE) != 140))
    {
        Print ("FindObject = ", CheckBOOL (FindObject ("rule")), "; Координата X = ", ObjectGet ("rule", OBJPROP_XDISTANCE), "; КООРДИНАТА Y = ", ObjectGet ("rule", OBJPROP_YDISTANCE));
        Sleep (2000);
        DelObj ("rule");
        WindowRedraw();
        Sleep (1000);
        if (confirm ("ИЗМЕНЯЕМ ПРАВИЛО. \nПродолжить?", "Подтверждение операции", MB_YESNO) == IDYES)
        {
            Sleep (3000);
            Basket_Conditions = IIFi ((Basket_Conditions == 0), 1, IIFi ((Basket_Conditions == 1), 2, 0));
        }
        return (1);
    }

Я совместил проверку существования объекта с получением его свойства:

//+------------------------------------------------------------------+
//    ПОЛУЧЕНИЕ СВОЙСТВ ГРАФИЧЕСКОГО ОБЪЕКТА                         |
//+------------------------------------------------------------------+
int GetObject (string txt, int Property)
{
    int cnt, result;
//----
    if (!FindObject (txt))
    return (-1);
    else
    {
        result = ObjectGet (txt, Property);
        while (result < 0)
        {
            result = ObjectGet (txt, Property);
            if (cnt == NumberOfTry)
            {return (-1);}
            cnt++;
        }
    }
        fGetLastError (StringConcatenate ("GetObject(): Get (", txt, ")"));
//----
    return (result);
}

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

СПАСИБО всем, кто помог или пытался это сделать!!! 

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