Ошибки, баги, вопросы - страница 1622

 
fxsaber:
Похоже, дело в незакрытых иногда окнах от визуального тестирования. Воспроизвести, правда, не получается. Сейчас все заработало.

У вас было именно тестирование или же оптимизация?  Если второе, то с этим действительно есть проблемки.

 
Karputov Vladimir:

Вот скрипт, который вызывает меню "Файл" - пункт "Подключиться к торговому счёту" - кликает на кнопку "OK" - таким образом терминал подключится к последнему торговому счёту, который проходил автризацию:

 

#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:
К сожалению не всегда. При долгом отсутствии подключения терминал выдает "Account disable"  и после этого необходимо логиниться вручную. Такое происходит например на фонде где на ночь сервера обычно отключаются. 

Вот такое решение: советник периодически проверяет состояние коннекта к торговому серверу (TERMINAL_CONNECTED) и если возвращаемое значение равно "0", то вызывается (при помощи WIn API) меню "Файл", пункт "Подключиться к торговому счёту". Включаемый файл, в котором реализуется функция клика в меню находится здесь. Пример советника:

//+------------------------------------------------------------------+
//|                                           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 секунд проверяет состояние соединения и через раз стирает комментарии. 

 
Неужели дефайна нету?
 

Как к советнику подключить файл с массивом?

Сначала скрипт записывает массив:

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

 В советнике подключаю файл:

#include <mas.dat> 

При компиляции, ошибки:

'??????????????????????????t????…' - identifier is too long mas.dat 1 1

'' - unknown symbol mas.dat 1 3015

 
Aliaksandr Yemialyanau:

Как к советнику подключить файл с массивом?

Сначала скрипт записывает массив:

 В советнике подключаю файл:

При компиляции, ошибки:

'??????????????????????????t????…' - identifier is too long mas.dat 1 1

'' - unknown symbol mas.dat 1 3015

Гораздо быстрей читать весь файл массива в память, а потом уже с ним работать - ускорение в разы быстрей будет.
 
Karputov Vladimir:

Вот такое решение: советник периодически проверяет состояние коннекта к торговому серверу (TERMINAL_CONNECTED) и если возвращаемое значение равно "0", то вызывается (при помощи WIn API) меню "Файл", пункт "Подключиться к торговому счёту". Включаемый файл, в котором реализуется функция клика в меню находится здесь. Пример советника:

 

Советник каждый 12 секунд проверяет состояние соединения и через раз стирает комментарии. 

Спасибо огромное за предоставленное решение. Все работает.
 
Отладка
#define i ii

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