Plugin на PureBasic, нужна помощь
- Author
- Message
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
Plugin на PureBasic, нужна помощь
Хочу попробовать написать плаг на PureBasic, но хотелось бы иметь шаблон с чего начать.
Я уже делал плаги используя шаблон, а с нуля это попытаться с моей стороны сравнить шаблоны плагов на С++, чтобы произвести такие же действия для PureBasic, с учётом что я слабо разбираюсь в С++.
Я уже делал плаги используя шаблон, а с нуля это попытаться с моей стороны сравнить шаблоны плагов на С++, чтобы произвести такие же действия для PureBasic, с учётом что я слабо разбираюсь в С++.
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
Может кто сделать плагин шаблон минимального типа, например для начала вывести мессагу "привет мир!". Собственно интересует встраивание пункта меню в интерфейс AkelPad, то есть в меню плагинов.
Я немного попытался
инклуд
Но наверняка мне не нужны некоторые структуры по крайней мере на начальном этапе, или не нужны все её параметры, просто задать её нужным размером.
Я немного попытался
инклуд
Но наверняка мне не нужны некоторые структуры по крайней мере на начальном этапе, или не нужны все её параметры, просто задать её нужным размером.
Last edited by AZJIO on Fri May 08, 2020 12:42 pm, edited 5 times in total.
-
Offline
- Posts: 3217
- Joined: Wed Nov 29, 2006 1:19 pm
- Location: Киев, Русь
- Contact:
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
VladSh
Ну если взять вызов "Format::LineFixWrap", здесь "Format" это имя DLL или имя импортированное из DLL. А также LineFixWrap это функция или Format это класс/модуль, а LineFixWrap функция внутри модуля. Я пока не понимаю связи. В исходнике нет описания или его мало или написано для знающих язык С++. Я смотрю плаг для Notepad++ на PureBasic, вижу функции в формате С++, там мне всё понятно, пытаюсь делать аналогию.
Если удастся разобраться в минималистическом коде, то в точку вызова мессаги я допустим вставлю вызов функции GUI, которая уже будет на понятном для меня языке PureBasic. Ну хотя придётся изучить язык вызова внутренних AkelPad-функций, чтобы получать позиции курсора и т.д. Но хотя бы начало получить, чтобы интерес был. Сразу я не смогу переписать заголовочный файл AkelDLL.h (и надо ли), могу пойти по неправильному пути. Я хоть и переписал пару структур, но по идее надо гуглить размер в байтах каждого типа данных для x86, а в будущем и для x64 или сразу, чтобы указать изменяющийся тип взависимости от битности.
Я скачал "Templates", думая что это пример, потом полегче взял "Exit", сейчас нашёл "AkelDLL", хотя я про него просто забыл, ранее пытался его ковырять. Ну да, он просто мессага, буду опять пробовать, вижу там функцию GetSelTextTest, которая экспортируется в окно плагов, а "AkelDLL" стало именем. Так что это имя файла и в ней функция, остаётся конвертировать жизненно необходимые структуры, в самой структуре PLUGINDATA несколько вложенных, так что не знаю, окажется ли во вложенных ещё вложенные, но цель уже понятна.
Ну если взять вызов "Format::LineFixWrap", здесь "Format" это имя DLL или имя импортированное из DLL. А также LineFixWrap это функция или Format это класс/модуль, а LineFixWrap функция внутри модуля. Я пока не понимаю связи. В исходнике нет описания или его мало или написано для знающих язык С++. Я смотрю плаг для Notepad++ на PureBasic, вижу функции в формате С++, там мне всё понятно, пытаюсь делать аналогию.
Если удастся разобраться в минималистическом коде, то в точку вызова мессаги я допустим вставлю вызов функции GUI, которая уже будет на понятном для меня языке PureBasic. Ну хотя придётся изучить язык вызова внутренних AkelPad-функций, чтобы получать позиции курсора и т.д. Но хотя бы начало получить, чтобы интерес был. Сразу я не смогу переписать заголовочный файл AkelDLL.h (и надо ли), могу пойти по неправильному пути. Я хоть и переписал пару структур, но по идее надо гуглить размер в байтах каждого типа данных для x86, а в будущем и для x64 или сразу, чтобы указать изменяющийся тип взависимости от битности.
Я скачал "Templates", думая что это пример, потом полегче взял "Exit", сейчас нашёл "AkelDLL", хотя я про него просто забыл, ранее пытался его ковырять. Ну да, он просто мессага, буду опять пробовать, вижу там функцию GetSelTextTest, которая экспортируется в окно плагов, а "AkelDLL" стало именем. Так что это имя файла и в ней функция, остаётся конвертировать жизненно необходимые структуры, в самой структуре PLUGINDATA несколько вложенных, так что не знаю, окажется ли во вложенных ещё вложенные, но цель уже понятна.
-
Offline
- Posts: 3217
- Joined: Wed Nov 29, 2006 1:19 pm
- Location: Киев, Русь
- Contact:
-
Offline
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Сам AkelPad и подавляющее большинство (если не все) его плагинов написаны на чистом C. Так что никаких классов.
В ContextMenu-Rus.txt читаем:
Описанный подход для вызова функции из плагина не уникален для плагина ContextMenu или Scripts. Это универсальный подход, с помощью которого и AkelPad, и его плагины вызывают функции других плагинов.
В ContextMenu-Rus.txt читаем:
Здесь `Scripts` - это имя плагина (файла с расширенем .dll), а `Main` - имя экспортируемой из .dll функции. Поскольку речь о чистом C, это имя функции as is (как в исходном коде), безо всяких mangled function name, могущих встретиться в C++ при экспорте функции без `extern "C"`.Call("Плагин::Функция"[, дополнительные параметры])
Call("Scripts::Main")
метод вызывает плагин Scripts и функцию Main.
Описанный подход для вызова функции из плагина не уникален для плагина ContextMenu или Scripts. Это универсальный подход, с помощью которого и AkelPad, и его плагины вызывают функции других плагинов.
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
так как вы отвечаете, сразу вопрос, вот макро с версией.
я не нашёл MAKEWORD как макро или функцию в заголовочных файлах, но гугл дал структуру
то есть просто создать 2 структуры. потом структуру MAKELONG и присвоить адрес структуры в *pv.dwExeMinVersion4x ?
А проще сразу 4-х байтовую структуру.
Как-то так
Code: Select all
((DWORD)MAKELONG(MAKEWORD(a, b), MAKEWORD(c, d)))
Code: Select all
WORD MAKEWORD(
BYTE bLow,
BYTE bHigh
);
А проще сразу 4-х байтовую структуру.
Как-то так
Code: Select all
Structure MAKELONG
StructureUnion
Num.l
byte.c[4]
EndStructureUnion
EndStructure
NumVer.MAKELONG
NumVer\byte[0] = 4
NumVer\byte[1] = 9
NumVer\byte[2] = 6
NumVer\byte[3] = 0
Debug Str(NumVer\Num) ; возвращает 589828, сходится?
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
В общем скомпилировал я плаг, он видит его в плагах, при клике выдаёт
Такая функция выдала то что надо... Мессага вылетела, но AkelPad упал.
Код плага выше я обновил пост №2---------------------------
AkelPad
---------------------------
Обновите 1test плагин.
Архитектура AkelPad'а: 2.2.2.0
Архитектура 1test плагина: 2.0.2.0
---------------------------
ОК
---------------------------
Такая функция выдала то что надо... Мессага вылетела, но AkelPad упал.
Code: Select all
Procedure MAKE_IDENTIFIER(d,c,b,a)
Protected x, y, z
x = ((a << 8) | (b & $FF))
y = ((c << 8) | (d & $FF))
z = ((x << 16) | (y & $FFFF))
ProcedureReturn z
EndProcedure
-
Offline
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Это параметр pv->dwAkelDllVersion, где pv - указатель на структуру PLUGINVERSION.AZJIO wrote:Архитектура AkelPad'а: 2.2.2.0
Архитектура 1test плагина: 2.0.2.0
То есть нужно просто установить pv->dwAkelDllVersion = MAKE_IDENTIFIER(2, 2, 2, 0)
Минимальный код плагина должен выглядеть примерно так:
Code: Select all
// Identification
void __declspec(dllexport) DllAkelPadID(PLUGINVERSION *pv)
{
pv->dwAkelDllVersion = AKEL_DLL_VERSION;
pv->dwExeMinVersion3x = EXE_MIN_VERSION_3X;
pv->dwExeMinVersion4x = EXE_MIN_VERSION_4X;
pv->pPluginName = PLUGIN_NAME;
}
// Plugin extern function
void __declspec(dllexport) QSearch(PLUGINDATA* pd)
{
pd->dwSupport |= PDS_SUPPORTALL;
if ( pd->dwSupport & PDS_GETSUPPORT )
return;
// do something useful here...
// If this function did everything and currently there is no visible
// or invisible (not destroyed) dialog created by it -->
// Stay in memory, and show as non-active
return UD_NONUNLOAD_NONACTIVE;
// If this function created a dialog it is not destroyed -->
// Stay in memory, and show as active
return UD_NONUNLOAD_ACTIVE;
}
Last edited by DV on Fri May 08, 2020 11:48 am, edited 1 time in total.
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
Обновил DLL + исходник, теперь работает захват текста естественным образом, и структуры вроде выровнял.
-
Offline
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Может, стоит создать проект на GitHub, например?AZJIO wrote:Обновил DLL + исходник
Мне с yadi.sk не удаётся скачать, браузер сообщает, что "We can’t connect to the server at yadi.sk".
-
Offline
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Поигрался с версией x86 (32-bit), работает!
На всякий случай, небольшая памятка по часто используемым в WinAPI типам:
На всякий случай, небольшая памятка по часто используемым в WinAPI типам:
Code: Select all
INT, UINT, DWORD, LONG, BOOL - целое число, всегда 4 байта
INT_PTR, UINT_PTR, DWORD_PTR, LONG_PTR, WPARAM, LPARAM - целое число размера указателя: 4 байта для x86, 8 байт для x64
void*, int*, char*, HANDLE, HWND - указатель: 4 байта для x86, 8 байт для x64
-
Offline
- Posts: 330
- Joined: Mon Jun 03, 2019 2:33 am
DV
В чём отличие между окнами, например у меня окно закрывается после создания, я вставляю цикл, но тогда команды плагов блокируются, например не могу сменить подсветку с HTML на XML, а команды AkelPad не блокируются.
Обновлённый, все функции на кнопках GUI.
В чём отличие между окнами, например у меня окно закрывается после создания, я вставляю цикл, но тогда команды плагов блокируются, например не могу сменить подсветку с HTML на XML, а команды AkelPad не блокируются.
Обновлённый, все функции на кнопках GUI.