Disliked...I tried to use API Monitor to capture MT5 calls when a script is launched, but I didn't find anything that would look like it. Any suggestions?Ignored
Disliked...How did you find out that it's this message ("MetaTrader4_Internal_Message") that has to be registered and posted in MT4?Ignored
Disliked...And that you need to call PostMessageW with wParam set to 16 to execute a script?Ignored
For inspecting an application's memory I use WinHex. I enter the assumed pointer seen in WinSpector into WinHex memory browser and can see what is stored. Essentially I'm navigating the heap of MT4 at runtime.
Now why PostMessage() and not SendMessage()? Because SendMessage works synchronously and PostMessage not. With SendMessage() the application (MT4) would wait until the call to SendMessage returns. That would essentially block your program - MT4 hung itself up in an infinite wait loop. On the other hand, PostMessage just delivers the message to the queue and returns immediately. That's what we need here. Standard Win32 message functionality.
But there is a catch. The message contains a pointer to a string buffer. That buffer is on the heap. PostMessage immediately returns and the message queue just does it's regular work, processing one message after the other until your message gets processed. That will be a few milliseconds later than your PostMessage call returned. Now it is your responsibility that the memory of the string buffer on the heap (holding the path to the EX4 file) is still valid. In a regular Win32 application that wouldn't be an issue. But in MT4, if you call PostMessage from a script or an expert things change because scripts and experts are executed in their own thread. In MT4 every tick of an expert is executed in a different thread. A core principle of win32 multi-threading is to not block other parts of the application. But it also means, as soon as your script terminates or the expert's tick funtion returns, allocated resources may be immediately released. Which means the memory for your string buffer on the heap will be released, and at the moment the message queue wants to process your message it finds a string pointer but the memory is gone - and boom - you just crashed MT4. So, your task as a developer is to make sure that the memory holding your buffer is still valid at the time the message is processed. I do this by moving the call LoadMqlProgram() to my DLL and pinning the DLL in memory, so it doesn't get unloaded after the call (DLL pinning). Then I allocate the buffer for the passed string in the DLL, not in the MQL program. Meaning, the DLL is unloaded (and memory released) only on application shutdown by the OS.
Attached File(s)
ps: Please don't download DLLs from this thread. They are many years old, outdated and contain serious bugs.
The latest version is here (you need a free Github account): rsfMT4Expander.dll
It takes blood, sweat and enough tears to wash away the blood.
3