Lib 'EasyAndFastGUI': Creating Canvas fails with error 4016 after update build 2265

 

Hi guys,

the following error occurs (which did not before releasing build 2265) when I create GUI elements with the EasyAndFastGUI library (https://www.mql5.com/de/code/19703):

CElement::CreateCanvas > Failed to create a canvas for drawing the (CButton) control: 4016

Let me first show you the methods of the library that fail. Later on I show code that utilizes these methods.

//+------------------------------------------------------------------+)
//| Creating a canvas for drawing a control                          |
//+------------------------------------------------------------------+
bool CElement::CreateCanvas(const string name,const int x,const int y,
                            const int x_size,const int y_size,ENUM_COLOR_FORMAT clr_format=COLOR_FORMAT_ARGB_NORMALIZE)
  {
   int xsize =(x_size<1)? 50 : x_size;
   int ysize =(y_size<1)? 20 : y_size;

   ::ResetLastError();

   if(!m_canvas.CreateBitmapLabel(m_chart_id,m_subwin,name,x,y,xsize,ysize,clr_format))
     {
      ::Print(__FUNCTION__," > Failed to create a canvas for drawing the ("+m_class_name+") control: ",::GetLastError());
      return(false);
     }

  //...
  }


Obviously, CreateBitmapLabel does not work properly:

bool CCanvas::CreateBitmapLabel(const long chart_id,const int subwin,const string name,
                                const int x,const int y,const int width,const int height,
                                ENUM_COLOR_FORMAT clrfmt)
  {
   if(Create(name,width,height,clrfmt))        // <--------------------------------- FAILS with '4016 – ERR_RESOURCE_NOT_FOUND (Ressource not found)'
     {
      if(ObjectCreate(chart_id,name,OBJ_BITMAP_LABEL,subwin,0,0))
        {
         if(ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x) &&
            ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y) &&
            ObjectSetString(chart_id,name,OBJPROP_BMPFILE,m_rcname))
           {
            //--- successfully created
            //--- complete initialization
            m_chart_id=chart_id;
            m_objname =name;
            m_objtype =OBJ_BITMAP_LABEL;
            //--- succeed
            return(true);
           }
        }
     }
//--- error
   return(false);
  }

Method Create(..) is returning false and when I debug and jump into it it will fail on ResourceCreate(...):

//+------------------------------------------------------------------+
//| Create dynamic resource                                          |
//+------------------------------------------------------------------+
bool CCanvas::Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt)
  {
      Destroy();
//--- prepare data array
        int resizedArray = ArrayResize(m_pixels,width*height);

   if(width>0 && height>0 && resizedArray > 0)
     {
      //--- generate resource name
      m_rcname="::"+name+(string)ChartID()+(string)(GetTickCount()+MathRand());
      //--- initialize data with zeros
      ArrayInitialize(m_pixels,0);
      //--- create dynamic resource
      if(ResourceCreate(m_rcname,m_pixels,width,height,0,0,0,clrfmt))   // <---------------------- FAILS with '4016 – ERR_RESOURCE_NOT_FOUND (Ressource not found)'
        {
         //--- successfully created
         //--- complete initialization
         m_width =width;
         m_height=height;
         m_format=clrfmt;
         //--- succeed
         return(true);
        }
     }
//--- error - destroy object
   Destroy();
   return(false);
  }

So now my code that uses methods of the EasyAndFastGUI lib:

bool CMarginCallCalculator::CreateComboBoxOrderType(const int x_gap, const int y_gap, const int innerSizeX, const int outerSizeX, const string text, int selectIndex)
{
        m_OrderType.MainPointer(m_window); // m_OrderType is a CComboBox

        m_OrderType.Alpha(InpTransparency);
        m_OrderType.XSize(outerSizeX);
        m_OrderType.ItemsTotal(2);
        m_OrderType.GetButtonPointer().BackColor(clrYellowGreen);
        m_OrderType.GetButtonPointer().AnchorRightWindowSide(true);
        m_OrderType.GetButtonPointer().XSize(innerSizeX);
        //m_OrderType.GetButtonPointer().XGap(-10);

        if (InpDarkTheme) {
                //m_OrderType.BackColor(clrLimeGreen);
                m_OrderType.LabelColor(clrLightGreen);
                m_OrderType.LabelColorHover(clrGreenYellow);
        }

        m_OrderType.SetValue(0, "Buy");
        m_OrderType.SetValue(1, "Sell");
                
        //--- List properties
        CListView *lv = m_OrderType.GetListViewPointer();
        lv.YSize(57);
        lv.LightsHover(true);
        lv.SelectItem(selectIndex);

        if (!m_OrderType.CreateComboBox(text, x_gap, y_gap))
                return false;

        CWndContainer::AddToElementsArray(0, m_OrderType);
        return true;
}

So that method worked just fine until the update and now fails with

         if (!m_OrderType.CreateComboBox(text, x_gap, y_gap))

Debugging that route it enters:

//+------------------------------------------------------------------+
//| Creates a group of the combobox objects                          |
//+------------------------------------------------------------------+
bool CComboBox::CreateComboBox(const string text,const int x_gap,const int y_gap)
  {
//--- Leave, if there is no pointer to the main control
   if(!CElement::CheckMainPointer())
      return(false);
//--- Initialization of the properties
   InitializeProperties(text,x_gap,y_gap);
//--- Create control
   if(!CreateCanvas())
      return(false);
   if(!CreateButton()) // <------ THIS FAILS
      return(false);
   if(!CreateList())
      return(false);
//--- Set the text to the button
   m_button.LabelText(m_listview.SelectedItemText());
   return(true);
  }

So creating the canvas itself seems not to be the problem, but drawing the button onto it. Entering CreateButton():

#resource "\\Images\\EasyAndFastGUI\\Controls\\up_thin_black.bmp"
#resource "\\Images\\EasyAndFastGUI\\Controls\\down_thin_black.bmp"

bool CComboBox::CreateButton(void)
  {

   m_button.MainPointer(this);

   int x_size=(m_button.XSize()<1)? 80 : m_button.XSize();

   int x =(m_button.XGap()<1)? x_size : m_button.XGap();
   int y =0;

   int icon_x_gap =(m_button.IconXGap()<1)? x_size-18 : m_button.IconXGap();
   int icon_y_gap =(m_button.IconYGap()<1)? 2 : m_button.IconYGap();

   int label_x_gap =(m_button.LabelXGap()<1)? 7 : m_button.LabelXGap();
   int label_y_gap =(m_button.LabelYGap()<1)? 4 : m_button.LabelYGap();

   m_button.NamePart("combobox_button");
   m_button.Index(0);
   m_button.TwoState(true);
   m_button.XSize(x_size);
   m_button.YSize(m_y_size);
   m_button.IconXGap(icon_x_gap);
   m_button.IconYGap(icon_y_gap);
   m_button.LabelXGap(label_x_gap);
   m_button.LabelYGap(label_y_gap);
   m_button.IsDropdown(CElementBase::IsDropdown());
   m_button.IconFile("Images\\EasyAndFastGUI\\Controls\\down_thin_black.bmp");
   m_button.IconFileLocked("Images\\EasyAndFastGUI\\Controls\\down_thin_black.bmp");
   m_button.IconFilePressed("Images\\EasyAndFastGUI\\Controls\\up_thin_black.bmp");
   m_button.IconFilePressedLocked("Images\\EasyAndFastGUI\\Controls\\up_thin_black.bmp");

   if(!m_button.CreateButton("",x,y))
      return(false);

   CElement::AddToArray(m_button);
   return(true);
  }

The resources are there (again, it all worked fine until the update), stepping down until we get to the failing line:

   if(!m_button.CreateButton("",x,y))

In the Button.mqh the method CreateButton(...) looks as follows:

bool CButton::CreateButton(const string text,const int x_gap,const int y_gap)
  {
   if(!CElement::CheckMainPointer())
      return(false);

   InitializeProperties(text,x_gap,y_gap);

   if(!CreateCanvas())   // <------------------------------ FAILS
      return(false);
//---
   return(true);
  }

InitializePropertoes works, but CreateCanvas() of this Button class does not:

bool CButton::CreateCanvas(void)
  {

   string name=CElementBase::ElementName("button");

   if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
      return(false);

   return(true);
  }

And there we are at the very first code snippet. Know that CElement::CreateCanvas(..) is called with proper name, m_x, m_y and the desired x/y size for the button.


Maybe someone can enlighten me why 

      if(ResourceCreate(m_rcname,m_pixels,width,height,0,0,0,clrfmt))

makes such trouble. Also, actually I do NOT understand the error. 4016 -> Resource not found? I thought this ResourceCreate() - Method is creating something not finding something! 


From the following screenshot you can see the values filled during the debugging run:



Would appreciate any hints and ideas!

I'll also contact @Anatoli Kazharski of EasyAndFastGui. Maybe he can help, too. 

Die Bibliothek EasyAndFastGUI zum Erstellen von grafischen Interfaces
Die Bibliothek EasyAndFastGUI zum Erstellen von grafischen Interfaces
  • www.mql5.com
Die Bibliothek EasyAndFastGUI ermöglicht das Erstellen von grafischen Interfaces für benutzerdefinierte MQL-Programme.
 

Just tried to change CButton::CreateCanvas with all available formats without avail:


bool CButton::CreateCanvas(void)
  {
   string name=CElementBase::ElementName("button");

   if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size, COLOR_FORMAT_XRGB_NOALPHA)) // <--- with COLOR_FORMAT_XRGB_NOALPHA and COLOR_FORMAT_ARGB_RAW it still FAILS
      return(false);

   return(true);
  }
 

I believe you directly if you say it's a huge library chaotic to edit but I tried and it's alright

Did you try with another version ? There's many. 

just there I have four differents archives and I even don't remember which one is the right one, nor which one I'm using - I just tried everything until it worked ;)

 

Hi Icham,

yes I had pulled the latest updates. Do you create a CComboBox somewhere in your GUI? Something like what I do as shown above:

        if (!m_OrderType.CreateComboBox(text, x_gap, y_gap))
                return false;

Maybe I'm preparing this ComboBox differently than you do.

I just commented out 

//m_OrderType.Alpha(InpTransparency);

but still the same. Looks like setting alpha doesn't make any difference.

Well, looks like I have to dissect this whole library.

Fun!

 
Marcel Fitzner:

Hi Icham,

yes I had pulled the latest updates. Do you create a CComboBox somewhere in your GUI? Something like what I do as shown above:

nope unfortunately I'm not using comboboxes. But if you look for the articles where the author is talking of comboboxes you may find the working version for combo

https://www.mql5.com/en/articles/2381#part_07

on the other hand, it may not work for others controls of the lib

you have to implement it, making your own fork

it's not easy but it does worth it - it's a really flexible lib
Graphical Interfaces V: The Combobox Control (Chapter 3)
Graphical Interfaces V: The Combobox Control (Chapter 3)
  • www.mql5.com
The first article  Graphical Interfaces I: Preparation of the Library Structure (Chapter 1) explains in detail what this library is for. You will find a list of articles with links at the end of each chapter. There, you can also download a complete version of the library at the current stage of development. The files must be placed in the same...
 

Just found out that rolling 'Canvas.mqh' back to the previous version makes the Combobox (and other failing components) work again.

Either some of those changes in the Canvas class are bugged or they are incompatible with resource loading used in the EasyAndFastGui.

If you have versioned the sources and use a diff tool you can see there are only a few relevant methods changed and mostly deal with transparency / COLOR_FORMAT_*

Checking in later.

Entdecken Sie neue Möglichkeiten des MetaTrader 5 mit MQL5 Gemeinschaft und Services
Entdecken Sie neue Möglichkeiten des MetaTrader 5 mit MQL5 Gemeinschaft und Services
  • www.mql5.com
Stellen Sie Fragen zur technischen Analyse, diskutieren Sie über Handelssysteme und verbessern Sie Ihre Kenntnisse im Programmieren von Handelsstrategien in der MQL5 Programmiersprache. Tauschen Sie sich mit anderen Händlern aus der ganzen Welt aus und helfen Sie den Anfängern — unsere Community entwickelt sich mit Ihrer Hilfe. FileFindFirst...
 
Marcel Fitzner:

Just found out that rolling 'Canvas.mqh' back to the previous version makes the Combobox (and other failing components) work again.

Either some of those changes in the Canvas class are bugged or they are incompatible with resource loading used in the EasyAndFastGui.

If you have versioned the sources and use a diff tool you can see there are only a few relevant methods changed and mostly deal with transparency / COLOR_FORMAT_*

Checking in later.

Yep, that way. Find a version that works for most of the controls you used in your interface, then patch what you need

 
Making things work with patches is ok for now, but I would assume here are other fellow coders & traders who'd like to know the FIX and not the patch ;)
 
Marcel Fitzner:
Making things work with patches is ok for now, but I would assume here are other fellow coders & traders who'd like to know the FIX and not the patch ;)

It has been released for free, and it's great ! 

I'm not sure it is supported as a paid product would be. In my opinion, the author will debug it only when he'll need it himself - but who knows ... try :)

or just do with what you have ;)

 
Marcel Fitzner:
Making things work with patches is ok for now, but I would assume here are other fellow coders & traders who'd like to know the FIX and not the patch ;)

Hello Marcel, I got the same problem... Don´t have de old Canvas.mqh to make a change. Could you please send to me?

 

Hi mate,

sure thing. I've uploaded the files (new, old, diff) so you can open/download them:

Canvas_Diff.htm

Canvas_before_build_2265.mqh

Canvas_build_2265.mqh

Cheers!

M.

Reason: