Внимание! Горячие новости и планы проекта Usb2Kbd
    18.03.2024 В версии девайса 6.7 Usb2kbd_LAN/COM реализован метод выполнения заранее заготовленных команд с MicroSD карты через .txt
    04.02.2024 Реализован метод управления через UDP девайсом Usb2kbd_COM (без LAN модуля) при помощи udp2serial
    16.11.2023 Начал применение более современных LAN модулей для Usb2kbd_LAN на основе чипа w5500, что обеспечит лучшую стабильность связи.
    04.06.2023 Начаты разработки для применимости девайса для разблокировки PIN-кода для владельцев MacBook.
    04.06.2023 Вышло глобальное обновление прошивки и ПО Usb2kbd_LAN 6.5. Внедрён альтернативный режим работы мыши - в абсолютной системе координат. Т.е. в этом режиме можно отправлять абсолютные координаты перемещения курсора мыши, например, сразу в координаты экрана X=100 Y=100.
    04.06.2023 Зафиксирован и подтвержден мной первый в истории девайса Usb2kbd_DLL факт блокировки игровой защитой одной из MMORPG самой управляющей DLL. Напрямую команды в Usb2kbd_DLL проходят без проблем. В связи с этим рекомендуется всем, у кого наблюдается данная проблема, переходить на продукт Usb2kbd_LAN/COM с управлением через UDP или COM порт.

Примеры обращения к DLL аппаратного эмулятора клавиатуры и мыши Usb2kbd


Примеры обращения к DLL аппаратного эмулятора клавиатуры и мыши Usb2kbd

В этом разделе вначале мы рассмотрим теоретические примеры "общения" с аппаратным эмулятором клавиатуры и мыши Usb2kbd (на фото) через DLL, а ниже, я приведу конкретные примеры обращения к девайсу через DLL из различных языков программирования и кликеров.

ВНИМАНИЕ! ВАЖНО!

- Все примеры и параметры вызова функций из Dll указаны для девайса Usb2kbd версии 5.0!! Для версий девайса ниже 5.0 параметры вызова функций смотрите в примерах, высылаемых на почту при покупке девайса! Кроме того, поддержка Usb2kbd версий ниже 5.0 прекращена, поэтому пожалуйста, обновите прошивку Usb2kbd на версию 5.0 или выше! (см. раздел Контакты сайта).

- Функция Sum ниже, а также параметры вызова этой функции даны ниже строго ДЛЯ ПРИМЕРА! В реальных девайсах ВСЕ эти параметры будут другими и будут высылаться Вам при покупке устройства!!!! 

Как я уже говорил, Usb2kbd  получает управляющие сигналы из файла-библиотеки DLL (mydll.dll). Сама же библиотека (mydll.dll), в свою очередь, должна получить управляющие сигналы из программы, написанной Вами в любом из языков программирования (Кстати, хочу сказать БОЛЬШОЕ СПАСИБО K.I.S.A. за помощь в разработке Dll!)

Итак, упрощенная схема работы устройства Usb2kbd (схема работы Usb2kbd_LAN описана в разделе сайта "Usb2kbd_LAN"):

1) Подключаем аппаратный эмулятор клавиатуры и мыши в USB-разьем компьютера;

2) При помощи доступных Вам языков программирования создаем программу, в которой подключаем/подгружаем библиотеку mydll.dl управления устройством;

3) Через язык программирования (программы) из подгруженной DLL вызываем функцию для обращения к Usb2kbd, например, Sum (эта функция хранится в подгруженной нами mydll.dl, причем название этой функции будет разным для каждого девайса Usb2kbd), затем этой функции передаем параметры, например, Sum(b1, b2, b3, b4, b5, b6). Параметры рассмотрены в таблице ниже;

4) mydll.dll обрабатывает полученные данные из Вашей программы, и шлет свои управляющие сигналы в аппаратный эмулятор клавиатуры и мыши Usb2kbd, который их выполняет (осуществляет нажатия клавиш клавиатуры, кнопок мыши, перемещение курсора мыши).

Общий вид функции в DLL и используемые типы приведены ниже:

function Sum(Event,Code,x,y:LongInt; vid_pid:PChar; ID:LongInt):LongInt; stdcall;

Важно! Функция возвращает 1 - если устройство usb2kbd найдено и 0 - если usb2kbd не найдено, или не верно заданны параметры функции.

Рассмотрим подробнее функцию Sum(b1, b2, b3, b4, b5, b6) и ее параметры (еще раз напомню, имя функции Sum, а также параметры b5 и b6 даны для примера! У Вас они будут другие, лично Ваши и присылаемые Вам по почте при покупке девайса!):

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

b2 - Вспомогательный символ, который дополняет символ b1. Может означать:

а) Код клавиши (целое число, значения от 4 до 231) - определяет код нажатой или отжатой клавиши клавиатуры для случаев, когда b1 = 1 или 2 (коды клавиш Вы сможете скачать в разделе "Загрузки");

ИЛИ

б) Код нажатия кнопок мыши (целое число, значения от 0 до 7) - определяет код нажатой или отжатой кнопки мыши для случаев, когда b1 равен 3 или 4 или 5 или 6.

... т.д. Подробнее - в таблице ниже.

Примеры обращения к DLL аппаратного эмулятора клавиатуры и мыши Usb2kbd
Внимание! Многие, прочитав раздел об управляющих командах мыши, зададут вопрос - Что такое "отключение ускорения мыши в Windows" и зачем его отключать? Дело в том, что по умолчанию такое ускорение мыши включено в Windows и если, например, Вы отправите девайсу usb2kbd команду, например, сместить курсор на 100 пикселей по оси X, то девайс, конечно выполнит команду и отправит уже в Windows смещение на те же 100 пикселей по оси X. Но вот Windows, получив такое смещение, самостоятельно "ускорит" мышь - и курсор мыши сместиться не на 100 пикселей, а на большую величину (например, 140 пикселей).  Так вот, чтоб такого не произошло, управляющая Dll самостоятельно умеет отключать и опять включать "ускорение" мыши автоматически, чтоб курсор не "ускорялся" и смещался корректно. Если использовать такие методы, где отключение ускорения мыши в Windows делает Dll (это методы b1=3 или 4), то такие события будут исполняться девайсом на порядок медленнее, чем методы без автоматического отключения ускорения (это методы b1=5, 6), так как на "отключение" и "включение" ускорения нужно время (около 12 мс). Но как в таком случае быть, чтоб курсор смещался корректно без микрозадержек в 12 мс ? Ответ прост - Вы сможете самостоятельно отключить ускорение мыши в настройках мыши Windows (смотрите рисунок ниже), и тогда спокойно использовать методы b1=5, 6, и они будут максимально быстрыми и точными.
Примеры обращения к DLL аппаратного эмулятора клавиатуры и мыши Usb2kbd
Теперь поговорим немного о паузах. Запомните - для корректной работы устройства необходима минимальная пауза в 3мс между каждым событием, отправляемым в Usb2kbd! Это важно! Вы можете увеличивать или уменьшать размер паузы между событиями самостоятельно из Вашего языка программирования под свои нужды, но не менее 3 мс, когда работа девайса считается стабильной!
ВНИМАНИЕ! Для методов b1=5 или b1=6 рекомендуется использовать паузы не менее 4мс! (спасибо за тесты Ruslan)
Кстати! Если у Вас несколько девайсов Usb2kbd, то Вы можете для всех них использовать одну DLL и одно имя функции, но разные параметры b5 (VID/PID) и b6 (ID).
Руководствуясь всем вышеперечисленным придумаем задачу и составим аргументы b1, b2, b3, b4, b5, b6 для функции Sum. Примем для примера возьмем параметр b5 = "vid_16c0&pid_05df", а b6 = 1014

Пример1 (схематично)

Задача: Печатаем слово "hello".

Решение:

Sum(1, 11, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 11 (код клавиши "h" - все коды можно сказать в разделе сайта "Загрузки"), b5, b6 - неизменны (высылаются Вам после получения устройства).

Пауза 3 мс; // читайте выше, зачем нужны паузы

Sum(8, 11, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 8 (отжатие всех клавиш клавиатуры), b2 = 11 (код клавиши "h")

Пауза 3 мс;

Sum(1, 8, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 8 (код клавиши "e")

Пауза 3 мс;

Sum(8, 8, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 8 (отжатие всех клавиш клавиатуры), b2 = 8 (код клавиши "e")

Пауза 3 мс;

Sum(1, 15, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 15 (код клавиши "l")

Пауза 3 мс;

Sum(8, 15, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 8 (отжатие всех клавиш клавиатуры), b2 = 15 (код клавиши "l")

Пауза 3 мс;

Sum(1, 15, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 15 (код клавиши "l")

Пауза 3 мс;

Sum(8, 15, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 8 (отжатие всех клавиш клавиатуры), b2 = 15 (код клавиши "l")

Пауза 3 мс;

Sum(1, 18, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 18 (код клавиши "o")

Пауза 3 мс;

Sum(8, 18, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 8 (отжатие всех клавиш клавиатуры), b2 = 18 (код клавиши "o")

Пауза 3 мс;

Заметьте, что я отжимаю каждую клавишу кодом 8 (отжать все клавиши клавиатуры) - так надежнее, чтоб не было "залипаний нажатия одной клавиши". Код 2 (отжатие конкретной клавиши клавиатуры) следует использовать, если Вы хотите передать устройству usb2kbd последовательную комбинацию нажатий/отжатий клавиш.

ВНИМАНИЕ! Если в процессе работы usb2kbd будет периодически мигать вторым красным светодиодом, то это свидетельствует о факте переполнения буфера FIFO в устройстве, т.е. данные из Dll поступают быстрее, чем устройство сможет их обрабатывать, и, как результат, эти  "быстрые" пакеты будут утеряны, о чем устройство просигнализирует миганием второго красного светодиода, что должно послужить Вам сигналом об увеличении пауз в Вашем скрипте между событиями (т.е. увеличиваем вместо 3 мс ставим большее значение).

Пример2.

Задача: Зажимаем комбинацию клавиш "Shift+F4"

Решение:

Sum(1, 225, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 225 (код клавиши "LShift")

Пауза 3 мс;

Sum(1, 61, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 1 (нажатие клавиши клавиатуры), b2 = 61 (код клавиши "F4")

Пауза 3 мс;

Sum(2, 61, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 2 (отжатие клавиши клавиатуры), b2 = 61 (код клавиши "F4")

Пауза 3 мс;

Sum(2, 225, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 2 (отжатие клавиши клавиатуры), b2 = 225 (код клавиши "LShift")

Пауза 3 мс;

Как видно, тут уже я использую код 2 для отжатия каждой клавиши, т.к. мы "нажимаем" комбинацию клавиш.

Пример3.

Задача: Нажатие левой кнопки мыши в координатах экрана X=100, Y=200 (т.е. в абсолютных координатах экрана).

Решение:

Sum(3, 1, 100, 200, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 3 (событие мыши, абсолютные координаты (с отключением ускорения в windows)), b2 = 1 (нажатие левой кнопки мыши), b3 = 100, b4 = 200 (координаты клика - Х=100 и Y=200)

Пауза 3 мс;

Sum(3, 0, 100, 200, "vid_16c0&pid_05df", 1014);  // управляющий символ b1= 3 (событие мыши, абсолютные координаты (с отключением ускорения в windows))  b2 = 0 (отжать все кнопки мыши), b3 = 100, b4 = 200 (координаты отжатия кнопки мыши - Х=100 и Y=200).

Пауза 3 мс;

Пример4.

Задача: Нажатие левой кнопки мыши в текущих координатах курсора.

Решение:

Sum(4, 1, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 4 (событие мыши, относительные координаты), b2 = 1 (нажатие левой кнопки мыши), b3 = 0, b4 = 0 (смещение курсора - в данном случае - без смещения)

Пауза 3 мс;

Sum(4, 0, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 4 (событие мыши, относительные координаты), b2 = 0 (отжать все кнопки мыши), b3 = 0, b4 = 0 (смещение курсора - в данном случае - без смещения)

Пауза 3 мс;

Пример5.

Задача: Выделение мышью от X=100 Y=100 в X=200 Y=200

Решение:

Sum(3, 1, 100, 100, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 3 (событие мыши, абсолютные координаты), b2 = 1 (нажатие левой кнопки мыши), b3 = 100, b4 = 100 (координаты нажатия левой мыши - Х=100 и Y=100)

Пауза 3 мс;

Sum(3, 1, 200, 200, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 3 (событие мыши, абсолютные координаты), b2 = 1 (нажатие левой кнопки мыши), b3 = 200, b4 = 200 (координаты нажатия левой мыши - Х=200 и Y=200)

Пауза 3 мс;

Sum(3, 0, 200, 200, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 3 (событие мыши, абсолютные координаты), b2 = 0 (отжать все кнопки мыши), b3 = 200, b4 = 200 (координаты отжатия левой мыши - Х=200 и Y=200)

Пауза 3 мс;

Пример6.

Задача: Нажать одновременно левую и правую кнопки мыши и отпустить (без перемещения).

Решение:

Sum(4, 3, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 4 (событие мыши, относительные координаты), b2 = 3 (нажатие левой+правой кнопок мыши), b3 = 0, b4 = 0 (без перемещения)

Пауза 3 мс;

Sum(4, 0, 0, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 4 (событие мыши, относительные координаты), b2 = 0 (отжать все кнопки мыши), b3 = 0, b4 = 0 (без перемещения)

Пауза 3 мс;

Пример7.

Задача: Прокрутить колёсиком мыши "вверх" на 1 "щелчок".

Решение:

Sum(7, 0, 1, 0, "vid_16c0&pid_05df", 1014);     //  управляющий символ b1= 7 (событие мыши, прокрутка колёсика), b3 = 1 ("вверх на один "щелчок")

Пауза 3 мс;

Для прокрутки колёсиком мыши "вниз" проставьте b3 = -1

Хватит теории, пошла практика для конкретных языков программирования...

Для обращения к аппаратному эмулятору клавиатуры и мыши Usb2kbd для начала необходимо при помощи любого доступного языка программирования определенным образом "подключить" управляющую библиотеку mydll.dll к Вашей программе.

Для примера я опишу подключение библиотеки mydll.dll и обращение к ее функции Sum (имя функции дано случайное для примера!) посредством различных языков программирования Borland C++ Builder 6.0 upd 4), Visual Basic, Delphi7.

Поехали...


Borland C++ Builder 6.0 upd 4 (вызов по событию нажатия кнопки в форме)

 

void __fastcall TForm1::Button1Click(TObject *Sender)
{
// эта часть для загрузки dll в память
HINSTANCE MYDLL;

typedef int(*__stdcall pSum)(int, int, int, int, AnsiString, int);

// имя фунции Sum дано для примера - проставьте СВОЮ!
pSum Sum;
MYDLL = LoadLibrary("mydll.dll");
Sum = (pSum)GetProcAddress(MYDLL, "Sum");

int b1=StrToInt(Edit1->Text.c_str());
int b2=StrToInt(Edit2->Text.c_str());
int b3=StrToInt(Edit3->Text.c_str());
int b4=StrToInt(Edit4->Text.c_str());

// ниже два параметра для примера - проставьте СВОИ
AnsiString b5 = "vid_16c0&pid_05df";
int b6 = 1012;


int b7=Sum(b1, b2, b3, b4, b5, b6); // вызываем функцию

FreeLibrary (MYDLL);
}
//---------------------------------------------------------------------------


Пояснения:

В первой части кода мы динамически "подгружаем" нашу управляющую библиотеку mydll.dll и ищем в ней необходимую нам функцию Sum. При этом очень важно, чтоб библиотека mydll.dll находилась либо в одной папке с программой, либо в месте, указанном в переменной Windows PATH (например, C:\windows\ и т.д.)

Затем мы передаем найденной выше функции Sum аргументы b1, b2, b3 и b4 из полей формы, а также b5 и b6 - идентификаторы устройства (для каждого девайса будут разные).

И уже в коде:

FreeLibrary (MYDLL);

мы "выгружаем" нашу DLL (mydll.dll), т.е. заканчиваем с ней работу.


Ниже также я приведу код, как обратиться к Dll посредством языка программирования Visual Basic (устройство Usb2kbd подключено, библиотека расположена в c:\temp\mydll.dll):

 

Public Class Form1

    Private Property a As Integer

    Private Declare Function Sum Lib "c:\temp\mydll.dll" (ByVal a As Integer, ByVal b As Integer, ByVal c As Integer, ByVal d As Integer, ByVal e As String, ByVal f As Integer) As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        a = Sum(3, 0, 100, 100, "vid_16c0&pid_05df", 1012)
    End Sub
End Class

 

PS: Совет от Алексея (пробуйте):

 

"измените
Private Declare Function Sum Lib
на
Private Declare PtrSafe Function Sum Lib 

(PtrSafe  - в любой 32- и 64-разрядных версий Office работать будет, это для VBA)".

 


 

Пример для vb.net в ms visual studio 2008 (спасибо за пример Андрею):

 

Public Class Form1
    Private Declare Function Sum Lib "c:\temp\mydll.dll" (ByVal a As Integer, ByVal b As Integer, ByVal c As Integer, ByVal d As Integer, ByVal e As String, ByVal f As Integer) As Integer 'Ваша функция Usb2kbd
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'функция обеспечивающая ожидание программы до следующего действия в миллисекундах
    Dim State As Integer ' в эту переменную будет передавать ответ с usb2kbd о успешности выполнения команды

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        PressKey(4) 'вызываем процедуру PressKey, которая нажимает и отжимает не раньше чем через 30 мс конопку с заданным в агрументе кодом
        State = Sum(8, 0, 0, 0, "Ваш_параметр_b5", Ваш_параметр_b5) 'отжимаем все кнопки
    End Sub

    Private Sub PressKey(ByVal Kod As Integer)
        Dim Time As Integer
        State = Sum(1, Kod, 0, 0, "Ваш_параметр_b5", Ваш_параметр_b6) 'нажать кнопку
        Time = 30 + Math.Round(20 * Rnd()) ' задаем время между нажатием и отжатием кнопки рандомно от 30 до 50 мс
        Sleep(Time) 'ждем заданное время
        State = Sum(2, Kod, 0, 0, "Ваш_параметр_b5", Ваш_параметр_b5) 'отжать кнопку
    End Sub
End Class

 

PS:

Если не работает обращение к функции dll с ошибкой BadImageFormatException, то необходимо выставить в настройках компиляции:

свойства проекта->компиляция->дополнительные параметры->конечный ЦП: необходимо поставить х86.


 

Для Visual Studio 2010  C++ код вызова функции следующий:

 

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
using namespace System;

typedef UINT (CALLBACK* LPFNDLLFUNC1)(INT,INT, INT, INT, String^, INT);


int main(array<System::String ^> ^args)
{
int b1=3;
int b2=0;
int b3=100;
int b4=100;
String^ b5  = gcnew String("vid_16c0&pid_05df");
int b6  = 1014;
int ReturnVal;

HINSTANCE hDLL;               // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
hDLL = LoadLibraryA("mydll.dll");
if (hDLL != NULL)
{
   lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "Sum");
   if (!lpfnDllFunc1)
   {
      // handle the error
      FreeLibrary(hDLL);
      return 0;
   }
   else
   {
      // call the function
      ReturnVal = lpfnDllFunc1(b1, b2, b3, b4, b5, b6);
   }
}

 


А это пример для x64 DLL на Visual Studio 2022 С++(спасибо за пример Денису)

 

#include <iostream>
#include <Windows.h>
 
typedef UINT(CALLBACK* LPFNDLLFUNC1)(INT, INT, INT, INT, const wchar_t*, INT);
 
int main()
{
    int ReturnVal = -1;
 
    HINSTANCE hDLL;               // Handle to DLL
    LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
    hDLL = LoadLibraryA("mydll_x64.dll");
    if (hDLL != NULL)
    {
        lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "Sum");
            // call the function
            Sleep(1000);
            ReturnVal = lpfnDllFunc1(1, 11, 0, 0, L"vid_16c0&pid_05df", 5611);
            std::cout << ReturnVal;
            Sleep(300);
            lpfnDllFunc1(8, 11, 0, 0, L"vid_16c0&pid_05df", 5611);
    }
}

 

 



А вот так будет выглядеть обращение к DLL на языке C#:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {

    [DllImport("mydll.dll", CharSet = CharSet.Ansi)]
        public static extern int Sum(int b1, int b2, int b3, int b4, String b5, int b6);


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Sum(3, 0, 100, 100, "vid_16c0&pid_05df", 1012);
        }
    }
}

 

ВНИМАНИЕ!

Для обращения к dll_x64 используйте следующий код (спасибо за пример Андрею):

 

[DllImport("mydll_x64.dll", CharSet = CharSet.Unicode)]

 

        public static extern int hitte(int b1, int b2, int b3, int b4, string b5, int b6);


А ниже мы увидим, как обратиться к DLL через Delphi7:

 

procedure TForm1.Button1Click(Sender: TObject);
var
c:integer;
dHandle: THandle;
usb2kbdSend: function (b1,b2,b3,b4:integer; b5:AnsiString,b6:integer):Integer; stdcall;
begin
if not FileExists('mydll.dll') then Exit; //Файла нет
dHandle:=LoadLibrary('mydll.dll');
if dHandle<=32 then Exit; //Ошибка
Form1.Caption:=dHandle.ToString;
@usb2kbdSend:=GetProcAddress(dHandle,'ИМЯ_ФУНКЦИИ');
if @usb2kbdSend=nil then Exit; //Функцию не нашли
C:=Sum(3, 0, 100, 100, 'vid_16c0&pid_05df', 1012);
FreeLibrary(dHandle);
end;

(спасибо за код K.I.S.A).

 

Или пробуем мой код (событие нажатия кнопки):

procedure TForm1.Button1Click(Sender: TObject);

var
c:integer;
dHandle: THandle;
Sum: function (a,b,c,d:integer;e:string,f:integer):Integer;stdcall;
begin
dHandle:=LoadLibrary('mydll.dll');
@Sum:=GetProcAddress(dHandle,'Sum');
C:=Sum(3, 0, 100, 100, 'vid_16c0&pid_05df', 1012);
FreeLibrary(dHandle);
end;

end.

 

Для Delphi версий выше 7 код следующий (спасибо за подсказку Buboner):

 

procedure TForm1.Button1Click(Sender: TObject);
var
c:integer;
dHandle: THandle;
Sum: function (a,b,c,d:integer;e:AnsiString{String}, f:integer):Integer;stdcall;
begin
dHandle:=LoadLibrary('mydll.dll');
Form1.Caption :=   dHandle.ToString;
@Sum:=GetProcAddress(dHandle,'Sum');
C:=Sum(3, 0, 100, 100, 'vid_16c0&pid_05df', 1014);
FreeLibrary(dHandle);
end;


Ниже рассмотрим пример обращения к Dll через скриптовый язык программирования Autohotkey:

 

Создаём файл hello.ahk:

 

Sleep, 2000
hModule := DllCall("LoadLibrary", "AStr", "mydll.dll")  ; Подгрузим Dll в начале скрипта, чтоб не подгружать постоянно


hFile := DllCall("mydll\Sum", int, 1, int, 11, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)

Sleep, 3
hFile := DllCall("mydll\Sum", int, 8, int, 11, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)
Sleep, 3

hFile := DllCall("mydll\Sum", int, 1, int, 8, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)

Sleep, 3

hFile := DllCall("mydll\Sum", int, 8, int, 8, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)
Sleep, 3

hFile := DllCall("mydll\Sum", int, 1, int, 15, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)

Sleep, 3

hFile := DllCall("mydll\Sum", int, 8, int, 15, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)
Sleep, 3

hFile := DllCall("mydll\Sum", int, 1, int, 15, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)

Sleep, 3

hFile := DllCall("mydll\Sum", int, 8, int, 15, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)
Sleep, 3

hFile := DllCall("mydll\Sum", int, 1, int, 18, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)

Sleep, 3

hFile := DllCall("mydll\Sum", int, 8, int, 18, int, 0, int, 0, "AStr", "vid_16c0&pid_05df", int, 1012)
Sleep, 3

DllCall("FreeLibrary", "UInt", hModule)  ; Выгрузим Dll, чтоб освободить память


А вот так будет выглядеть обращение к Dll на языке AutoIt:

 

Sleep(2000)
$dll = DllOpen("mydll.dll")


$hModule = DllCall($dll, "int", "Sum", "int", 1, "int", 11, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

$hModule = DllCall($dll, "int", "Sum", "int", 8, "int", 11, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

 

$hModule = DllCall($dll, "int", "Sum", "int", 1, "int", 8, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

$hModule = DllCall($dll, "int", "Sum", "int", 8, "int", 8, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

 

$hModule = DllCall($dll, "int", "Sum", "int", 1, "int", 15, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

$hModule = DllCall($dll, "int", "Sum", "int", 8, "int", 15, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

 

$hModule = DllCall($dll, "int", "Sum", "int", 1, "int", 15, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

$hModule = DllCall($dll, "int", "Sum", "int", 8, "int", 15, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

 

$hModule = DllCall($dll, "int", "Sum", "int", 1, "int", 18, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

$hModule = DllCall($dll, "int", "Sum", "int", 8, "int", 18, "int", 0, "int", 0, "str", "vid_16c0&pid_05df", "int", 1012)

Sleep(3)

 

DllClose($dll)

 


Для Autoit_x64 используйте следующий код:

 

$dll = DllOpen("mydll_x64.dll")

 

$hModule = DllCall($dll, "int", "swarn", "int", 3, "int", 0, "int", 100, "int", 100, "wstr", "vid_c21d&pid_d48f", "int", 1576)

 


Ниже пример перемещения мыши по Безье через девайс на AutoIt (Спасибо за пример Николаю!)

 

; не все обязательные

#include <Array.au3>

#include <INet.au3>

#include <File.au3>

#include <GUIConstantsEx.au3>

#include <GDIPlus.au3>

#include <WinAPI.au3>

#include <Misc.au3>

#include <Date.au3>

#include <ImageSearch.au3>

 

global $xm, $ym

global $VID="vid_046d&pid_c292"

global $dll_name="unreal64.dll"

 

Dim $PtX[4]

Dim $PtY[4]

Dim $MaxPt = 3

 

;------исполняемая область

MC(100,100) 

MC(10,800)

MC(800,10)

;------

 

Func MC($xm,$ym) ; перемещение по кривой Безье, в конце перемещения щелчок в относительных координатах

   $dll = DllOpen($dll_name)

   MouseBezier($xm,$ym)

   $hModule = DllCall($dll, "int", "gurus", "int", 4, "int", 1, "int", 0, "int", 0, "WStr", $VID, "int", 1292) ;щелчок в текущих координатах мыши

   Sleep(4)

   $hModule = DllCall($dll, "int", "gurus", "int", 4, "int", 0, "int", 0, "int", 0,  "WStr", $VID, "int", 1292) ;отпустить кнопки мыши

   Sleep(4)

   DllClose($dll)

EndFunc

 

Func MM($x,$y) ; перемещение мыши

   $dll = DllOpen($dll_name)

   $hModule = DllCall($dll, "int", "gurus", "int", 3, "int", 0, "int", $x, "int", $y,  "WStr", $VID, "int", 1292)

   DllClose($dll)

EndFunc

 

Func Factorial($n)

   $value = 1

    For $i = 2 To $n

        $value = $value * $i

    Next

 

    Return $value

EndFunc

 

Func Y($t)

   $value = 0

 

    For $i = 0 To $MaxPt

        $value = $value + $PtY[$i] * Blend($i, $MaxPt, $t)

    Next

 

    Return $value

EndFunc

 

Func X($t)

   $value = 0

 

    For $i = 0 To $MaxPt

        $value = $value + $PtX[$i] * Blend($i, $MaxPt, $t)

    Next

   Return $value

EndFunc

 

Func MouseBezier($ex, $ey)

   $pos = MouseGetPos()

   If IsArray($pos) Then

      If $pos[0] < $ex Then

         $PtX[0] = $pos[0]

         $PtX[1] = $pos[0] * Random(2, 3)

         $PtX[2] = $PtX[1]

         $PtX[3] = $ex

      Else

         $PtX[0] = $pos[0]

         $PtX[1] = $pos[0] / Random(2, 3)

         $PtX[2] = $PtX[1]

         $PtX[3] = $ex

      EndIf

 

      If $pos[1] < $ey Then

         $PtY[0] = $pos[1]

         $PtY[1] = $pos[1]

         $PtY[2] = $pos[1] * Random(2, 3)

         $PtY[3] = $ey;

      Else

         $PtY[0] = $pos[1]

         $PtY[1] = $pos[1]

         $PtY[2] = $pos[1] / Random(2, 3)

         $PtY[3] = $ey;

      EndIf

 

      MouseCurve(0, 1)

   EndIf

EndFunc

 

Func MouseCurve($start_t, $stop_t)

   $dt = 0.01

    $t = $start_t + $dt

    While $t < $stop_t

        MM(X($t), Y($t))

        $t = $t + $dt

    Wend

EndFunc

 

Func Blend($i, $n, $t)

    Return Factorial($n) / Factorial($i) / Factorial($n - $i) * $t ^ $i * (1 - $t) ^ ($n - $i)

EndFunc


Рассмотрим, как обратиться к устройству посредством популярного кликера Clickermann:

 

DEFINE($VID,0x16c0)
DEFINE($PID,0x05df)
DEFINE($ID,1012)

WAITMS(5000)
CALL("mydll.dll", 1, 11, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 8, 11, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 1, 8, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 8, 8, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 1, 15, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 8, 15, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 1, 15, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 8, 15, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 1, 18, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 8, 18, 0, 0,$VID,$PID,$ID)
WAITMS(3)
CALL("mydll.dll", 3, 0, 100, 100,$VID,$PID,$ID)

WAITMS(3)
halt // for single run


Ниже давайте разберем, как обратиться к Usb2kbd через Kibor (Кибор):

sleep(5000);
external(INT, "Sum", "Sum", "mydll.dll");
Sum(1, 11, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);
Sum(8, 11, 0, 0, "vid_16c0&pid_05df", 1012);
sleep(3);

Sum(1, 8, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);

Sum(8, 8, 0, 0, "vid_16c0&pid_05df", 1012);
sleep(3);

Sum(1, 15, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);

Sum(8, 15, 0, 0, "vid_16c0&pid_05df", 1012);
sleep(3);

Sum(1, 15, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);

Sum(8, 15, 0, 0, "vid_16c0&pid_05df", 1012);
sleep(3);

Sum(1, 18, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);

Sum(8, 18, 0, 0, "vid_16c0&pid_05df", 1012);

sleep(3);


А вот простой пример на питоне печатает символ h (спасибо за пример Сергею):

import ctypes
hllDll = ctypes.WinDLL("./mydll.dll")
hllApiProto = ctypes.WINFUNCTYPE(
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_char_p,
    ctypes.c_int
)
hllApi = hllApiProto(("mefis", hllDll))
hllApi(1, 11, 0, 0, b"vid_16c0&pid_05df", 1012)
hllApi(2, 11, 0, 0, b"vid_16c0&pid_05df", 1012)

ВНИМАНИЕ!

На pythonx64 для обращения к DLL_x64 надо в структуре примера выше ctypes.c_char_p заменить на ctypes.c_void_p тогда работает. (Спасибо за совет Алексею!)


Еще пример  для x86 и x64 DLL-кам на Питоне (Спасибо за пример Станиславу!):

import time

from ctypes import *

# Загрузка библиотеки

#lib = cdll.LoadLibrary(".../mydll.dll")      #Для 32 разрядной архитектуры

#lib = cdll.LoadLibrary(".../mydll_x64.dll")  #Для 64 разрядной архитектуры

lib = cdll.LoadLibrary("D:/Distr/id1189/mydll_x64.dll") 

# Определение переменных, передаваемых в методы-эмуляции

#b5 = b"vid_a7fe&pid_bb23" #Для 32 разрядной архитектуры

#b5 = "vid_a7fe&pid_bb23"  #Для 64 разрядной архитектуры

# Идентификатор устройства

b5 = "vid_a7fe&pid_bb23" 

# Серийный номер устройства

b6 = 1189

def PressKey(Key,Dalay): 

    # Пауза

    if Dalay > 0:

        time.sleep(Dalay)

    #Нажатие на кнопку клавиатуры

    lib.roche(1, Key, 0, 0, b5, b6)

    lib.roche(8, Key, 0, 0, b5, b6)

def MouseMove(X,Y,Dalay):

    # Пауза

    if Dalay > 0:

        time.sleep(Dalay)

    # Перемещение в точку Х,У

    lib.roche(3, 0, X, Y, b5, b6) 

def MouseLeftClick(X,Y,Dalay):

    # Пауза

    if Dalay > 0:

        time.sleep(Dalay)

    # Перемещение в точку Х,У

    lib.roche(3, 0, X, Y, b5, b6) 

    # Одиночный клик левой кнопкой мыши, используя метод, предоставленный с библиотекой, данном случае был предоставлен метод "roche",

    # правила использования которого приведено в файле main.ahk

    lib.roche(3, 1, X, Y, b5, b6) 

    lib.roche(3, 0, X, Y, b5, b6)

time.sleep(2)

# Печать слова hello с паузой между нажатиями в 0.1 секунду

PressKey(11, 0.1)

PressKey(8, 0.1)

PressKey(15, 0.1)

PressKey(15, 0.1)

PressKey(11, 0.1)

# Перемещение указателя мышки БЕЗ клика в точке Х, У с паузой в 1 секунду

MouseMove(100, 100, 1)

MouseMove(200, 200, 1)

MouseMove(300, 300, 1)

# Перемещение указателя мышки с кликом в точку Х, У с паузой в 0.5 секунды

MouseLeftClick(200, 400, 0.5)

MouseLeftClick(100, 500, 0.5)


Ниже пример для Node.js (Спасибо за пример Андрею!):

// Для 64bit ноды - нужна 64 бит либа

// bille => у каждого устройства название функции своё

const ffi = require('ffi-napi');

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const VID = 'vid_16c0&pid_05df'

const ID = '1012'

let lib = ffi.Library('./mydll.dll', {

    bille: ['int', ['int', 'int', 'int', 'int', 'string', 'int']],

});

const token = new Buffer.from(VID, 'ucs2').toString('binary');

(async () => {

    // do magic

    lib.bille(4, 2, 0, 0, token, ID);await delay(10); //Right click on current pos

});