@SteveH with regards to GuiSendKeyEvents and potential overlap:
There is no overlap problem if you have correct code, you should be checking not only the ID, but also notification code/type.
In other words, to detect key down events, you have to include this part in your formula:
id = GuiGetEvent( n, 0 ); // this gets the ID of control, or ASCII code of key
code = GuiGetEvent( n, 1 ); // this gets notification CODE
if( code == notifyKeyDown )
{
// this is KEY DOWN event
// id holds ASCII code of the key
}
else
{
// this is OTHER event (you can extend detection to click/setfocus/etc)
// id holds control ID
}
Example coding that checks properly various events:
idMyFirstButton = 1;
idMySecondButton = 2;
function CreateGUI()
{
GuiSendKeyEvents("ED"); // send notifications for keypresses of "E" and "D"
GuiButton( "Enable", idMyFirstButton, 10, 60, 100, 30, notifyClicked );
GuiButton( "Disable", idMySecondButton, 110, 60, 100, 30, notifyClicked );
}
function HandleEvents()
{
for ( n = 0; id = GuiGetEvent( n, 0 ); n++ ) // get the id of the event
{
code = GuiGetEvent( n, 1 );
if( code == notifyKeyDown )
{
switch( id )
{
case 'D':
Say("pressed D key");
break;
case 'E':
Say("pressed E key");
break;
}
}
else
switch ( id )
{
case idMyFirstButton:
// do something
Say( "Pressed first button" );
break;
case idMySecondButton:
// do something else
Say( "Pressed second button" );
break;
default:
break;
}
}
}
CreateGUI();
HandleEvents();
Alternatively, you can use "high" values for control IDs that don't overlap with the ASCII table (>=256)
"Alternatively, you can use "high" values for control IDs that don't overlap with the ASCII table (>=256)"
Yes, I started out the same as your code separation example based on the notify but the letters and buttons turned out to have too much code in common since the letters are shortcuts for the button presses.
Both ways might deserve mention in the GetGuiEvent() documentation.
I have some code in a switch statement in the typical for() loop getting Gui events:
case idQty:
if (notify == notifyEditChange)
{
str = GuiGetText(idQty);
if (_market_position == positionFlat)
_pos = StrToNum(str);
}
break;
So if I'm in the GuiEdit control (i.e., the edit control that idQty is tied to has the focus), trying to type in the number 1 or 2, they got "eaten" by the notifyKeyDown event and won't be accepted into the edit box.
Sorry, but that how Windows works. Only one window receives events. If keys were not eaten by PARENT, they would not work if focus was on buttons. So in order to handle key strokes when you have GUI controls and you may have focus on GUI control, the PARENT has to eat them. And edit fields are children as buttons.
That is exactly what I described earlier:
If I change that so parent does not eat keystrokes, they notifyKeyDown will not work when focus is in any control (which in practice means after any click on any control)
One solution is NOT to register digit keys via GuiSendKeyEvents. Only characters that are registered are eaten. So if you don't register digits for key down notifications via GuiSendKeyEvents, they will be able to arrive to the edit field.
From a logical level, I would have thought that if any of the script's edit controls has the focus, the GuiSendKeyEvents() processing logic would not be executed. Essentially, it's turned off. However, if no edit control has the focus then GuiSendKeyEvents() logic can be active (turned on).
Another thing I'm noticing is that the keystrokes detected by GuiSendKeyEvents() are raw. For example, there's no such thing as GuiSendKeyEvents("@"), even though its in the ASCII table and has its own integer equivalent. That's a shift-2 on a US keyboard. It's up the user to also call the GetAsyncKeyState() function to do the proper detection.
@Tomasz, Thank you for the release. I use 4k monitors, the HighDPI awareness fixes MDI issues you pointed out in 23 & 24. I wrote a bunch of chart using gfx. When I wrote those I was using 1920x1080 resolution monitors. They look perfect on 1920x1080 monitors, however on 4k monitors I think because of pixel size they don't look as good. Does gfx need to become HighDPI aware or is there a programming trick that can be use to make gfx charts resolution independent?
I assume that you mean Gfx* functions when you talk about "chart using gfx". If thats the case, all Gfx* works with physical pixels, that obviously are much smaller on HighDPI screens.
Therefore you need to scale all pixel co-ordinates if you want Gfx* - drawn elements to be larger. Program won't do that for you because, as I wrote, the unit for Gfx function is one physical pixel.
Thanks, I was referring to Gfx functions. Is there a function (a way) to get the resolution of the screen in afl. I am thinking using conditional statement for scaling co-ordinates based on screen resolution.
There is only GetStatus("pxchartwidth"), GetStatus("pxchartheight") that reports CHART pane pixel dimensions. You may use that to switch after certain threshold is exceeded.
GetObject allows you to connect to already running instance of OLE automation server that has given file already opened:
// would connect to running Excel instance that has given file open
obj = GetObject("C:\\SomeDir\\TestFile.XLS");
Disclaimer: this function uses pretty old Microsoft APIs that are known to have their own bag of problems and are known to NOT work for some automation objects on Windows 10. I don't accept ANY "bug reports" to the functionality of GetObject, because it is SOLELY MICROSOFT code and I can't fix Microsoft errors.
Thanks for the suggestion to use GetStatus. As the size of chart pane changes so does info reported by GetStatus. I couldn't find a way to decipher the resolution of the screen, unless Amibroker window is fully maximized.
Perhaps if it make sense, you can add a function that return DPI setting in the future. meanwhile I guest I live with imperfect charts.
BTW, I believe Esignal will stop providing data access to Amibroker via the eSignal Data Access from December. Anyone else receive the email below? If so, are there other long term historical intraday data providers besides IQFeed?
Email received:
Our records indicate that you are currently subscribed to the eSignal Data Access / eSignal Data Manager product (“Product”).
Please be advised that as of your next monthly billing date of 12/4/2020, the Product will no longer be available under your eSignal account. As of such date, you will no longer receive or be invoiced for the Product.
We apologize for any inconvenience this may cause. We appreciate your business and hope that you will consider transitioning to our [eSignal Suite of software products]
If you have any questions or need further assistance please feel free to [contact our Support Team]
I believe that if you change your subscription to regular eSignal, it will continue to work with AmiBroker because, eSignal is using Data Manager and very same API that AmiBroker uses in their own charting application and from technical stand point there is no difference what application consumes data fed by Data Manager.
There is no single technical reason, just purely eSignal "business" decision to "persuade" customers to use their software.
to remove all doubts, I decided to extend the subscription with eSignal by one month. It is likely as you have rightly pointed out to me.
The right hand of the support, does not know what the left hand trade does.
Thanks a lot