Форум
Написать нам
  • Страница 1 из 1
  • 1
Модератор форума: as-master  
Пример создания плагина
ПётрДата: Суббота, 26 Февраля 2011, 23:45 | Сообщение # 1
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Решил поделится примером создания плагина для MMB, поскольку информация, описывающая методы создания своих плагинов, почти отсутствует, по крайней мере, мне не удалось её найти. Рассмотрим как создавать плагин для MMB в среде PureBasic
Предоставленная здесь информация, не претендует на полноту сведений и достоверность, т. к. получена методом проб и ошибок.
Как известно плагин для MMB обычная DLLка, но написанная по определённым правилам, которые нужно соблюдать чтобы всё работало нормально.
Функции плагина должны использовать соглашение cdecl.
Так же должен быть набор специальных функций, необходимых в каждом плагине и используемых для "общения" программы и плагина.

Расмотрим исходный текст примера плагина:

Code
;  //// Служебный код плагина! НЕ МОДИФИЦИРОВАТЬ \\\\

; Глобальные переменне
Global Prog_WinHandle.l ; Хендл окна программы на MMB
Global Prog_Path.s      ; Абсолютный путь к проге на MMB
Global GetInt.l         ; Переменая типа LONG, используемая для хранения инфы переданной прогой (PluginSet)
Global SetInt.l         ; Переменая типа LONG, хранящая данные, передаваемые в прогу (PluginGet)
Global GetStr.s         ; Переменая типа STRING, используемая для хранения инфы переданной прогой (PluginSet)
Global SetStr.s         ; Переменая типа STRING, хранящая данные, передаваемые в прогу (PluginGet)
           
ProcedureCDLL.s GetInfo()
      ProcedureReturn "Пример плагина на PureBasic для MMB"
EndProcedure

ProcedureCDLL.s Copyright()
      ProcedureReturn "Copyright MyCorp © 2011"
EndProcedure

ProcedureCDLL SetParentWindow(Handle)
       Prog_WinHandle = Handle
EndProcedure

ProcedureCDLL SetPath(Path.s)
       Prog_Path = Path
EndProcedure

ProcedureCDLL SetData(int.l)
       GetInt = int
EndProcedure

ProcedureCDLL SetFile(String.s)
       GetStr = String
EndProcedure

ProcedureCDLL.l GetData()
      ProcedureReturn SetInt
EndProcedure

ProcedureCDLL.s GetFile()
      ProcedureReturn SetStr
EndProcedure

; //// Функции пользователя, вызываемые из проги на MMB \\\\

; Это спец. процедура, вызывемая при доступе к DLL
ProcedureDLL AttachProcess(Instance)
       Static RunOnly
       If Only<>1
         Only = 1
         InitAudioCD()
         UseAudioCD(0)
       EndIf
EndProcedure

ProcedureCDLL CD_Control()
       State = GetInt & 1
       EjectAudioCD(State)
EndProcedure

ProcedureCDLL Message()
       MessageRequester("ExamplePB_Plugin", GetStr, 64)
       SetStr = "Текущее время: "+FormatDate("%hh:%ii:%ss", Date())
EndProcedure

Функции, находящиеся в верху кода - служебные, необходимые для превильного функционирования связки "программа на MMB - плагин".
Последние две функции "полезные", вызываемые из проги на MMB.
Функция CD_Control открывает и закрывает лоток CD/DVD дисковода по команде из проги, а функция Message, отображает мессагу с текстом, переданным из проги плагину и возвращает текущее время в формате часы:минуты:секунды.

Для создания DLL в PureBasic, нужно открыть новую вкладку и сохранить файл, а затем, в меню "Компилятор", выбрать пункт, "Настройки компилятора".

http://s60.radikal.ru/i169/1102/63/0431d7b5d5aa.png

В открывшемся окне, в выпадающем списке "Формат исполняемого файла", нужно выбрать пункт Shared DLL.

http://i012.radikal.ru/1102/5c/3ccc6cdc0511.png

Затем, сохраняем исходный текст и в меню "Компилятор", выбираем пункт, "Создать приложение" и указываем имя и место сохранения DLL-плагина.

Плагин с его исходным текстом (файл с расширением PB) и примеров использования в MMB, находится во вложении.

PS.
Хотел написать здесь http://mmbuilder.ru/forum/32 поскольку данная тема больше соответствует тому разделу, но там не получилось создать топик. :'( %)

Прикрепления: ExamplePB_Plugi.zip (9.5 Kb)


Сообщение отредактировал Пётр - Воскресенье, 27 Февраля 2011, 00:03
 
DEMBELДата: Суббота, 26 Февраля 2011, 23:59 | Сообщение # 2
Наш дизайнер
Группа: Модераторы
Сообщений: 2266
Репутация: 135
Награды: 32
Статус: Offline
нифига себе )
это вы молодец. а некоторая инфа есть в папке \Plugins\MMBPlugInSDK\




Win7x64 SP1 Neobook v5.70 (Trial)
WinXP SP3 Neobook v5.62
 
Alex3AДата: Воскресенье, 27 Февраля 2011, 01:41 | Сообщение # 3
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
Пётр, сдк на паскале и с доступны, скорвертнуть под твое пюре не проблема.
Ты потерял поцедуру отрисовки окна плагина
Code
void       Draw(HDC hDC, int left, int top,
                 int width, int height);        // calling drawing of the non-windowed plug-in's rectangle

Так что оно годится только для невизуальных плагинов.
Согласно сдк, процедуры
PluginGet, PluginSet оперируют с типом интегер -32-разрядные (4-байтовые) а не лонг -Содержит 64-разрядные (8-байтные).
Что там будет у тебя со стеком нескажу.
 
PeterДата: Воскресенье, 27 Февраля 2011, 02:12 | Сообщение # 4
Админ NeoBook
Группа: Админ NeoBook
Сообщений: 1265
Репутация: 75
Награды: 18
Статус: Offline


Никто не может вернуться в прошлое и изменить свой старт.
Но каждый может стартовать сейчас и изменить свой финиш!
 
Alex3AДата: Воскресенье, 27 Февраля 2011, 03:08 | Сообщение # 5
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
Peter,
 
ПётрДата: Воскресенье, 27 Февраля 2011, 11:31 | Сообщение # 6
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Quote (Alex3A)
Ты потерял поцедуру отрисовки окна плагина
Добавил.
Вот пример с ее использованием:
Code

;  //// Служебный код плагина! НЕ МОДИФИЦИРОВАТЬ \\\\

; Глобальные переменне
Global Prog_WinHandle.l ; Хендл окна программы на MMB
Global Prog_Path.s      ; Абсолютный путь к проге на MMB
Global GetInt.l         ; Переменая типа LONG, используемая для хранения инфы переданной прогой (PluginSet)
Global SetInt.l         ; Переменая типа LONG, хранящая данные, передаваемые в прогу (PluginGet)
Global GetStr.s         ; Переменая типа STRING, используемая для хранения инфы переданной прогой (PluginSet)
Global SetStr.s         ; Переменая типа STRING, хранящая данные, передаваемые в прогу (PluginGet)

ProcedureCDLL.s GetInfo()
  ProcedureReturn "Пример плагина (Draw) на PureBasic для MMB"
EndProcedure

ProcedureCDLL.s Copyright()
  ProcedureReturn "Copyright MyCorp © 2011"
EndProcedure

ProcedureCDLL SetParentWindow(Handle)
   Prog_WinHandle = Handle
EndProcedure

ProcedureCDLL SetPath(Path.s)
   Prog_Path = Path
EndProcedure

ProcedureCDLL SetData(int.l)
   GetInt = int
EndProcedure

ProcedureCDLL SetFile(String.s)
   GetStr = String
EndProcedure

ProcedureCDLL.l GetData()
  ProcedureReturn SetInt
EndProcedure

ProcedureCDLL.s GetFile()
  ProcedureReturn SetStr
EndProcedure

Declare DrawGradient(hDC,StartColor,EndColor, xx,yy, SelWidht, SelHeight)

ProcedureCDLL Draw(hDC, left, top, width, height)
   Shared Font, IconID
    
   DrawPos.RECT
    
   DrawPos\left = left
   DrawPos\top  = top
   DrawPos\right  = DrawPos\left + width
   DrawPos\bottom = DrawPos\top  + height
    
   ; Рисование градиента
   DrawGradient(hDC, RGB(255, 0, 0), RGB(0, 255, 0), left, top, width, height)
    
   SelectObject_(hDC, Font)
   SetTextColor_(hDC, $FFFFFF)
   SetBkMode_(hDC, #TRANSPARENT)
   Text.s="Работа функции Draw плагина DrawPB_Plugin.dll"
   DrawText_(hDC, Text,Len(Text),DrawPos,#DT_SINGLELINE|#DT_VCENTER|#DT_CENTER)
      
EndProcedure

; //// Функции пользователя, вызываемые из проги на MMB \\\\

; Это спец. процедура, вызывемая при доступе к DLL
ProcedureDLL AttachProcess(Instance)
   Shared Font, IconID
   Static RunOnly
   If Only<>1
     Only = 1
     Font=CreateFont_(18,0,0,0,0,0,0,0,#RUSSIAN_CHARSET,0,0,0,0,"Arial")
   EndIf
EndProcedure

; Рисование градиента
Procedure DrawGradient(hDC,StartColor,EndColor, xx,yy, SelWidht, SelHeight)
   PointPen.POINT
    
   sRed.f   = Red(StartColor)   : r.f = (Red  (StartColor) - Red  (EndColor))/SelHeight
   sGreen.f = Green(StartColor) : g.f = (Green(StartColor) - Green(EndColor))/SelHeight
   sBlue.f  = Blue(StartColor)  : b.f = (Blue (StartColor) - Blue (EndColor))/SelHeight
    
   For a = 0 To SelHeight
     x.f = sRed   - a*r
     y.f = sGreen - a*g
     z.f = sBlue  - a*b
     Pen = CreatePen_(#PS_SOLID,1, RGB(x,y,z))
     If Pen
       SelectObject_(hDC, Pen)
       SetROP2_(hDC,#R2_COPYPEN)
       MoveToEx_(hDC, xx, yy+a, @PointPen)
       LineTo_(hDC, xx+SelWidht,  yy+a)
       DeleteObject_(Pen)
     EndIf
   Next a
EndProcedure

http://s16.radikal.ru/i191/1102/cd/38eb17591710.png

Quote (Alex3A)
PluginGet, PluginSet оперируют с типом интегер -32-разрядные (4-байтовые) а не лонг -Содержит 64-разрядные (8-байтные). Что там будет у тебя со стеком нескажу.
Со стеком будет все в порядке - Long целочисленная 4-ёх байтаная переменная.
Прикрепления: DrawPB_Plugin.rar (7.1 Kb)
 
Alex3AДата: Воскресенье, 27 Февраля 2011, 12:35 | Сообщение # 7
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
Quote (Пётр)
Со стеком будет все в порядке - Long целочисленная 4-ёх байтаная переменная.

Присмотрелся я и действительно, ничего себе о..тельно. :D
Интересное трактование типов в энтом пюре.
Будут воросы по сдк, спрашивай, помогу.
Нов общем вполне сойдет.
 
ПётрДата: Воскресенье, 27 Февраля 2011, 14:09 | Сообщение # 8
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Плагин для работы с любым портом компа.
Code
;  //// Служебный код плагина! НЕ МОДИФИЦИРОВАТЬ \\\\

; Глобальные переменне
Global Prog_WinHandle.l ; Хендл окна программы на MMB
Global Prog_Path.s      ; Абсолютный путь к проге на MMB
Global GetInt.l         ; Переменая типа LONG, используемая для хранения инфы переданной прогой (PluginSet)
Global SetInt.l         ; Переменая типа LONG, хранящая данные, передаваемые в прогу (PluginGet)
Global GetStr.s         ; Переменая типа STRING, используемая для хранения инфы переданной прогой (PluginSet)
Global SetStr.s         ; Переменая типа STRING, хранящая данные, передаваемые в прогу (PluginGet)

ProcedureCDLL.s GetInfo()
       ProcedureReturn "Плагин работы с портами для MMB"
EndProcedure

ProcedureCDLL.s Copyright()
       ProcedureReturn "Copyright MyCorp © 2011"
EndProcedure

ProcedureCDLL SetParentWindow(Handle)
        Prog_WinHandle = Handle
EndProcedure

ProcedureCDLL SetPath(Path.s)
        Prog_Path = Path
EndProcedure

ProcedureCDLL SetData(int.l)
        GetInt = int
EndProcedure

ProcedureCDLL SetFile(String.s)
        GetStr = String
EndProcedure

ProcedureCDLL.l GetData()
       ProcedureReturn SetInt
EndProcedure

ProcedureCDLL.s GetFile()
       ProcedureReturn SetStr
EndProcedure

ProcedureCDLL Draw(hDC, left, top, width, height)
              
EndProcedure

; //// Функции пользователя, вызываемые из проги на MMB \\\\

Global Address_IO, Data_IO

Prototype pInp32(Address) ; Прототипы фунукций из inpout32.dll
Prototype pOut32(Address, Infa)

CompilerIf Defined(LoadLibraryM, #PB_Function) = 0
        CompilerError "Для компиляции нужна библиотека PBOSL"
CompilerEndIf

; Это спец. процедура, вызывемая при доступе к DLL
ProcedureDLL AttachProcess(Instance)
        Static RunOnly
        If Only<>1
          Only = 1
                
           *PB_UpakDLL_Mem=AllocateMemory(80000) ; Выделение 80000 байт памяти
           UnpackMemory(?DLL, *PB_UpakDLL_Mem)   ; Распаковка inpout32.dll
           *HModule=LoadLibraryM(*PB_UpakDLL_Mem); Загрузка inpout32.dll из памяти
           If *HModule
             Global Inp32.pInp32 = GetProcAddressM(*HModule, "Inp32")
             Global Out32.pOut32 = GetProcAddressM(*HModule, "Out32")
           EndIf
                 
        EndIf
EndProcedure

ProcedureCDLL SetAddress() ; Задаем адрес порта
        Address_IO = GetInt
EndProcedure

ProcedureCDLL Set_Data() ; Задаем данные порта
        Data_IO = GetInt
EndProcedure

ProcedureCDLL OutPort()  ; Запись данных в выбранный порт
        If Out32<>0 And Address_IO>0
          Out32(Address_IO, Data_IO)
        EndIf
EndProcedure

ProcedureCDLL InpPort()  ; Чтение данных из выбранного порта
        Result = 0
        If Inp32 And Address_IO>0
          Result = Inp32(Address_IO)
        EndIf
        SetInt = Result
EndProcedure
              

DataSection ; Добавление упакованого файла "inpout32.dll" DLL-файл плагина
        DLL:
        IncludeBinary "inpout32.pak"
        DLL_End:
EndDataSection

Данный плагин позволяет работать с любым из портов компа, скажем, LPT портом.
Так как в NT системах, приложения работающие на третьем кольце не имеют привилегий использования ассемблерных инструкций INP и OUT, был использован драйвер inpout32.dll, котрый для уменьшения размера, предварительно сжат и на этапе компиляции, помещен в DLL-файл плагина. При старте плагина, файл inpout32.dll распаковывается в память и от-туда же запускается без создания временного файла на диске.

Для примера, сделал прогу, отображающую текущую температуру процессора с помощью встроенного датчика. Для этого используются порты мат. платы с адресами 661 и 662.
Аналогичный метод измерения температуры процессора использован в известных программах, типа Аида, Эверест и др.
Правда, будет работать не на всех компах, а лишь на тех, материнские платы которых поддерживают данную функцию.

Скрипт для MMB

Code
var=661
PluginSet("PlugIn","var")
PluginRun("PlugIn","SetAddress")
var=43
PluginSet("PlugIn","var")
PluginRun("PlugIn","Set_Data")
Plu   ginRun("PlugIn","OutPort")
var=662
PluginSet("PlugIn","var")
PluginRun("PlugIn","SetAddress")
PluginRun("PlugIn","InpPort")
PluginGet ("  PlugIn","Result")
DisplayValue("Text1","Result")

PS.
Для компиляции плагина нужна библиотека PBOSL, которая позволяет загружать DLL не с диска, а из памяти. Скачать можно здесь http://pure-basic.narod.ru/libs/PBOSL_4.30.rar
Устанавливается распаковкой содержимого архива в папку со средой PureBasic.

Прикрепления: Port_IO_PB_Plug.rar (45.9 Kb)


Сообщение отредактировал Пётр - Воскресенье, 27 Февраля 2011, 14:15
 
DEMBELДата: Воскресенье, 27 Февраля 2011, 14:17 | Сообщение # 9
Наш дизайнер
Группа: Модераторы
Сообщений: 2266
Репутация: 135
Награды: 32
Статус: Offline
а можешь сделать плаг с функциями описанными здесь? (выкл компа, сон, киллпроцесс, отруб. инет)?



Win7x64 SP1 Neobook v5.70 (Trial)
WinXP SP3 Neobook v5.62
 
ПётрДата: Воскресенье, 27 Февраля 2011, 16:21 | Сообщение # 10
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Quote (DEMBEL)
а можешь сделать плаг с функциями описанными
Смотри вложение.
Для завершения системных процессов (обычных не касается), нужно чтобы программа получила привилегии отладчика. Для этого необходимо однократно вызвать функцию EnableDebugPrivilege(), но для этого обязательно нужно запустить прогу с правами админа. В случае успеха, она вернет число 1. :)

А с функцией BSOD() нужно быть по осторожнее, а то появится "синий экран смерти"! :D

Прикрепления: MiskPlugin.rar (21.7 Kb)


Сообщение отредактировал Пётр - Воскресенье, 27 Февраля 2011, 16:22
 
DEMBELДата: Воскресенье, 27 Февраля 2011, 16:37 | Сообщение # 11
Наш дизайнер
Группа: Модераторы
Сообщений: 2266
Репутация: 135
Награды: 32
Статус: Offline
разрыв связи с инетом не пашет, LAN, w7x64. как именно гасится инет? по моему, нужно похимичить, чтобы пахало на всех типах подключения. сперва вычислить устройство, ответственное за инет, потом отключить его, так?



Win7x64 SP1 Neobook v5.70 (Trial)
WinXP SP3 Neobook v5.62
 
ПётрДата: Воскресенье, 27 Февраля 2011, 16:48 | Сообщение # 12
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Сейчас разрывается соединение, поднимаемое виндой.
Чтобы отключить инет по LAN, нужно либо блокировать сетевой трафик (или фильтровать его) или отключать сетевую карту.
 
DEMBELДата: Воскресенье, 27 Февраля 2011, 17:19 | Сообщение # 13
Наш дизайнер
Группа: Модераторы
Сообщений: 2266
Репутация: 135
Награды: 32
Статус: Offline
ну вот, надо отключать и для lan. выбрать нужное сетевое устроиство (с навешенным ip) и грохнуть его.



Win7x64 SP1 Neobook v5.70 (Trial)
WinXP SP3 Neobook v5.62
 
ПётрДата: Воскресенье, 27 Февраля 2011, 22:21 | Сообщение # 14
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Пример плагина, упаковывающего и распаковывающего ZIP архивы, т. ч. и защищённые паролем.
Он создан на основе библиотеки PureZIP.
Библиотека довольно мощная и позволяет работать не только с обычными архивами, но и с самораспаковывающимися (запросто можно создать свой аналог WinRARа) но многие функции будет сложно "подружить" с MMB, скажем, слабо представляю как можно передать в MMB структуру, описывающую упакованый файл (там дата создания файла, модификации, имя, размеры упакованного и нет, CRC и многое другое).

Пока что пример.

Прикрепления: Example_ZIP_Arc.rar (91.3 Kb)


Сообщение отредактировал Пётр - Воскресенье, 27 Февраля 2011, 22:58
 
ПётрДата: Понедельник, 28 Февраля 2011, 23:07 | Сообщение # 15
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Плагин для работы с USB HID устройствами.
Пример взаимодействует с USB устройством, созданным на микроконтроллере ATmega8, схема устройства и прошивка для микроконтроллера (файл, "USB_Termo.hex" в папке "Bascom" архива "USB_Termo_ATmega8.rar") прилагается.
Прикрепления: MMB_HID_Plugin.rar (67.7 Kb)
 
DEMBELДата: Понедельник, 28 Февраля 2011, 23:32 | Сообщение # 16
Наш дизайнер
Группа: Модераторы
Сообщений: 2266
Репутация: 135
Награды: 32
Статус: Offline
zip крутой, а сеть lan сделаешь чтоб отключалось? :)



Win7x64 SP1 Neobook v5.70 (Trial)
WinXP SP3 Neobook v5.62
 
ПётрДата: Понедельник, 28 Февраля 2011, 23:56 | Сообщение # 17
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Quote (DEMBEL)
а сеть lan сделаешь чтоб отключалось
Если напишешь как, может сделаю.
Я не сталкивался с такой задачей.
 
ПётрДата: Четверг, 19 Апреля 2012, 15:48 | Сообщение # 18
Новый участник
Группа: Пользователи
Сообщений: 15
Репутация: 0
Награды: 0
Статус: Offline
Подниму ка я тему.
Вот плагин для работы с потами компа. Проверен и нормально работает на Windows x86 2000, XP, 7.
В отличии от уже имеющихся на форуме, аналогичных плагинов, этот отличается тем, что не использует библиотеки-посредники, типа inpout32.dll или аналогичные, а сам является такой библиотекой и непосредственно обращается к драйверу pbdriverio.sys.
Во вложении есть сам плагин, примеры использования (работа с LPT портом и получение температуры процессора) и исходники плагина. Их кстати, можно использовать как основу если хотите понять как работать с драйверами режима ядра ОС.

А для особо любознательных, выкладываю исходники драйвера режима ядра pbdriverio.sys в месте с DDK и др. файлами, необходимыми для компиляции драйвера.
Прикрепления: pbdriverio_MMB_.zip (22.4 Kb) · __pbdriverio.zip (83.1 Kb)
 
  • Страница 1 из 1
  • 1
Поиск: