MQL4/MT4 BUG report: clrNONE does not work on every light background, especially if G=255 (en)

 

(Reposted using English in this "en" English forum; please ignore improper duplicate English-in-Russian forum https://www.mql5.com/ru/forum/474328 )

I haven't found a MT4 bug report of this issue; perhaps I missed it. (Tested MT4 b1420; This works on MT5).

When I draw a Rectangle object (with Draw Object as background checked), then with color = "clrNONE", I expect an invisible rectangle.

This works fine when Background color = White, WhiteSmoke, Snow, Ivory, ... many other light colors.

HOWEVER, Background color = MintCream (245,255,250), or Honeydew (240,255,240), the rectangle is NOT invisible! 

Workaround: Change the G value of the background RGB color from 255 to just 254, and it works:



P.S.  My workaround will be to auto-change light background colors:

bool  isBackgroundLight() export { if(colorToRGBsum( (int) ChartGetInteger(0,CHART_COLOR_BACKGROUND)) >382 ) return(true); else return(false); }

//+------------------------------------------------------------------+
bool fixBackgroundColorFor_clrNONE_objects() export
{
   color _bgcolor = (color) ChartGetInteger(0,CHART_COLOR_BACKGROUND);
   if( (_bgcolor & 0x00FF00) == 0x00FF00)
   {
      if(_bgcolor != clrWhite)
      {
         Print("NOTE: Background color was adjusted from ",ColorToString(_bgcolor,true),"(RBG ",ColorToString(_bgcolor),") to ",
            ColorToString(_bgcolor & 0xFFFEFF)," as BUG workaround in MT4 (b1420) to properly handle clrNONE objects");
         _bgcolor = (color) (_bgcolor & 0xFFFEFF); // Reduces the G (of RGB) from 255 to 254 to fix MT4 (b1420) clrNONE bug.
         ChartSetInteger(0,CHART_COLOR_BACKGROUND,_bgcolor);
         return(true);
      } 
   }
   return(false);
}//end of fixBackgroundColorFor_clrNONE_objects()
MQL4/MT4 BUG report: clrNONE does not work on every light background, especially if G=255
MQL4/MT4 BUG report: clrNONE does not work on every light background, especially if G=255
  • 2024.10.08
  • pips4life
  • www.mql5.com
I haven't found a MT4 bug report of this issue; perhaps I missed it. (Tested MT4 b1420; This works on MT5...
 

Hi 

There is an object property called 

OBJPROP_TIMEFRAMES

With it you can "cheat" and hide/show objects

The "All periods" shows the object , the "no periods" hides it

    ObjectSetInteger(ChartID(),nam,OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
    ObjectSetInteger(ChartID(),nam,OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS);
Of course it depends on why you want the rectangle to be invisible
 
Lorentzos Roussos #:

Hi 

There is an object property called 

OBJPROP_TIMEFRAMES

With it you can "cheat" and hide/show objects

The "All periods" shows the object , the "no periods" hides it

Of course it depends on why you want the rectangle to be invisible

That property is not applicable in my scenario.  I have a Sessions indicator which not only draws rectangles to surround price bars within the session, it also draws a horizontal Open line the width of the same session.  In my case, I only want to see the Open line, and don't want to see the session box.  (Other sessions, I do).  The solution is to use clrNONE when I don't want to see the session box, even though it is actually created and drawn.   (Of course I could use another indicator that just draws Open lines, but clrNONE usually works just fine, so long as I don't encounter this MT4 bug; my workaround to slightly change the BG color will work just fine).

 
pips4life:

(Reposted using English in this "en" English forum; please ignore improper duplicate English-in-Russian forum https://www.mql5.com/ru/forum/474328 )

I haven't found a MT4 bug report of this issue; perhaps I missed it. (Tested MT4 b1420; This works on MT5).

When I draw a Rectangle object (with Draw Object as background checked), then with color = "clrNONE", I expect an invisible rectangle.

This works fine when Background color = White, WhiteSmoke, Snow, Ivory, ... many other light colors.

HOWEVER, Background color = MintCream (245,255,250), or Honeydew (240,255,240), the rectangle is NOT invisible! 

Workaround: Change the G value of the background RGB color from 255 to just 254, and it works:



P.S.  My workaround will be to auto-change light background colors:

Set the fill property to false.

ObjectSetInteger(0,"YourRectangle",OBJPROP_FILL,false);
 
Alain Verleyen #:

Set the fill property to false.

Perhaps I was not clear enough.  These posts referring to object properties are irrelevant, and missing the point.

I've reported a bug with MT4.   Regardless of why I'm using clrNONE for my object, I stated in my first post:

When I draw a Rectangle object (with Draw Object as background checked), then with color = "clrNONE", I expect an invisible rectangle.


This works fine when the background color is: White, WhiteSmoke, ... many light colors, but specifically does not work when the background color is MintCream or Honeydew.

Those 2 bad colors have G=255.  After reducing the G to 254, everything works!   Objects that are clrNONE are invisible on my chart, as they should be.

 
pips4life #:

Perhaps I was not clear enough.  These posts referring to object properties are irrelevant, and missing the point.

I've reported a bug with MT4.   Regardless of why I'm using clrNONE for my object, I stated in my first post:

When I draw a Rectangle object (with Draw Object as background checked), then with color = "clrNONE", I expect an invisible rectangle.


This works fine when the background color is: White, WhiteSmoke, ... many light colors, but specifically does not work when the background color is MintCream or Honeydew.

Those 2 bad colors have G=255.  After reducing the G to 254, everything works!   Objects that are clrNONE are invisible on my chart, as they should be.

YOU missed the point.

MT4 is dead software, no bugs are fixed since years. Only critical bugs and security fixes.

I gave you an easy fix.

 
Alain Verleyen #:

YOU missed the point.

MT4 is dead software, no bugs are fixed since years. Only critical bugs and security fixes.

I gave you an easy fix.

I thank you for your reply and attempt to provide me with a solution.

The OBJPROP_FILL property is non-functioning in MT4, only MT5.  In MT4, the closest equivalent of "FILL" is to control the OBJPROP_BACK property.  When "True" it behaves as if FILL=true.

But even when FILL="false", in MT5, it will draw the outline of a rectangle, so it's still not the same as achieving a completely invisible object as 'clrNONE' does.  (And in MT5, clrNONE works fine; no bug).


Yes I know that MT4 is not being fixed.  If it won't be fixed, then the point of my post is to document the bug for the benefit of other MT4 users who might search for it.  If they find my post, I also posted my code for the easy workaround, which I discovered on my own.  Perhaps no one will notice or care, but it's at least an informational post.  Plenty of us are still using MT4 and haven't made the transition.

 

You just want the border of the rectangle ?

You can utilize the canvas library 

Put a canvas in the background and handle drawing manually

 
pips4life #:

I thank you for your reply and attempt to provide me with a solution.

The OBJPROP_FILL property is non-functioning in MT4, only MT5.  In MT4, the closest equivalent of "FILL" is to control the OBJPROP_BACK property.  When "True" it behaves as if FILL=true.

But even when FILL="false", in MT5, it will draw the outline of a rectangle, so it's still not the same as achieving a completely invisible object as 'clrNONE' does.  (And in MT5, clrNONE works fine; no bug).


Yes I know that MT4 is not being fixed.  If it won't be fixed, then the point of my post is to document the bug for the benefit of other MT4 users who might search for it.  If they find my post, I also posted my code for the easy workaround, which I discovered on my own.  Perhaps no one will notice or care, but it's at least an informational post.  Plenty of us are still using MT4 and haven't made the transition.

I know how it works on MT4 or MT5, up to know you didn't talk about MT5. If the rectangle is intended to be invisible (clrNone), it doesn't matter if there is an outline or a fill, so my suggestion to use FILL=false.

We can't guess what you are doing, an other time please share all relevant information from the start to avoid wasting people time. Topic closed on my side.

 
pips4life #:

I thank you for your reply and attempt to provide me with a solution.

The OBJPROP_FILL property is non-functioning in MT4, only MT5.  In MT4, the closest equivalent of "FILL" is to control the OBJPROP_BACK property.  When "True" it behaves as if FILL=true.

But even when FILL="false", in MT5, it will draw the outline of a rectangle, so it's still not the same as achieving a completely invisible object as 'clrNONE' does.  (And in MT5, clrNONE works fine; no bug).


why don't you just do this instead... it is the equivalent of clrNONE

#define clrBACKGROUND ChartGetInteger(0,CHART_COLOR_BACKGROUND)

void OnStart()
{
   ObjectSetInteger(0,"Rectangle 35931",OBJPROP_COLOR, clrBACKGROUND);
}

or just redefine clrNONE

#define clrNONE ChartGetInteger(0,CHART_COLOR_BACKGROUND)

or as has already been suggested change the timeframe visibility.

 
Paul Anscombe #:
#define clrBACKGROUND ChartGetInteger(0,CHART_COLOR_BACKGROUND)

My MT4 code has: 
extern color colorChoice =   clr___; // The user can enter any choice, including clrNONE

So if I had not discovered the workaround I described, my next workaround would have been:

if(colorChoice == clrNONE) colorChoice = ChartGetInteger(0,CHART_COLOR_BACKGROUND);
(I would have to repeat this test for ~20 extern vars; no problem, just an extra nuisance)

Setting the object color to the background color does indeed make it invisible, so it works.  (I knew that, but thanks).


Side topic regarding your #define statement:

I am most familiar with the simplest use of "#define  identifier  constant".   I wasn't really aware that 'constant' could be an expression.  (Nor did I know identifier could be identifier(par1,...,par8) )


I learned something from your example, because using 'crlBACKGROUND' is indeed a dynamic value, executing the *expression* ChartGetInteger(...) when called.
I read the docs for "#define" so I understand a little more now.

Is there a simple way to describe the difference -- and advantages/disadvantages between:

#define clrBACKGROUND (color) ChartGetInteger(0,CHART_COLOR_BACKGROUND)

vs. defining a function:

color getBackgroundColor() { return( (color) ChartGetInteger(0,CHART_COLOR_BACKGROUND) ); }

With my "#define", as you can see, I added the typecasting, "(color)"

Having done so, these seem almost equivalent.  The only difference I've noticed is that when I'm using MetaEditor, if I use a function, typing 'ge' prompts me with auto-complete choices that include my getBackgroundColor function, whereas as #define, a disadvantage is that I have to spell out the complete "clrBACKGROUND" before it turns red, meaning it has an associated #define.  In other words, the MetaEditor doesn't help me auto-complete #define identifiers.

Any other differences worth noting?