Тестируем CGraphic - вопросы и предложения - страница 11

 
Artyom Trishkin:

В общем, устал я вам объяснять. Кто хочет - тот поймёт.

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

 
Aleksey Vyazmikin:


Указывает на этот код - D.PointsFill(false);

Ошибка была в связи с разным размером массивов X и Y - почему нельзя было об этом писать в логе - загадка.

 
Aleksey Vyazmikin:

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

Запомните просто одно: в _LastError вписывается не только код реальной ошибки, но и коды сообщений о работе функций. В обсуждаемом случае - там как раз вписан код того, что нет объекта. И всё зависит от контекста, при котором запрашивается объект с определённым именем. Если для модификации объекта, то такой код укажет о необходимости понять - а почему это мой объект вдруг пропал.., а если для создания нового объекта, то код, говорящий что нет такого объекта - тут как раз наоборот - всё хорошо и можно создавать.

И примите за правило: проверять нужно результат возврата функции и, если она возвращает реальную ошибку, то уже тогда анализировать код ошибки.

Вы же в своём примере голову себе морочите тем, что было успешное создание объекта-канваса, а вы думаете, что там где-то ошибка.

 
Artyom Trishkin:

Запомните просто одно: в _LastError вписывается не только код реальной ошибки, но и коды сообщений о работе функций. В обсуждаемом случае - там как раз вписан код того, что нет объекта. И всё зависит от контекста, при котором запрашивается объект с определённым именем. Если для модификации объекта, то такой код укажет о необходимости понять - а почему это мой объект вдруг пропал.., а если для создания нового объекта, то код, говорящий что нет такого объекта - тут как раз наоборот - всё хорошо и можно создавать.

И примите за правило: проверять нужно результат возврата функции и, если она возвращает реальную ошибку, то уже тогда анализировать код ошибки.

Вы же в своём примере голову себе морочите тем, что было успешное создание объекта-канваса, а вы думаете, что там где-то ошибка.

Хорошо, буду пробовать думать в описанном вами ключе при анализе ошибок. Спасибо.

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

 
Aleksey Vyazmikin:

Хорошо, буду пробовать думать в описанном вами ключе при анализе ошибок. Спасибо.

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

Не смогу - на то нужно время. Его, увы, нету, извините.

 
Aleksey Vyazmikin:

Хорошо, буду пробовать думать в описанном вами ключе при анализе ошибок. Спасибо.

  1. Сбросили код ошибки - ResetLastError()
  2. Вызвали функцию
  3. Обязательно смотрите что она вернула
  4. Если вернула именно ошибку (код ошибочного выполнения функции смотрите в справке на конкретную функцию)
    1. Уточняете что именно за ошибка при помощи GetLastError()
    2. Смотрите свой код если такого быть не должно в принципе, заложенном в программу, или
    3. Реагируете в логике своей программы на такую ошибку если это предусмотрено логикой программы (например ошибочные стопы)
    4. ...
    5. ...
    6. и т.д. ...
  5. Если вернула результат, который не является ошибкой, а является простым ответом на вопрос
    1. Делаете то, что заложено в логике программы и не смотрите на код последней ошибки, так как там лишь ответ на ваш запрос к функции, а не описание ошибки
    2. ну что-то ещё, что не могу сходу придумать...
  6. Enjoy


 
Artyom Trishkin:

Не смогу - на то нужно время. Его, увы, нету, извините.

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

 

Ошибка в CGraphic::CreateAxes:

      //--- draw mark and set y value
      int yi_width=m_canvas.TextWidth(yvalue);
      m_canvas.TextOut(m_left-yi_width-m_mark_size-m_gap,m_yc[i]-yh/2,yvalue,ColorToARGB(clrBlack),TA_LEFT);
      if(m_mark_size>0.0)
         m_canvas.LineHorizontal(x1,x2,m_yc[i],ColorToARGB(clrBlack));
...
      //--- draw mark and set y value
      m_canvas.TextOut(m_xc[i]-xw/2,y2+m_gap,xvalue,ColorToARGB(clrBlack));
      if(m_mark_size>0.0)
         m_canvas.LineVertical(m_xc[i],y1,y2,ColorToARGB(clrBlack));

Вместо выделенного должно быть m_y.Color() и m_x.Color(), соответственно.

Решается наследованием от CGraphic и переопределением CreateAxes (благо, виртуальный).

 

В том же CGraphic::CreateAxes используется m_grid.clr_frame, который невозможно задать самостоятельно:

void CGraphic::CreateAxes(void)
  {
...
//--- create frame
   m_canvas.Rectangle(m_left,m_up,m_width-m_right,m_height-m_down,m_grid.clr_frame);

Необходимо добавить метод для установки значения:

void              GridFrameColor(const uint clr)        { m_grid.clr_frame=clr;       }
 

Почему не рисуется горизонтальная линия на графике? Почему у неё координаты типа int, а не double?

//+------------------------------------------------------------------+
//|                                                   Test_CLine.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
#include <Graphics\Graphic.mqh>
#include <Graphics\Axis.mqh>

input int pix_X=800;//Ширина графика баланса
input int pix_Y=400;//Высота графика баланса
input bool Use_Koef=true;//Использовать коэфициент для установки ширины графика Parallel
input double Point_Kx=0.5;//Коэффициент ширины графика Parallel
input int Point_K=12;//Размер шрифта
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Save_Graf_P();   
  }
//+------------------------------------------------------------------+
void Save_Graf_P()
{

   int pixx_Y=pix_Y;
   int pixx_X=pix_X;

//--- отключим показ ценового графика
   ChartSetInteger(0,CHART_SHOW,false);

   long chart=0;
   string NameGraf="Test Line";

   CGraphic graphicL;

   if(ObjectFind(chart,NameGraf)<0)
   {
      graphicL.Create(chart,NameGraf,0,0,0,pixx_X,pixx_Y);//Создает графический ресурс, привязанный к объекту чарта
   }
   graphicL.Attach(chart,NameGraf);//Получить/создать  графический ресурс и привязать его к экземпляру класса CGraphic
   graphicL.BackgroundMain(NameGraf);//Получить/установить текст заголовка графика
   graphicL.BackgroundMainSize(16);//Получить/установить размер шрифта заголовка
   graphicL.HistoryNameSize(Point_K);//Устанавливает размер шрифта имени кривой
   graphicL.HistorySymbolSize(Point_K);//Получить/установить размер символов условных обозначений
   graphicL.LineAdd(-5,10,5,10,ColorToARGB(Blue,255),POINT_HORIZONTAL_DASH);//Создает и добавляет линию на график
   graphicL.CurvePlotAll();//Отрисовывает все ранее созданные кривые
   graphicL.Update();//Отображает на экране сделанные изменения
   ResetLastError();

   Sleep(3000);
   graphicL.Destroy();//Удаляет с чарта график и уничтожает графический ресурс.
   ChartSetInteger(0,CHART_SHOW,true);
}
Причина обращения: