在MetaTrader 4/MQL4 4中,我能够显示一个非模态表单(即带有字符串网格的简单窗口),并使用DLL接口将数据从指示符传递到该表单。这样做已经有一段时间了,而且效果很好。
试图在MetaTrader 5/MQL5 5中完成相同的任务,但是遇到了一些麻烦。表单显示,但立即进入无响应状态(应用程序没有响应)。
我在不同的64位平台(eSignal 12)上使用相同的64位DLL运行了一个测试,并且表单加载得很好。
我正在使用Delphi更新2构建XE5。32位用于MT4,64位用于MT5.MT5构建是1881年。我创建了一个非常简单的MQL5脚本和Delphi来测试它:
MQL5
#import "TestForm.dll"
int showAForm(int hwnd);
int closeAForm();
#import
void OnStart()
{
//---
int hwnd=ChartGetInteger(0,CHART_WINDOW_HANDLE,0);
showAForm(hwnd);
Sleep(5000);
closeAForm();
//---
}Delphi
library TestForm;
uses
System.SysUtils,
System.Classes,
Windows,
Vcl.Forms, Vcl.Dialogs;
{$R *.res}
var
myForm: TForm;
function showAForm(handle: HWND): integer; stdCall;
var
myHandle: HWND;
begin
myHandle := FindWindow('MetaQuotes::MetaTrader::5.00', nil);
showMessage(IntToStr(myHandle));
try
myForm := TForm.Create(nil);
// myForm:=TForm.CreateParented(myHandle);
// Windows.SetParent(myForm.Handle, myHandle);
myForm.Show;
result := 1;
except
result := -2;
end;
end;
function closeAForm(): integer; stdCall;
begin
myForm.Close();
FreeAndNil(myForm);
result := 1;
end;
exports
showAForm,
closeAForm;
begin
IsMultiThread := true;
end.我尝试过几种不同的创建表单的方法(零,父母),但没有区别。如果我使用ShowModal而不是显示,表单将正确显示,但当然,MT5图形用户界面会被阻塞。
不生成异常,两个函数都返回correctly...it,只是表单本身不会显示。如果有人能对可能发生的事情和任何可能的解决办法有所了解,我将不胜感激。
发布于 2019-02-08 02:03:40
这就是问题所在:
showAForm(hwnd);
Sleep(5000);
closeAForm();您的Sleep(5000);阻塞GUI线程整整5秒。
因此,创建表单showAForm(),阻塞GUI线程5秒,然后关闭表单closeAForm()。
Delphi需要一个工作的消息泵才能正常工作,但是Sleep(5000);阻塞线程,不让消息泵运行。
在Delphi应用程序中,例如。"mydelphiapp.exe",Application.ProcessMessage函数处理消息,在Application.Run过程中,有如下代码:
repeat try HandleMessage; except HandleException(Self); end; until Terminated;
要解决这个问题,您需要在Delphi中构建,这是一种Sleep()的消息抽取替代方案。
procedure MessagePumpingSleep(ADelay:Longword); stdcall;
var
T1, T2, dT : Longword;
begin
T1 := GetTickCount;
repeat
Application.ProcessMessages;
Sleep(1); // this will stop this procedure from consuming 100% CPU.
T2 := GetTickCount;
dT := T2 - T1;
until dT >= ADelay;
end;
exports MessagePumpingSleep;然后调用MessagePumpingSleep(5000)而不是Sleep(5000);
显然,要能够调用MessagePumpingSleep(5000),需要在MQL5中编写适当的导入代码,以便从Delphi导入MessagePumpingSleep() -function。
https://stackoverflow.com/questions/51575254
复制相似问题