Canvas - это круто! - страница 28

 
Evgeny Potapov:

Спасибо! Этот вариант вполне реалистично выглядит!

Спасибо за Ваш вопрос, потому что, отвечая на него, я понял одну очень важную вещь, о которой не знал.
Удивлюсь, если об этом вообще кто-то знал.

Если делать ресайз канваса или его положение с помощью ObjectSetInteger, то не требуется его перерисовка. 

  • Даже если мы уменьшили размер сформированного канваса, а потом вернули этот размер, то данные канваса сохраняются первоначальной прорисовки. 
  • Если увеличили размер сформированного канваса, то данные проподают, но появляются вновь когда возвращаем первоначальный размер.
  • При ресайзе или изменения положения канваса даже вовсе не обязательно делать Update() или ChartRedraw(), он обновиться с приходом нового тика или изменения окна.

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

#property indicator_chart_window

#define protected public  // увы, это необходимо, чтобы расширить наши возможности 
#include <Canvas\Canvas.mqh> 
#undef protected
CCanvas C;
int OnInit()
  {
   if(!C.CreateBitmapLabel(0,0,"_Canvas",100,100,600,400,COLOR_FORMAT_ARGB_NORMALIZE))
      Print("Error creating canvas: ",GetLastError());
   DrawCanvas(600,400);
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   C.Destroy();
  }
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])       
  {
    return prev_calculated;               
  }

void OnChartEvent(const int id,          
                  const long& lparam,   
                  const double& dparam, 
                  const string& sparam) 
  {
   if (id==CHARTEVENT_MOUSE_MOVE)  DrawCanvas((int)lparam,(int)dparam);
  }
//+------------------------------------------------------------------+
void DrawCanvas(int x, int y)
{
 static bool first=true;
 //Comment(string(x)+"   " +string(y));
 ObjectSetInteger(C.m_chart_id,C.m_objname,OBJPROP_XDISTANCE,x/5);
 ObjectSetInteger(C.m_chart_id,C.m_objname,OBJPROP_YDISTANCE,y/5);
 ObjectSetInteger(C.m_chart_id,C.m_objname,OBJPROP_XSIZE,x);
 ObjectSetInteger(C.m_chart_id,C.m_objname,OBJPROP_YSIZE,y);  
 if(first) // канвас формируется только один раз
 {
   C.Erase();
   C.FillCircle(100,100,70,ColorToARGB(clrViolet,200));
   C.FillCircle(300,200,100,ColorToARGB(clrLightBlue,100));
   C.Rectangle(140,50,250,150,ColorToARGB(clrAqua));
   C.Update(); 
   first=false;
 }
 ChartRedraw(); // можно обойтись и без этого, но тогда перерисовка будет только с каждым тиком или изменением чарта
}
Файлы:
 
а в видео можно сохранять?
 
Andrey Dik:
а в видео можно сохранять?
можно 
 
Nikolai Semko:
можно 

круто! надеюсь не созданием миллиона изображений с последующей сборкой в видео в каком нибудь видеоредакторе?))

если не затруднит, пожалуйста подробнее

 
Andrey Dik:

круто! надеюсь не созданием миллиона изображений с последующей сборкой в видео в каком нибудь видеоредакторе?))

если не затруднит, пожалуйста подробнее

нет, конечно, не так.
Затруднит.

 
Nikolai Semko:

нет, конечно, не так.
Затруднит.

код не нужен, намекните как это сделать

 
Nikolai Semko:
  • При ресайзе или изменения положения канваса даже вовсе не обязательно делать Update() или ChartRedraw(), он обновиться с приходом нового тика или изменения окна.

Ну так по этим событиям терминал сам и вызывает ChartRedraw() ;)

 
Andrey Dik:

код не нужен, намекните как это сделать

Существует масса вариантов в зависимости от того, какое видео нужно снимать. Просто что происходит в окне в реальном времени в окне с указателем мыши, индикаторами, объектами, ГУИ ? Или что-то другое?

 
А какая реальная полезность этой фишки? Помогает находить закономерности на графике цены, которые помогали бы торговать?
 
Andrey Khatimlianskii:

Ну так по этим событиям терминал сам и вызывает ChartRedraw() ;)

это понятно, просто не стал углубляться. 
Акцентировал на этом внимание, потому что для перерисовки объекта канваса при ChartRedraw() перерисовки не происходит, а происходит только при  Update(). А в случае применения  ObjectSetInteger для перерисовки объекта канваса достаточно принудительного ChartRedraw() или дождаться изменения чатра или прихода нового тика, при которых происходит ChartRedraw().

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