错误、漏洞、问题 - 页 1622

 
fxsaber:
这似乎是关于视觉测试 中有时未关闭的窗口。不过,我无法重现它。现在开始工作了。

你一直在测试或优化吗? 如果是后者,这确实存在问题。

 
Karputov Vladimir:

这里的脚本会弹出 "文件 "菜单--"连接到交易账户 "项目--点击 "确定 "按钮--这样终端就会连接到最后一个自动生成的交易账户。

#ifndef  _IsX64
#define  HWND long
#define  HMENU long
#define  HBITMAP long
#define  ULONG_PTR long
#else
#define  HWND int
#define  HMENU int
#define  HBITMAP int
#define  ULONG_PTR int
#endif

_IsX64不能以这种方式使用。它 只在运行时相关。

 
Alexey Navoykov:

你一直在测试或优化吗? 如果是后者,这确实存在问题。

单次运行,我没有包括优化。
 
Koldun Zloy:

_IsX64不能以这种方式使用。它 只在运行时才重要

谢谢你的提示。纠正了它,并将其作为一个包含文件。

//+------------------------------------------------------------------+
//|                                          LoginToTradeAccount.mqh |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Library for clicks on the MetaTrader 5 menu \"File\" item \"Login to trading account\""
#property description "Библиотека для кликов по меню MetaTrader 5 \"Файл\" пункт \"Подключиться к торговому счёту\""

int number_menu=1;   //menu "File"; меню "Файл"
int item_menu=14;    //item "Login to trading account"; пункт "Подключиться к торговому счёту"

#define  GA_ROOT            0x00000002  // Retrieves the root window by walking the chain of parent windows
#define  WM_COMMAND         0x00000111
#define  BM_CLICK           0x000000F5

#import "user32.dll"
int  GetLastError();
//+------------------------------------------------------------------+
//| GetAncestor. Retrieves the handle to the ancestor of the         |
//| specified window. Возвращает хендл предка заданного окна         |
//+------------------------------------------------------------------+
//--- x64
long  GetAncestor(long hwnd,int gaFlags);
//--- x86
int  GetAncestor(int hwnd,int gaFlags);
//+------------------------------------------------------------------+
//| GetMenu. Retrieves a handle to the menu assigned to the          |
//| specified window. Возвращает хендл меню,                         |
//| назначенного указанному окну.                                    |
//+------------------------------------------------------------------+
//--- x64
long GetMenu(long hWnd);
//--- x86
int GetMenu(int hWnd);
//+------------------------------------------------------------------+
//| GetSubMenu. Retrieves a handle to the drop-down menu or submenu  |
//| activated by the specified menu item. Возвращает хендл           |
//| выпадающего меню или подменю указанного пункта меню.             |
//+------------------------------------------------------------------+
//--- x64
long GetSubMenu(long hMenu,int nPos);
//--- x86
int GetSubMenu(int hMenu,int nPos);
//+------------------------------------------------------------------+
//| GetMenuItemID. Retrieves the menu item identifier of a menu item |
//| located at the specified position in a menu. Возвращает          |
//| идентификатор пункта меню, расположенного в                      |
//| указанной позиции в меню.                                        |
//+------------------------------------------------------------------+
//--- x64
int   GetMenuItemID(long hMenu,int nPos);
//--- x86
int   GetMenuItemID(int hMenu,int nPos);
//+------------------------------------------------------------------+
//| PostMessageW. Places (posts) a message in the message queue      |
//| associated with the thread that created the specified window     |
//| and returns without waiting for the thread to process the        |
//| message. Размещает (публикует) сообщение в очереди сообщений,    |
//| связанной с потоком, который создал указанное окно и             |
//| возвращается, не дожидаясь потока, чтобы обработать сообщение.   |
//+------------------------------------------------------------------+
//--- x64
bool  PostMessageW(long hWnd,int Msg,int wParam,int lParam);
//--- x86
bool  PostMessageW(int hWnd,int Msg,int wParam,int lParam);
//+------------------------------------------------------------------+
//| GetLastActivePopup. Determines which pop-up window owned by the  |
//| specified window was most recently active. Определяет, какое     |
//| всплывающее окно, принадлежащие указанному окну, совсем недавно  |
//| было активным.                                                   |
//+------------------------------------------------------------------+
//--- x64
long  GetLastActivePopup(long hWnd);
//--- x86
int  GetLastActivePopup(int hWnd);
//+------------------------------------------------------------------+
//| GetDlgItem. Retrieves a handle to a control in the specified     |
//| dialog box. Возвращает хэндл элемента управления в               |
//| указанном диалоговом окне.                                       |
//+------------------------------------------------------------------+
//--- x64
long  GetDlgItem(long hDlg,int nIDDlgItem);
//--- x86
int  GetDlgItem(int hDlg,int nIDDlgItem);
#import
//+------------------------------------------------------------------+
//| Click on the item "Login to trading account"                     |
//| Клик на пункте "Подключиться к торговому счёту"                  |
//+------------------------------------------------------------------+
void LoginToTradeAccount()
  {
   long mainChartID=ChartID(); //returns the ID of the current chart; возвращает идентификатор текущего графика
   int hdlmainChartID=ChartWindowsHandle(mainChartID); //returns the Chart window handle (HWND); получает хэндл графика 

   if(_IsX64)
     {
      long hdlRoot=GetAncestor((long)hdlmainChartID,GA_ROOT);
      long hmenu=GetMenu(hdlRoot);
      long hsubmenu=GetSubMenu(hmenu,number_menu);
      int hpos=GetMenuItemID(hsubmenu,item_menu);
      PostMessageW(hdlRoot,WM_COMMAND,hpos,0);
      Sleep(2000);
      long hlastPopup=GetLastActivePopup(hdlRoot);
      long hOK=GetDlgItem(hlastPopup,0x00000001);
      PostMessageW(hOK,BM_CLICK,0,0);
     }
   else
     {
      int hdlRoot=GetAncestor(hdlmainChartID,GA_ROOT);
      int hmenu=GetMenu(hdlRoot);
      int hsubmenu=GetSubMenu(hmenu,number_menu);
      int hpos=GetMenuItemID(hsubmenu,item_menu);
      PostMessageW(hdlRoot,WM_COMMAND,hpos,0);
      Sleep(2000);
      int hlastPopup=GetLastActivePopup(hdlRoot);
      int hOK=GetDlgItem(hlastPopup,0x00000001);
      PostMessageW(hOK,BM_CLICK,0,0);
     }
  }
//+------------------------------------------------------------------+
//| The function gets the handle graphics                            |
//| Функция получает хэндл графика                                   |
//+------------------------------------------------------------------+
int ChartWindowsHandle(long chart_ID)
  {
//--- prepare the variable to get the property value
//--- подготовим переменную для получения значения свойства
   long result=-1;
//--- reset the error value
//--- сбросим значение ошибки
   ResetLastError();
//--- receive the property value
//--- получим значение свойства
   if(!ChartGetInteger(chart_ID,CHART_WINDOW_HANDLE,0,result))
     {
      //--- display the error message in Experts journal
      //--- выведем сообщение об ошибке в журнал "Эксперты"
      Print(__FUNCTION__+", Error Code = ",GetLastError());
     }
//--- return the value of the chart property
//--- вернем значение свойства графика
   return((int)result);
  }
//+------------------------------------------------------------------+
附加的文件:
 
Dmitri Custurov:
不幸的是,并非总是如此。如果长时间没有连接,终端会显示 "账户已禁用",然后你必须手动登录。这种情况发生在通常在夜间关闭服务器的基金中。

解决方案如下:EA定期检查与交易服务器的连接状态(TERMINAL_CONNECTED),如果返回值为 "0",则调用(使用WIn API)"文件 "菜单,"连接到交易账户 "项目。实现菜单点击功能的include文件可以在这里 找到。EA的例子。

//+------------------------------------------------------------------+
//|                                           TestAccountDisable.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <LoginToTradeAccount.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(12);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   static bool cleaner=false;
   if(!cleaner)
     {
      long rezult=TerminalInfoInteger(TERMINAL_CONNECTED);
      Comment("TERMINAL_CONNECTED: ",IntegerToString(rezult));
      if(rezult==0)
         LoginToTradeAccount();
     }
   else
      Comment("");
   cleaner=!cleaner;
  }
//+------------------------------------------------------------------+

顾问每12秒检查一次连接状态,每隔一段时间就擦除一次评论。

 
真的没有定义吗?
 

我如何将一个数组文件连接到我的EA?

首先,该脚本写了一个数组。

string filename="mas.dat";
int handle=FileOpen(filename,FILE_BIN|FILE_WRITE);
FileWriteArray(handle,hol,0,4608);
FileClose(handle);

我在EA中连接了该文件。

#include <mas.dat> 

编译时,出现错误。

'??????????????????????????t????...' - 标识符太长 mas.dat 1 1

'' - 未知符号 mas.dat 1 3015

 
Aliaksandr Yemialyanau:

我如何将一个数组文件连接到我的EA?

首先,该脚本写了一个数组。

我在EA中连接了该文件。

编译时,出现错误。

'??????????????????????????t????...' - 标识符太长 mas.dat 1 1

'' - 未知符号 mas.dat 1 3015

把整个数组文件读到内存中,然后对其进行处理,会快很多--会快很多倍。
 
Karputov Vladimir:

解决方案如下:EA定期检查与交易服务器的连接状态(TERMINAL_CONNECTED),如果返回值为 "0",则调用(使用WIn API)"文件 "菜单,"连接到交易账户 "项目。实现菜单点击功能的include文件可以在这里 找到。EA的例子。

顾问每12秒检查一次连接状态,每隔一段时间就会擦掉评论。

非常感谢您提供的解决方案。一切都在运作。
 
调试
#define  i ii

void OnTick()
{
  for (int i = 0; i < 5; i++)
    Print(i); // отладчик по Shift+F9 показывает не ii, а i, выдавая Unknown identifier
}