Импорт функции SendInput из user32.dll

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

Добрый день. Возникла необходимость использования функции SendInput из библиотеки user32.dll. Функция выглядит так (синтаксис С++):

UINT WINAPI SendInput(_In_ UINT  nInputs,  _In_ LPINPUT pInputs,  _In_ int  cbSize);

Второй параметр этой функции "LPINPUT pInputs" - массив структур. Здесь и здесь написано, как это выглядит на С++. Получается вроде как структура в структуре. Кто-нибудь может подсказать, как это реализовать в MQL4? Заранее благодарен.

Koldun Zloy
762
Koldun Zloy  

Это очень просто:

#define INPUT_MOUSE     0
#define INPUT_KEYBOARD  1
#define INPUT_HARDWARE  2

struct HARDWAREINPUT
{
   uint   uMsg;
   ushort wParamL;
   ushort wParamH;
   
   uint   placeholder[4];
};

struct MOUSEINPUT
{
   int    dx;
   int    dy;
   uint   mouseData;
   uint   dwFlags;
   uint   time;
   uint   dwExtraInfo;
};

struct KEYBDINPUT
{
   ushort wVk;
   ushort wScan;
   uint   dwFlags;
   uint   time;
   uint   dwExtraInfo;
   
   uint   placeholder[2];
};

struct INPUT
{
   uint type;
   
   KEYBDINPUT ki;
};

#import "user32.dll"
   uint SendInput( uint nInputs, INPUT& pInputs[], int cbSize );
#import

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   INPUT Inputs[10];
   
   for( int i = 0; i < 10; i++ ){
      Inputs[i].type = INPUT_KEYBOARD;
      Inputs[i].ki.wVk = 1;
      Inputs[i].ki.wScan = 2;
      Inputs[i].ki.dwFlags = 3;
      Inputs[i].ki.time = 4;
      Inputs[i].ki.dwExtraInfo = 0;
   }
   
   SendInput( 10, Inputs, sizeof( INPUT ) );
}
//+------------------------------------------------------------------+
DenisR
290
DenisR  
Ko1dun:

Это очень просто:

 

Спасибо за подсказку.
Maikl_Russia
7
Maikl_Russia  

Здравствуйте всем.

В 32-х битном терминале правый клик мышки работает.

Никак не могу добиться работы этого простецкого скриптика в 64-х битном терминале.

В интернетах много недовольства насчёт связки SendInput в 64-х битной виндовс. Кому-то помогает переопределение типа переменной dwExtraInfo на IntPTR, которого нет в MQL5, ещё какие-то махинации... Уши проблемы торчат, вроде как, из-за разной длины указателей в 32 и 64 битных системах. Посоветуйте, как решить проблему?

Windows 7 x64, максимальная, SP1. Терминал пятый, 64 бита, билд 1816.

#define INPUT_MOUSE     0
#define MOUSEEVENTF_RIGHTDOWN 0x0008
#define MOUSEEVENTF_RIGHTUP 0x0010

struct MOUSEINPUT {
   int    dx;
   int    dy;
   uint   mouseData;
   uint   dwFlags;
   uint   time;
   uint   dwExtraInfo;
};

struct INPUT {
   uint type;
   MOUSEINPUT mi; };

#import "user32.dll"
   uint SendInput(uint nInputs, INPUT& pInputs[], int cbSize);
#import

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {
   Sleep(3000);
   INPUT mInputs[2]; 

   mInputs[0].type = INPUT_MOUSE;
   mInputs[0].mi.dx = 0;
   mInputs[0].mi.dy = 0;
   mInputs[0].mi.mouseData = 0;
   mInputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
   mInputs[0].mi.time = 0;
   mInputs[0].mi.dwExtraInfo = 0;
   
   mInputs[1].type = INPUT_MOUSE;
   mInputs[1].mi.dx = 0;
   mInputs[1].mi.dy = 0;
   mInputs[1].mi.mouseData = 0;
   mInputs[1].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
   mInputs[1].mi.time = 0;
   mInputs[1].mi.dwExtraInfo = 0;

   SendInput(2, mInputs, sizeof(INPUT));
}
oups, тут ветка по 4-му терминалу. 
Koldun Zloy
762
Koldun Zloy  

Вот код для любых терминалов:

#define _WIN64  // Только для 64-разрядного терминала!

#include <WinDef.mqh>

#define SM_CXSCREEN 0
#define SM_CYSCREEN 1

#define INPUT_MOUSE     0
#define INPUT_KEYBOARD  1
#define INPUT_HARDWARE  2

#define MOUSEEVENTF_MOVE       0x0001
#define MOUSEEVENTF_RIGHTDOWN  0x0008
#define MOUSEEVENTF_RIGHTUP    0x0010
#define MOUSEEVENTF_ABSOLUTE   0x8000

struct MOUSEINPUT
{
   int    dx;
   int    dy;
   DWORD   mouseData;
   DWORD   dwFlags;
   DWORD   time;
#ifdef _WIN64
   uint pad;
#endif
   ULONG_PTR dwExtraInfo;
};

struct KEYBDINPUT
{
   WORD    wVk;
   WORD    wScan;
   DWORD   dwFlags;
   DWORD   time;
#ifdef _WIN64
   uint pad;
#endif
   ULONG_PTR dwExtraInfo;
};

struct HARDWAREINPUT
{
   DWORD   uMsg;
   WORD    wParamL;
   WORD    wParamH;
};

struct INPUT
{
   DWORD type;
   
#ifdef _WIN64
   uint pad;
#endif
   
   union __inputs
   {
      MOUSEINPUT     mi;
      KEYBDINPUT     ki;
      HARDWAREINPUT  hi;
   } inp;
};

#import "user32.dll"
   UINT SendInput( UINT nInputs, INPUT& pInputs[], int cbSize );
   int GetSystemMetrics( int nIndex );
#import

// Координаты мыши
int pX = 36;
int pY = 103;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   double width = GetSystemMetrics( SM_CXSCREEN );
   double height = GetSystemMetrics( SM_CYSCREEN );
	
   Sleep( 3000 );
   
   INPUT mInputs[2];
   
   int x = int(65535.0 / (width / pX));
   int y = int(65535.0 / (height / pY));
   
   mInputs[0].type = INPUT_MOUSE;
   mInputs[0].inp.mi.dx = x;
   mInputs[0].inp.mi.dy = y;
   mInputs[0].inp.mi.mouseData = 0;
   mInputs[0].inp.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN|MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
   mInputs[0].inp.mi.time = 0;
   mInputs[0].inp.mi.dwExtraInfo = 0;
   
   mInputs[1].type = INPUT_MOUSE;
   mInputs[1].inp.mi.dx = x;
   mInputs[1].inp.mi.dy = y;
   mInputs[1].inp.mi.mouseData = 0;
   mInputs[1].inp.mi.dwFlags = MOUSEEVENTF_RIGHTUP|MOUSEEVENTF_ABSOLUTE;
   mInputs[1].inp.mi.time = 0;
   mInputs[1].inp.mi.dwExtraInfo = 0;
   
   SendInput( 2, mInputs, sizeof( INPUT ) );
}
//+------------------------------------------------------------------+

oups, тут ветка по 4-му терминалу. 

Не заморачивайтесь.

Файлы:
WinDef.mqh 2 kb
Maikl_Russia
7
Maikl_Russia  

@Koldun Zloy Благодарю за оперативную помощь. :)

Но ничего не могу поделать: так и не работает в 64-х битке скриптик. Ваш пример скопировал от корки до корки, компиляция происходит без ошибок, но хоть тресни: в 32 битном терминале как часики (естественно без "#define _WIN64"), а в 64 - ничего не происходит.

Если у вас этот скриптик отрабатывает без проблем - попробую тогда найти чистенькую windows x64, может моя семёрка уже стухла. Вот ведь засада на ровном месте.... :-\

Стоит ли грешить на терминал: он не чистый, а брокерский?

Koldun Zloy
762
Koldun Zloy  
Maikl_Russia:

@Koldun Zloy Благодарю за оперативную помощь. :)

Но ничего не могу поделать: так и не работает в 64-х битке скриптик. Ваш пример скопировал от корки до корки, компиляция происходит без ошибок, но хоть тресни: в 32 битном терминале как часики (естественно без "#define _WIN64"), а в 64 - ничего не происходит.

Если у вас этот скриптик отрабатывает без проблем - попробую тогда найти чистенькую windows x64, может моя семёрка уже стухла. Вот ведь засада на ровном месте.... :-\

Стоит ли грешить на терминал: он не чистый, а брокерский?

Извиняюсь, писал без проверки. Сейчас всё работает.

Maikl_Russia
7
Maikl_Russia  
Просто чудеса. :) С пол-пинка заработало. Спасибо. Какие-то несчастные пара доп. полей в обеих структурах.
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий