TheXpert: Are you so sure your article is perfect?
I am very pleased that you read it.
I will be happy to answer all questions in the appropriate thread.
===
So that there are no unnecessary misconceptions, I have nothing against Anatoly! Kudos to him for the article! But it is necessary to answer the questions...
Excuse me, am I distracting you by any chance from writing another tutorial or recipe?
If not, let's continue discussing your article about control in the indicator subwindow. So, you offer a mass solution (or an idea) how to make a convenient menu in an indicator. Good, the purpose of the article is very worthy! But how can a "beginner" programmer use all this arsenal? Where to place custom functions? Demonstrate it by example. And at the same time explain what you need to fix in the code to use, for example, 5 buttons? Consider it a beginner's question.
No, you're not. I'm not writing anything yet. I have to rest at least one day a year. Just resting is not interesting, especially not for a long time. )
It's not a mass decision and I didn't write about it. Let's not attribute something that did not happen. It was already voiced at the beginning of the discussion that this is not a universal solution, but a special case. In my opinion, it is a good example for a beginner to practice. And not to get a ready-made solution for free and run, mouth open in a wide smile, to meet the sun. ) Do you understand? I would like such a simple and clear example at the very beginning of learning programming. Especially when this is the first programming language in your life and before that your whole life's activity was in a completely different field, in no way connected with it.
In order to make 5 buttons, in this case, we need to change the size of arrays and exclude unnecessary elements when declaring arrays for the names of objects-buttons, displayed text in buttons and button states.
There is an array of button states, so the same principle can be used to check which button is pressed and instead of just changing the colour of the button, perform some other (user required) action. This can be, for example, trading functions (and not only): deleting all pending orders, closing all positions, etc. The ideas are endless. And if there are no ideas, then you have chosen the wrong kind of activity. )
In order to implement this, you need to create another array, which will be initialised with identifiers of a custom enumeration (which also needs to be created), for example, with the name ENUM_SCRIPT. And the identifiers will then be called, for example: SCRIPT_01 =0, SCRIPT_02 =2, etc. Also in the loop, when checking whether the button on the panel is pressed, you will need to determine which identifier is bound to the pressed button and the current state of the button, and then pass the corresponding function to the programme for execution.
I will not show a sample code on purpose. Let it be a homework for beginners. )
But I don't understand how to connect my functions to the buttons. Show me an example.
Well, let's continue the game of "beginner" started by you. )
At what point are you stuck? Show an attempt at how understood at the current point. Create an enumeration with five identifiers and an array whose elements need to be assigned those identifiers.
//+------------------------------------------------------------------+//|| Executing scripts |//+------------------------------------------------------------------+void ScriptOn()
{
for(int i=0; i<NUMBER_BUTTONS_WIDTH; i++)
{
for(int j=0; j<NUMBER_BUTTONS_HEIGHT; j++)
{
//--- If this button is pressed, we will run the corresponding scriptif(buttons_state[j][i])
{
if(buttons_scripts[j][i]==SCRIPT_01)
{
F1();
return;
}
//---if(buttons_scripts[j][i]==SCRIPT_02)
{
F2();
return;
}
//---if(buttons_scripts[j][i]==SCRIPT_03)
{
F3();
return;
}
//---if(buttons_scripts[j][i]==SCRIPT_04)
{
F4();
return;
}
//---if(buttons_scripts[j][i]==SCRIPT_05)
{
F5();
return;
}
}
}
}
}
...and place this function in this part of the code:
//--- Tracking left mouse button clicks on a graphical objectif(id==CHARTEVENT_OBJECT_CLICK)
{
//--- If you click on the buttonif(InitializeButtonStates(sparam))
{
//--- Set the colours for the buttons
ChangeButtonColorOnClick();
//--- Run the scriptScriptOn();
}
//--- Update the chartChartRedraw();
return;
}
And then you can think about how to optimise the code, if you need to. :)
The programme that has tracking enabled at startup turns it off when unloading. And the programme, which remains on the chart and needs tracking, checks if it is enabled, and if it is disabled, it enables it.
It is desirable to give your variant on the examples of Expert Advisor and indicator code from my post on the previous page to exclude ambiguity of statements.
There is no need to constantly check if someone has disabled tracking of mouse events. To be more precise, if you want to protect yourself from any situation at all, you can check it, but I think it's too much.
Maybe we should suggest developers to generate CHARTEVENT_CHART_CHANGE when CHART_EVENT_MOUSE_MOVE changes? Then it would be possible to elegantly restore the necessary setting when the Expert Advisor is running.
So far, I have this variant:
#property copyright"Copyright 2013, komposter"#property link"http://www.komposter.me/"#property version"1.00"#property indicator_chart_windowinputbool EnableMouseDetect = false; // true - work with mouse tracking, false - without itbool PrevState = false;
//+------------------------------------------------------------------+//| Custom indicator initialisation function |//+------------------------------------------------------------------+intOnInit()
{
if ( EnableMouseDetect )
{
//--- Get the current state
PrevState = (bool)ChartGetInteger(0,CHART_EVENT_MOUSE_MOVE);
//--- Enable mouse event trackingif ( PrevState == false ) ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
}
return(0);
}
//+------------------------------------------------------------------+//| Deinitialisation function of the expert |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
if ( EnableMouseDetect )
{
//--- Disable mouse event trackingif ( PrevState == false )
{
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
ChartRedraw(); // Without this line, tracking is disabled only when a tick arrives. Is this the way it's designed?
}
}
}
//+------------------------------------------------------------------+//| OnTick|//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime& time[],
constdouble& open[],
constdouble& high[],
constdouble& low[],
constdouble& close[],
constlong& tick_volume[],
constlong& volume[],
constint& spread[])
{
return(rates_total);
}
//+------------------------------------------------------------------+//| ChartEvent function|//+------------------------------------------------------------------+voidOnChartEvent(constint id,
constlong &lparam,
constdouble &dparam,
conststring &sparam)
{
//--- Tracking mouse movement and left mouse button pressesif(id==CHARTEVENT_MOUSE_MOVE)
{
staticint count=1;
Print("CHARTEVENT_MOUSE_MOVE; EXPERT; ",count);
count++;
}
}
//+------------------------------------------------------------------+
I made one indicator, but with a parameter: run with EnableMouseDetect = true - controls tracking, false - just prints the number of events, if tracking is enabled.
------------------ Now I've thought about it some more, and I have to agree - this option won't work. If you run first one programme that tracks the mouse (it will enable tracking), then the second one (it will see what is already enabled), and then delete the first one, it will disable tracking, and the second one will be left with nothing. I.e. we need to come up with some kind of semaphore to signal that tracking is needed.
And in light of the research conducted here (about the load on the processor) in such crutches is not necessary.
So I propose to vote my proposal to the developers, and the topic can be closed.
ChartRedraw(); // Without this line, tracking is disabled only when a tick arrives. Is this the way it's designed?
MT5 has asynchronous updating of chart properties. I.e. the fact that we set a property does not mean that the terminal immediately picked it up. The ChartRedraw() function is used to have all properties re-read by the terminal. You can also use the ChartGet... ObjectGet, in this case the properties will also be re-read.
Are you so sure your article is perfect?
I am very pleased that you read it.
I will be happy to answer all questions in the appropriate thread.
===
So that there are no unnecessary misconceptions, I have nothing against Anatoly! Kudos to him for the article! But it is necessary to answer the questions...
Excuse me, am I distracting you by any chance from writing another tutorial or recipe?
If not, let's continue discussing your article about control in the indicator subwindow. So, you offer a mass solution (or an idea) how to make a convenient menu in an indicator. Good, the purpose of the article is very worthy! But how can a "beginner" programmer use all this arsenal? Where to place custom functions? Demonstrate it by example. And at the same time explain what you need to fix in the code to use, for example, 5 buttons? Consider it a beginner's question.
No, you're not. I'm not writing anything yet. I have to rest at least one day a year. Just resting is not interesting, especially not for a long time. )
It's not a mass decision and I didn't write about it. Let's not attribute something that did not happen. It was already voiced at the beginning of the discussion that this is not a universal solution, but a special case. In my opinion, it is a good example for a beginner to practice. And not to get a ready-made solution for free and run, mouth open in a wide smile, to meet the sun. ) Do you understand? I would like such a simple and clear example at the very beginning of learning programming. Especially when this is the first programming language in your life and before that your whole life's activity was in a completely different field, in no way connected with it.
In order to make 5 buttons, in this case, we need to change the size of arrays and exclude unnecessary elements when declaring arrays for the names of objects-buttons, displayed text in buttons and button states.
There is an array of button states, so the same principle can be used to check which button is pressed and instead of just changing the colour of the button, perform some other (user required) action. This can be, for example, trading functions (and not only): deleting all pending orders, closing all positions, etc. The ideas are endless. And if there are no ideas, then you have chosen the wrong kind of activity. )
In order to implement this, you need to create another array, which will be initialised with identifiers of a custom enumeration (which also needs to be created), for example, with the name ENUM_SCRIPT. And the identifiers will then be called, for example: SCRIPT_01 =0, SCRIPT_02 =2, etc. Also in the loop, when checking whether the button on the panel is pressed, you will need to determine which identifier is bound to the pressed button and the current state of the button, and then pass the corresponding function to the programme for execution.
I will not show a sample code on purpose. Let it be a homework for beginners. )
I made the changes like you said:
And this is what I got on the screen:
How do I fix it? (I'm a beginner)
I made the changes like you said:
And this is what I got on the screen:
How do I fix it? (I'm a beginner)
Like this:
Oh, great! It works.
But I don't understand how to connect my functions to the buttons. Show me an example.
Oh, great! It works.
But I don't understand how to connect my functions to the buttons. Show me an example.
Well, let's continue the game of "beginner" started by you. )
At what point are you stuck? Show an attempt at how understood at the current point. Create an enumeration with five identifiers and an array whose elements need to be assigned those identifiers.
So what do we do next?
So what do we do next?
This is the kind of array you need:
//--- Scripts ENUM_SCRIPT buttons_scripts[NUMBER_BUTTONS_HEIGHT][NUMBER_BUTTONS_WIDTH]= { {SCRIPT_01,SCRIPT_02,SCRIPT_03,SCRIPT_04,SCRIPT_05} };Then you need to write a function like this:
...and place this function in this part of the code:
And then you can think about how to optimise the code, if you need to. :)
That's how I have it done.
The programme that has tracking enabled at startup turns it off when unloading. And the programme, which remains on the chart and needs tracking, checks if it is enabled, and if it is disabled, it enables it.
It is desirable to give your variant on the examples of Expert Advisor and indicator code from my post on the previous page to exclude ambiguity of statements.
There is no need to constantly check if someone has disabled tracking of mouse events. To be more precise, if you want to protect yourself from any situation at all, you can check it, but I think it's too much.
Maybe we should suggest developers to generate CHARTEVENT_CHART_CHANGE when CHART_EVENT_MOUSE_MOVE changes? Then it would be possible to elegantly restore the necessary setting when the Expert Advisor is running.
So far, I have this variant:
I made one indicator, but with a parameter: run with EnableMouseDetect = true - controls tracking, false - just prints the number of events, if tracking is enabled.
------------------
Now I've thought about it some more, and I have to agree - this option won't work. If you run first one programme that tracks the mouse (it will enable tracking), then the second one (it will see what is already enabled), and then delete the first one, it will disable tracking, and the second one will be left with nothing. I.e. we need to come up with some kind of semaphore to signal that tracking is needed.
And in light of the research conducted here (about the load on the processor) in such crutches is not necessary.
So I propose to vote my proposal to the developers, and the topic can be closed.