首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MQL5 -启动嵌入DLL中的表单

MQL5 -启动嵌入DLL中的表单
EN

Stack Overflow用户
提问于 2018-07-28 21:03:56
回答 1查看 656关注 0票数 0

在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

代码语言:javascript
复制
#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

代码语言:javascript
复制
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,只是表单本身不会显示。如果有人能对可能发生的事情和任何可能的解决办法有所了解,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2019-02-08 02:03:40

这就是问题所在:

代码语言:javascript
复制
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()的消息抽取替代方案。

代码语言:javascript
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51575254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档