I have such question. Is it possible to recognize mouse double-click event from AFL code?
There is function GetCursorMouseButtons(). But unfortunately this function returns only mouse single-click event and doesn’t return mouse double-click event.
Yes we can.
We can use GetCursorMouseButtons() and static variable to do this job.
If you tell us what you like to do maybe we can help better.
Now, I am guessing one example you may it is easy to use ParamToggle() in your code
ActiveMouseButtons = ParamToggle("MouseButtons","No|Yes",0);
LeftButtonDown = GetCursorMouseButtons() == 1;
If (ActiveMouseButtons )
{
// do something
}
@igor_russia In general I would rather avoid relying on detection of a double mouse click in your codes, because in AmiBroker it is already reserved for marking the beginning and the end of a range on a chart (see here: selected date range ). I personally prefer solutions with for instance CTRL + mouse button click to avoid unintentional executions of some parts of the code (see here: Link ) , but if you really want, here is an example of a working code detecting a double mouse click:
if( GetCursorMouseButtons() )
{
Delay = 0.25; // In seconds
PCB = Nz( StaticVarGet( "PCB" ), 10 );
PCN = GetPerformanceCounter() / 1000;
ElapsedSeconds = PCN - PCB;
if( ElapsedSeconds < Delay ) Say( "Double click!" );
StaticVarSet( "PCB", PCN );
}
There are also much simpler solutions like ParamTrigger()
etc.
After giving it some additional thought, I came to the conclusion that you can use modified code to detect a double mouse click and (after a little practice) use safely it in your codes (although I would still prefer CTRL + mouse click solution), because you can define a double mouse click differently from the system's double click.
The default maximum delay between clicks to be recognized by the system as a double click is probably below 0.4 second. If you define "our custom AFL double click" in the code as a delay for instance between 0.4 and 1 second (or accordingly to your preferences) and additionally check if the mouse pointer position is exactly the same as before - you can safely recognize a custom double click. It won't interfere with the system's double click and AmiBroker's range marking! All you need to do is clicking twice a little slower.
if( GetCursorMouseButtons() )
{
MinDelay = 0.4; // In seconds
MaxDelay = 1; // In seconds
x = GetCursorXPosition( 0 ); y = GetCursorYPosition( 0 );
PCB = Nz( StaticVarGet( "PCB" ), 10 ); XB = Nz(StaticVarGet("XB")); YB = Nz(StaticVarGet("YB"));
PCN = GetPerformanceCounter() / 1000;
Esec = PCN - PCB;
StaticVarSet( "PCB", PCN ); StaticVarSet("XB", X); StaticVarSet("YB", Y);
if( Esec >= MinDelay AND Esec <= MaxDelay AND X == XB AND Y == YB)
{
Say( "Double click!" );
Title = "" + EncodeColor(colorGreen) + " !! Double Click! !! ";
}
}
Thanks for answers, but I want to clarify.
If we double click on Y-axis, then rescaling occurs. Moreover, we can rescale by drag-and-drop Y-axis. I want to detect these events (rescaling by double click and rescaling by drag-and-drop) from AFL code. Is there any way to do it?
Unfortunately, the ways, described above, don’t work in this situation :(.
In short, you should not do that as @Milosz wrote. AmIBroker handles double-click event internally for its own purposes. Relying on double click to detect scale change is bad idea because scale change can occur in other situations too (such as scrolling or changing symbol). Scale change can be detected using Status("axisminy") and Status("axismaxy") and static vars.
I love when users write in their n-th post, that the solution they initially had requested is needed for something that they didn't mention, which in many cases have nothing to do with the initial question or can be achieved in other, better way. It really didn't cross my mind, that you might need a double mouse click for detection of rescaling of a chart or something similar! The word "rescaling" didn't appear even once! I offered you a working solution detecting a double mouse click, which you can additionally customize so it doesn't interfere with AmiBroker's inner working. That was your initial request.
As Tomasz wrote, your problem can be easily solved using Status("axismaxy")
and Status("axisminy")
or (in my opinion - HighestVisibleValue(H)
and LowestVisibleValue(L)
) and Static variables.
For the reasons mentioned above, I'm not going to write another solution for you, but I will give you an example regarding changing Y scale similar to your problem. If you use GFX screen pixel mode and need to do conversion between bars/price and pixels, extra refresh when Y scale changes is required to adjust the chart. Probably 99% users force regular refreshes for that. Because I don't like using them (unless they are absolutelly necessary) I've come up with a solution providing just one additional refresh only when it is really needed - when Y scale changes. I've tried different variations of such code - for example using Status("axismaxy")
or Status("axisminy")
but in my case only below code works as I expected:
Chid = GetChartID();
HVY = HighestVisibleValue(H);
LVY = LowestVisibleValue(L);
HVYBefore = Nz( StaticVarGet( "HVYBefore" + Chid ) );
LVYBefore = Nz( StaticVarGet( "LVYBefore" + Chid ) );
if(HVY != HVYBefore OR LVY != LVYBefore)
{
RequestTimedRefresh( 0.1 );
StaticVarSet( "HVYBefore" + Chid, HVY );
StaticVarSet( "LVYBefore" + Chid, LVY );
}
You can use some ideas from this code. Having all this information, you should be able to work out the solution on your own. Of course you don't need using RequestTimedRefresh()
.
It’s very good idea, but I need another. I need to detect double-click on Y-axis event, when scaling of chart returns to its initial state (detecting of returning to initial state is important). It’s because my AFL code must do certain manipulations by this event. It’s difficult to detect it by Status("axisminy") and Status("axismaxy") and static vars.
I guess, that AmIBroker handles double-click event, but I thought that it’s possible to recognize it from AFL (something like GetCursorMouseButtons()). As I understood it's impossible.(
Is it very complicated to make function GetCursorMouseButtons() to return double-click event (by modification of Amibroker)?
And one more question: Is it possible to detect pushing buttons “Shorter bar” and “Taller bar” (on toolbar) from AFL?
Even if something is difficult - does it mean that it is impossible?
This one I don't understand. Do you still think, that it is impossible? If yes, it means that preparing above example codes for you was a waste of time...
If you use GetCursorX/YPosition(1)
--> mouse coordinates expressed in screen pixels NOT GetCursorX/YPosition(0)
--> X-coordinate in DateTime format, y - value in price, you can easily detect when the mouse pointer is in the Y-axis area. This simple code is a proof:
x = GetCursorXPosition( 1 );
y = GetCursorYPosition( 1 );
Title = " X: " + x + " Y: " + y;
RequestMouseMoveRefresh();
I have shown you that you can detect system's or custom double mouse click and you can tell, when the mouse pointer is in the Y-axis area (and where exactly), so you can experiment with whatever you want, but I still think, that you don't need detecting any double click to achieve what you want!
... but you haven't told us why do you actually need such strange solution (no good explanation, no code, no screenshot). That's why probably it would be better if you work out the solution on your own. I'm out of this thread.
I tried such way to recognize double-click on Y-axis with following rescaling:
Xp = GetCursorXPosition(1);
Yp = GetCursorYPosition(1);
pxChartRight = Status("pxChartRight");
if(Xp > pxChartRight + 20 AND GetCursorMouseButtons() == 9)
PopupWindow("double-click on Y-axis","",30);
But this way can’t distinguish rescaling by double click from rescaling by drag-and-drop. (
Hi,
RequestMouseMoveRefresh();
This is not a AFL funcion, how will it execute.
I tried using this command line and as expected "Error 30" pops up
This function was introduced in AB 6.21. I quote from: http://www.amibroker.com/devlog/wp-content/uploads/2017/03/readme6210.html
AFL:
RequestMouseMoveRefresh()
- request formula execution / refresh when mouse is moved INSIDE given chart pane (so it only triggers for ONE window under the cursor)
This provides less resource consuming way to handle chart graphics that depends on mouse hovering over chart pane than using RequestTimedRefresh as it only triggers one window currently under the cursor and only does not trigger refreshes when mouse does not move
NOTE2: mouse move refreshes come "as fast as possible". if your code is fast you can get butter smooth animation (even 50fps). Example:
Plot( C, "Price", colorDefault ); GfxCircle( GetCursorXPosition(1), GetCursorYPosition(1), 7 ); RequestMouseMoveRefresh();
https://forum.amibroker.com/search?q=RequestMouseMoveRefresh
Hi,
Update from ver.6.20 to ver6.28.0, find a lot of new AFL functions like the one above and for"GUI".
Where can I find a list (& explanation) of all new AFL functions added after ver.6.20, using the "F1" button
just turns up " this programme can not display this web page".
In the devlog: http://www.amibroker.com/devlog/
For more details, instructions and examples how to use new features, I really recommend studying READ ME files attached to each release. These files cover 100% of the implemented changes and almost always contain very helpful example codes. I print out each READ ME file after the new AB version is released and attach it to the previously printed materials. I also recommend reviewing older READ ME files. Most users will be surprised how much information and useful knowledge can be obtained from this source:
http://www.amibroker.com/devlog/wp-content/uploads/2018/02/readme6280.html
http://www.amibroker.com/devlog/wp-content/uploads/2017/10/readme6271.html
http://www.amibroker.com/devlog/wp-content/uploads/2017/09/readme6260.html
http://www.amibroker.com/devlog/wp-content/uploads/2017/07/readme6250.html
http://www.amibroker.com/devlog/wp-content/uploads/2017/04/readme6220.html
http://www.amibroker.com/devlog/wp-content/uploads/2017/03/readme6210.html
Besides each new version has also its own thread on the forum. For example:
etc.
As @Milosz wrote - with each BETA functions are documented in the READ ME.
Then once "official" release arrives (in this case 6.30) the Users Guide gets updated and F1 is able to find information on new functions.
Hi Milos z,
Thanks, I had read these but now I will follow your practice, print out all the read me files - make a hard copy --and maintain a file for easy reference and continuity.
Hi Milosz,
Now I also have a file (hard copy) of all the updates of the beta version releases.
Trying out the changes, one by one.
Tried out the AFL (gfxcircle and RequestMouseMoveRefresh();), made some changes - AFL below:--
GfxSetZOrder(-1 );
GfxSelectPen( colorYellow, 2 ) ;
GfxSelectSolidBrush( colorYellow ) ;
GfxCircle( GetCursorXPosition(1), GetCursorYPosition(1), 15 );
RequestMouseMoveRefresh();
and voila, a lovely yellow circle to high light the cursor position.
Learning the marvels of Amibroker !