Скачать MetaTrader 5

Обсуждение статьи "Управление терминалом MetaTrader с помощью DLL"

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
MetaQuotes Software Corp.
Модератор
182668
MetaQuotes Software Corp.  

Опубликована статья Управление терминалом MetaTrader с помощью DLL:

В данной статье рассматривается управление элементами интерфейса MetaTrader с использованием вспомогательной DLL-библиотеки на примере изменения настроек рассылки Push-сообщений. К статье приложен исходный код библиотеки и пример скрипта.

Имеется список MetaQuotesID, который составляет более четырех адресов для рассылки. Как известно, функция SendNotification использует только ID, указанные в окне настроек на вкладке "Уведомления". Таким образом, средствами MQL можно делать рассылку только на указанные ранее ID и не более четырех за раз. Попробуем исправить данную ситуацию.

Задачу можно решать двумя путями: написать полностью аналог функции для рассылки Push-сообщений или поменять настройки терминала и воспользоваться стандартной функцией. Первый путь довольно трудоемкий и, самое главное, не универсальный, поэтому был выбран другой вариант. Но и сами настройки терминала можно менять разными способами. Из тех что мне известны, это взаимодействие через интерфейс или подмена значений в памяти самого процесса. Хотя работа с памятью будет для пользователя выглядеть намного лучше, так как не будет мигающих окон, но при малейшей ошибке это может нарушить работу всего терминала. При работе через интерфейс мы в худшем случае не сможем найти нужное окно или кнопку.

Итак, в данной статье мы рассмотрим управление терминалом через интерфейс с помощью вспомогательной библиотеки DLL. В частности, будем рассматривать изменение настроек. "Общение" с терминалом будем организовывать через обращение к его окнам и компонентам, то есть так, как это делают обычные пользователи. Никаких вмешательств в процесс терминала не производим. Данный метод можно будет применять и для решения иных задач, к которым может привести самая неудержимая фантазия.

1.3. Работа с меню

Работа с меню, как и со всеми остальными компонентами, начинается после нахождения хэндла родителя, то есть определенного окна. После этого необходимо найти соответствующий пункт меню, подпункт и произвести его выбор.

Тут необходимо сделать важное замечание: количество пунктов меню в терминале изменяется в зависимости от того, развернуто окно графика или нет (см. рис. 2). Нумерация пунктов меню начинается с 0.

Рис. 2. Изменение количества пунктов меню

Рис. 2. Изменение количества пунктов меню

При изменении количества пунктов меню, соответственно, изменяется и порядковый номер пункта "Сервис". Поэтому при работе учитываем количество общее количество пунктов с помощью функции GetMenuItemCount(Hnd:HMenu), в которую передается хэндл меню.

Автор: Galina Bobro

Ihor Herasko
9306
Ihor Herasko  

Интересная задача выбрана. Правда, удивлен, что ее решение пустили "в эфир". Ведь таким макаром можно создать спам-сервис ))

 

По поводу самого решения возникли мысли и вопросы: 

1. Для вызова окна "Настройки" можно было бы использовать более универсальный способ: эмуляция нажатия  Ctrl + O. Вариант с меню не настолько уж и универсальный, т. к. зависит от расположения пунктов главного меню. Да, можно сказать, что и Ctrl+O никто не гарантирует. Тем не менее, изменение горячих клавиш в процессе развития приложения происходит достаточно редко и для этого должны быть веские причины.

2. Вместо нажатия "ОК" в окне "Настройки" - эмуляция клавиши Enter.

3. Что делать обычному пользователю, если в следующем билде разработчики добавят закладки в окно "Настройки", изменив при этом порядковый номер вкладки "Уведомления"? Программист то понятно - исправит на новый номер.

 

P. S. Что-то не так с семантикой предложения: "Даже несмотря на быструю работу программы, пользователь может его закрыть окно, что повлечет полное зависание терминала." В итоге мысль непонятна. Просьба исправить.

Galina Bobro
4863
Galina Bobro  
Игорь Герасько:

Интересная задача выбрана. Правда, удивлен, что ее решение пустили "в эфир". Ведь таким макаром можно создать спам-сервис ))

 

По поводу самого решения возникли мысли и вопросы: 

1. Для вызова окна "Настройки" можно было бы использовать более универсальный способ: эмуляция нажатия  Ctrl + O. Вариант с меню не настолько уж и универсальный, т. к. зависит от расположения пунктов главного меню. Да, можно сказать, что и Ctrl+O никто не гарантирует. Тем не менее, изменение горячих клавиш в процессе развития приложения происходит достаточно редко и для этого должны быть веские причины.

2. Вместо нажатия "ОК" в окне "Настройки" - эмуляция клавиши Enter.

3. Что делать обычному пользователю, если в следующем билде разработчики добавят закладки в окно "Настройки", изменив при этом порядковый номер вкладки "Уведомления"? Программист то понятно - исправит на новый номер.

 

P. S. Что-то не так с семантикой предложения: "Даже несмотря на быструю работу программы, пользователь может его закрыть окно, что повлечет полное зависание терминала." В итоге мысль непонятна. Просьба исправить.

Сама в шоке)

Спасибо за идею, попробую еще из клавишами, правда тут еще будет играть большую роль фокус. Если вдруг пользователь клацнет на окно что появляется  или на что-то еще (вдруг ему еще музыку захочется параллельно послушать) , то не известно что собственно нажмем.

За билд: очень сомнительно что будут частые существенные изменения в виде окна. Конечно это недостаток. 

В последнем не поняла что тут именно не ясно, может и потому что мне, как автору, все по умолчанию понятно. При работе скрипта появляется окно настроек которое потом ищем. Так как программно выполняются действия, то пользователь видит практически мигание окна, но вполне может успеть его закрыть (проверяла). Если это произойдет, а поиск в бесконечном цикле, то имеем полностью "висящий" терминал.

Ihor Herasko
9306
Ihor Herasko  
Galina Bobro:

В последнем не поняла что тут именно не ясно, может и потому что мне, как автору, все по умолчанию понятно. При работе скрипта появляется окно настроек которое потом ищем. Так как программно выполняются действия, то пользователь видит практически мигание окна, но вполне может успеть его закрыть (проверяла). Если это произойдет, а поиск в бесконечном цикле, то имеем полностью "висящий" терминал.

Имелось в виду часть предложения: "пользователь может его закрыть окно". Возможно, здесь лишнее "его". А может и что-то другое.
Sergey Dzyublik
4942
Sergey Dzyublik  
Игорь Герасько:

По поводу самого решения возникли мысли и вопросы: 

1. Для вызова окна "Настройки" можно было бы использовать более универсальный способ: эмуляция нажатия  Ctrl + O. Вариант с меню не настолько уж и универсальный, т. к. зависит от расположения пунктов главного меню. Да, можно сказать, что и Ctrl+O никто не гарантирует. Тем не менее, изменение горячих клавиш в процессе развития приложения происходит достаточно редко и для этого должны быть веские причины.

а что 
 PostMessageW(hParentWnd, WM_COMMAND, 33265, 0);

Больше не работает ? 

Andrey Osorgin
Модератор
62
Andrey Osorgin  
Игорь Герасько:
Имелось в виду часть предложения: "пользователь может его закрыть окно". Возможно, здесь лишнее "его". А может и что-то другое.
Исправлено, спасибо за замечание.
Ihor Herasko
9306
Ihor Herasko  
Sergey Dzyublik:
а что 
 PostMessageW(hParentWnd, WM_COMMAND, 33265, 0);

Больше не работает ? 

Не проверял. Но к подобного рода решениям отношусь с осторожностью, т. к. они недокументированы. Следовательно, могут в любой момент "поломаться" и нигде об этом никто ничего не напишет. В то же время программист будет долго ломать голову, прежде чем найдет возникшую ошибку. А вот Ctrl+O на данный момент является документированной возможностью терминала. Поэтому ее можно смело использовать. При изменениях в поведении терминала от разработчиков обязательно последуют изменения документации.
Dmitry Orlov
64
Dmitry Orlov  

вот это я называю mad skills !

способ поражает одновременно и простотой и изощрённостью ;)

Denis Sartakov
628
Denis Sartakov  
Dmitry Orlov:

вот это я называю mad skills !

способ поражает одновременно и простотой и изощрённостью ;)


интересно, кто-нибудь это все проверял ?

п‌ереписываю все на С++, здесь вот что-то странное:

HWND cSetPush::FindTab(int i_AccountNumber,int i_Language)
{
  TCHAR t_Buffer[255];
  HWND  h_Button;
  HWND  h_Parent;
  HMENU h_Menu;
  int i;
  UINT ui_MenuItemID;

  _itow(i_AccountNumber,gt_MT_WindowName,10);

  wcscpy(gt_MT_WindowClassName,TEXT("MetaTrader"));

  EnumWindows(&FindFunc, 0);

  if (gh_MT_Window != NULL)
  {
          SetForegroundWindow(gh_MT_Window);

          h_Menu = GetMenu(gh_MT_Window);

          if (GetMenuItemCount(h_Menu) == 7)
          h_Menu = GetSubMenu(h_Menu,4);
          else
          h_Menu = GetSubMenu(h_Menu,5);

          ui_MenuItemID = GetMenuItemID(h_Menu,6);

h_Menu - это handle для Tools

Tools содержит

0‌ - New Order

1‌ - History Center

2 - Global Variables

3 - MetaEditor

4 - Options

‌надо наверное так:

ui_MenuItemID = GetMenuItemID(h_Menu,4);

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий