MQL4 - Incomplete screenshot

 

I have a simple code to take a screenshot, but the problem is that the screenshot is incomplete. It doesn't matter the time I use in Sleep() after the redraw. Here's the code:

//+------------------------------------------------------------------+
//| Global constants                                                 |
//+------------------------------------------------------------------+
const string screenshotFile = "screenshot.png"; // Screenshot file

//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include <stdlib.mqh>
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Helper function to capture the screenshot and save the message   |
//+------------------------------------------------------------------+
void CaptureAndSendScreenshot()
  {
   // Get the ID of the current chart
   long chart_id = ChartID();

   // Capture the width and height of the chart window
   int chartWidth = 640;//ChartGetInteger(chart_id, CHART_WIDTH_IN_PIXELS);
   int chartHeight = 480;//ChartGetInteger(chart_id, CHART_HEIGHT_IN_PIXELS);
   Print("Chart width: ", chartWidth, ", height: ", chartHeight);

   // Redraw the window
   WindowRedraw();
   
   // Wait a bit to ensure the window is completely redrawn
   Sleep(5000);

   // Capture the screenshot of the open chart
   if (WindowScreenShot(screenshotFile, chartWidth, chartHeight))
     {
      Print("Screenshot saved: ", screenshotFile);
     }
   else
     {
      Print("Error saving the screenshot: ", ErrorDescription(GetLastError()));
     }
  }

Here's the original chart:

Original chart

Here's the screenshot:

The screenshot

Several graphical items are missing. I also tried ChartScreenShot(), but I had the same result. This is an indicator in a sub-window bigger than the main window, but it doesn't matter either. It doesn't matter the extension as well (.png, .gif...).

Any thoughts?

Thank you.

 

Never used WindowRedraw, but here's what the ChartRedraw documentation says:

https://docs.mql4.com/chart_operations/chartredraw

When the ChartRedraw() function is called from an indicator, the chart is redrawn only after the calculation of the OnCalculate() function is over, because indicators are executed in the common terminal thread.

That is, try to take a screenshot on the next tick (next OnCalculate call)
 
Just testing right now. I'll let you know the results. Thank you!
 

It seems to be working correctly! Thank you very much!

Here's the code:

//+------------------------------------------------------------------+
//| Global constants                                                 |
//+------------------------------------------------------------------+
const string screenshotFile = "screenshot.png"; // Screenshot file
bool WaitNextOnCalculate = false;

//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include <stdlib.mqh>

//+------------------------------------------------------------------+
//| Helper function to capture the screenshot and save the message   |
//+------------------------------------------------------------------+
void CaptureAndSendScreenshot()
  {
   // Get the ID of the current chart
   long chart_id = ChartID();

   // Capture the width and height of the chart window
   int chartWidth = 640;//ChartGetInteger(chart_id, CHART_WIDTH_IN_PIXELS);
   int chartHeight = 480;//ChartGetInteger(chart_id, CHART_HEIGHT_IN_PIXELS);
   Print("Chart width: ", chartWidth, ", height: ", chartHeight);

   // Redraw the window
   ChartRedraw();
   
   // Wait a bit to ensure the window is completely redrawn
   Sleep(5000);

   // Capture the screenshot of the open chart
   if (ChartScreenShot(chart_id, screenshotFile, chartWidth, chartHeight))
     {
      Print("Screenshot saved: ", screenshotFile);
     }
   else
     {
      Print("Error saving the screenshot: ", ErrorDescription(GetLastError()));
     }
  }

//+------------------------------------------------------------------+
//| 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[])
  {
   int limit;
   int counted_bars = IndicatorCounted();

   if(counted_bars < 0)
      return(-1);
   if(counted_bars > 0)
      counted_bars -= 10;

   limit = Bars - counted_bars;

   if(maxBars > 0)
     {
      limit = MathMin(maxBars, limit);
     }

   int i;
   RefreshRates();

   int lowLimit = 0;
   limit = WindowFirstVisibleBar();
   lowLimit = limit - WindowBarsPerChart();

   for(i = limit; i >= lowLimit; i--)
     {
      if(WaitNextOnCalculate)
        {
         WaitNextOnCalculate=false;
         CaptureAndSendScreenshot();
        }
      
      .
      .
      .
      
      if(IndicatorConditionForScreenShot)
        {
         WaitNextOnCalculate=true;
        }
     }
  }
 
Felipe Augusto Torres Maggico #:
for(i = limit; i >= lowLimit; i--)
     {
      if(WaitNextOnCalculate)
        {
         WaitNextOnCalculate=false;
         CaptureAndSendScreenshot();
        }

It's quite strange that this is inside a loop. You risk executing this code on the next iteration of the loop rather than on the next OnCalculate.

 

You're right. Just put it outside the loop to avoid the for iteration.

Thank you again!

Best regards!