RUS  ENG 

Как сделать плагин. Руководство.

Страницы: 1 2 3 4 След.
RSS
Как сделать плагин. Руководство.
 
Здравствуйте!
Будьте добры, опишите общую последовательность действий для создания плагина. Я не профессиональный программист, а в справке разъясняются частные вопросы, из них сложить общую картину мне непросто. И на каком языке лучше писать, чтобы было эффективно, но и не увязнуть? С программированием знаком. Сейчас начал осваивать Visual Basic, но не проблема потратить немного больше времени на изучение языка, чтобы потом сподручнее решить основную задачу.
И ещё объекты и константы в справке не систематизированы, просто перечислены по алфавиту - попробуй-ка удержи всё это многообразие в голове. Хорошо бы сгруппировать как-то.
Заранее спасибо.
 
О создании плагинов подробно описано здесь: http://politerm.com/zuludoc/plugin_about.htm
Если возникнут конкретные вопросы, пишите.
Модули можно писать можно на любом языке, который позволяет создавать плагины (Visual Basic, Delphi, C++, C#)
Объектная модель представлена в виде диаграммы http://politerm.com/zuludoc/objectmodel.htm
 
Это я видел и вдумчиво читал. Но именно общей картины не получилось, потому и спрашиваю. Напишите, что нужно сделать, по шагам.
У меня пример "Отравляющие вещества" грузится с ошибкой, говорит: "[путь примера]/zb.dll не может загрузиться, продолжить загрузку проекта?" Пробовал копировать этот длл из корня Зулу в папку с примером - результат тот же.
 
Пример был старый для Zulu 5.0 Обновите. Заодно можно скачать совсем простой пример плагина, где минимум необходимых методов. ConnectZuluPlugin DisconnectZuluPlugin и вызов команды OnCommand1 http://politerm.com/zulu/samples/CustomBrowse.rar
 
Справка по внутреннему устройству программы больше похожа на технический справочник. Весьма неплохой, но неполный.
В примерах пояснения крайне лаконичны и их мало, или их вообще нет.
И справка и примеры годятся только для опытных программистов, простому человеку разобраться, что к чему, в высшей степени проблематично. Даже в совсем простом примере плагина мало что понятно, т.к. всё равно без понимания логики построения программы ничего понять в принципе нельзя, даже если я могу написать простенькую программу на VB.
Я биолог.
Я, конечно, могу изучить вдоль и поперёк диаграмму объектной модели Zulu со всеми потрохами и сложить из этой кучи цельную систему, но это займёт очень много времени. И поэтому я обращаюсь к вам, как к знающим людям.
А вы вместо нормальных объяснений на человеческом языке отсылаете меня к какому-то разделу, где описаны отрывки из обрывков, и ничего не понятно в целом (хотя я упоминал, что заглядывал в справку).
Ну и как, много будет пользы от такой вашей "помощи"? Скорее, так вы отобъёте всякую охоту пользоваться вашей программой. Ну, или общаться с вами (всё равно толку нету). Сами свой ответ на мой вопрос почитайте.
А ведь в ваших интересах сделать программу и справку такой, чтобы их использование было максимально эффективным. Так может, всё-таки попробуете мне объяснить, что к чему? Заодно и обратную связь получите.
 
У желающих написать плагин разный порог вхождения. От "все понятно" до "ничего не ясно". Перерабатывать в данный момент руководство не планируем. Поэтому проще задавать конкретные вопросы. На них готовы ответить. Пишите пожалуйста на почту [email protected] и сообщите телефон для связи.
 
Предлагаю всё-таки вести дискуссию здесь, т.к. эта информация понадобится тем, кому "ничего не ясно".
Конкретный вопрос: с чего начать создание плагина?
 
Сперва нужно определиться со средой разработки. На чем будете писать?
 
visual basic
 
Ekolog, в зависимости от решаемой задачи, плагин:
1. Должен выполнять какой-либо линейный код, получая данные от системы и выдавая результат пользователю. Тогда плагин лучше выполнить в виде библиотеки ActiveX, предоставляющей для этого COM-объект (OLE Automation Object). Это простой вариант.
2. Должен предоставить пользователю некоторую форму, встроенную в систему Zulu, с которой пользователь будет взаимодействовать. Форма является основной частью функционирования плагина. Тогда плагин можно оформить в виде библиотеки элементов ActiveX, и форма плагина должна быть выполнена в виде элемента ActiveX (OLE Control).
3. Осуществляет развитое взаимодействие с системой и пользователем, предоставляет группы команд меню и панелей инструментов, внедряет рабочие окна в систему (наподобие окон Сообщения, Рабочее место и т.п.). В данном случае плагин реализуется (в нашем случае, используя Visual Basic) в виде библиотеки ActiveX (как в первом случае), однако размещение плавающих/докируемых окон, форм и т.п. программируется вручную.
 
Затрудняюсь сказать, какой из этих трёх вариантов мне нужен. Скорее, 2й или 3й. Мне нужно сделать блок расчётов, для которого нужно будет указать объект на экране, преобразовать его, внести (через форму) дополнительные данные и подключить данные внешние (база данных, но для начала можно и вручную через форму вносить), после чего сделать расчёт и представить его графически (тематическая раскраска). Что-то похожее на ваш пример "отравляющие вещества", только другой расчёт и нужно брать данные с объектов карты.

И ещё скажите, как разрезать полилинию в заданной точке (не обязательно в вершине)? Кроме как вырезать полигоном ничего не нащёл.
 
1. В Вашем случае имеет смысл остановиться на 2-м варианте. Уточните c какой версии Visual Studio Вы работаете ?
2. Можно в режиме выделения узлов выделить точку разреза на полилинии и вставить узел (см. politerm.com/zuludoc/edit_elem_insert_node.htm)
 
Microsoft Visual Basic 6.0
Программно разрезать, Douser, программно. Тыкнуть мышкой примерно в линию и этим её разрезать на две максимально близко в точке тычка. И получить координаты точки разреза (лежащие на исходной полилинии).
 
В таком случае, отталкиваясь от выбора второго варианта, можно создать плагин, который позволит внедрить в Zulu какую-либо внешнюю форму. В нашем случае форма будет реализована в виде элемента Activex (ActiveX Control).
1. В Visual Basic Вам нужно создать новый проект. Тип проекта - ActiveX Control
2. Сделайте первоначальный дизайн формы (UserControl), скомпилируйте проект, зарегистрируйте (можно с помощью утилиты regsvr32.exe) и протестируйте, что форма благополучно внедряется в какие-либо контейнеры. Когда во всем убедились форма готова внедряться в Zulu.
3. Чтобы Zulu узнала, что есть такой модуль, и что этот модуль - плагин и что его можно в себя подключить нужны две вещи: первое - модуль должен разместить информацию о себе в Реестре и второе - модуль должен иметь определенные точки входа, чтобы Zulu могла с ним взаимодействовать.
4. Поэтому, нужно создать раздел в Реестре, как это сказано в politerm.com/zuludoc/plugin_about.htm#_plugin_register, задать, что с плагином Zulu должна связываться через COM, для этого указать ProgID созданного UserControl'а. В нашем случае Zulu сама разберется, что это не просто COM-объект, а ActiveX Control, и при загрузке плагина создаст плавающую панель с внедренным туда Вашим UserControl. Это нам и нужно.
5. В сам UserControl добавьте пару методов - ConnectZuluPlugin и DisconnectZuluPlugin (см. politerm.com/zuludoc/plugin_connect.htm). Плагин почти готов работать.
6. Чтобы пользователь мог вызвать появление Вашей формы нужна команда. Пользователь должен выбрать пункт меню или кнопку панели инструментов. Поэтому в разделе Реестра, посвященного Вашему плагину добавим подраздел Commands и добавим команду ShowForm. Задайте читабельное название команды (оно появится в пользовательском интерфейсе системы), описание как описано в politerm.com/zuludoc/plugin_commands.htm.
7. Так как команда нужна по сути только для вызова формы, можно не добавлять дополнительного метода в UserControl, а задать поведение формы с помощью раздела ControlBar (см. politerm.com/zuludoc/plugin_controlbar.htm) и задать параметр ShowHideCommand, указывая нашу команду, добавленную на предыдущем шаге.
8. Теперь можно протестировать в Zulu. Для этого в Zulu выберите команду Сервис - Выполнить и выберите Вашу команду из п.6.

Описанные шаги я оформил в виде проекта Visual Basic 6.0 по адресу: www.politerm.com/download/zulu/samples/plugins/vb/SimpleFormPlugin.rar
 
Цитата:
Microsoft Visual Basic 6.0
Тыкнуть мышкой примерно в линию и этим её разрезать на две максимально близко в точке тычка. И получить координаты точки разреза (лежащие на исходной полилинии).

Отдельной функции, которая разбивала бы объект, если где-то рядом тыкнуть, нет. Программно сейчас можно, например, так для автономного приложения (для плагина аналогично):


Private Sub MapCtrl1_OnMouseLeftDblClick(ByVal State As ZuluOcx.eMouseState, ByVal X As Long, ByVal Y As Long, ByVal RealX As Double, ByVal RealY As Double)

Dim ID, i As Long
Dim Pt As ZPoint
Dim El As Element
Dim L As Layer
Dim M As MapDoc
Dim Pl, Pl1 As PolyLine
Dim Ppl As PolyPolyLine
Dim Geom As ZGeometry

Set Geom = New ZGeometry

Set M = MapCtrl1.Map
Set L = M.Layers.Active

Set Pt = New ZPoint

'Получаем ID объектa, ближайшего к тычку мыши в пределах пяти пикселей экрана и точку на нем
ID = L.GetClosestElementByXY(RealX, RealY, 5 * M.Active.MapScale, False, Pt)

If ID <> -1 Then

'Получаем объект
Set El = L.Elements.GetElement(ID)

'Проверяем, что объект линейный
If El.GraphType = eGraphTypePrimPolyline Or El.GraphType = eGraphTypeTypedPolyline Then

Set Ppl = El.PolyPolyLine

'Проверяем, что объект состоит из одной полилинии (не составной)
If Ppl.Count = 1 Then

Dim Idx As Long

Idx = -1

'Получили геометрию объекта в виде полилинии
Set Pl = Ppl.Item(0)

'Проверяем, не совпал ли тычок мыши с вершиной
For i = 1 To Pl.NumTops

If Pt.X = Pl.GetX(i) And Pt.Y = Pl.GetY(i) Then

'Запомнили номер вершины разбиения
Idx = i

Exit For

End If

Next i

'Если вершины не совпали с тычком мыши, ищем отрезок, ближайший к тычку
If Idx = -1 Then
For i = 1 To Pl.NumTops - 1

Dim D, D1, D2 As Double

D = Geom.Distance(Pl.GetX(i), Pl.GetY(i), Pl.GetX(i + 1), Pl.GetY(i + 1))
D1 = Geom.Distance(Pl.GetX(i), Pl.GetY(i), Pt.X, Pt.Y)
D2 = Geom.Distance(Pl.GetX(i + 1), Pl.GetY(i + 1), Pt.X, Pt.Y)

'Сравниваем длину отрезка ломаной с суммой расстояний от точки до его концов
If (D1 + D2 - D) < 2 Then

'Если разницы длин меньше 2 сантиметров (для сантиметровой точности), вставляем в ломаную новую точку
Pl.InsertPoint Pt.X, Pt.Y, i + 1

'Запомнили номер вершины разбиения
Idx = i + 1

Exit For

End If

Next i
End If

'Если вершина разбиения есть и не является концом ломаной
If Idx > 1 And Idx <> Pl.NumTops Then

Dim St As ElemStyle

Set St = El.ElemStyle

Set Pl1 = New PolyLine

'Создаем новую полилинию для разбиваемого объекта
For i = 1 To Idx

Pl1.AddPoint Pl.GetX(i), Pl.GetY(i)

Next i

'Перезаписываем старый объект
El.SetPolyLine Pl1

Pl1.Clear

'Создаем полилинию для нового объекта (вторую часть результата разбиения)
For i = Idx To Pl.NumTops

Pl1.AddPoint Pl.GetX(i), Pl.GetY(i)

Next i

'Добавляем новую полилинию
L.AddPolyLine Pl1, St, El.TypeID, El.ModeId

End If

End If

End If

End If

End Sub
 
Douser, Lyosha, благодарю, буду разбираться.
Не совсем понял функцию GetClosestElementByXY: какую точку она выдаёт как retPoint? Точку с координатами ближайшей из вершин полилинии?
 
GetClosestElementByXY выдает точку на полилинии, ближайшую к заданной точке. Т.е. если ткнуть где-то в середину отрезка, то там точка и будет на отрезке в середине.
 
Нда, перечитываю справку и нахожу там знакомые слова. Когда читал всё это в первый раз (разы), то из-за большого количества сжатой специфической информации, разбитой по разделам, да в сочетании со специфической терминологией, в голове образуется каша.
После объяснения Douser`а последовательности действий (в т.ч. выбор типа проекта) появилось понимание что к чему. Похоже, меня сбила с толку страница справки "Подключение модуля" - запутался, что подключать и как это друг с другом должно быть связано.
Только почему в справке метод подключения выглядит как
Public Function ConnectZuluPlugin(Connector As IPluginConnector) As Boolean
а у вас в примере
Public Function ConnectZuluPlugin(conn As Object) As Boolean
?
И где взять ProgID?
 
И ещё. Насколько я понял, команды в реестре нужно прописывать только для того, чтобы Зулу могла их использовать напрямую, без вызывания окна модуля. Т.е. если их не прописывать в реестре, то из формы самого плагина они всё равно работать будут?
И про SetEventSink тоже не ясно, как это работает. Раздел справки пустой.
 
Как я понял, SetEventSink - это метод IPluginConnector, включающий / выключающий передачу событий из Зулу в плагин. Me=вкл, Nothing=выкл.
А OnZuluEvent принимает коды событий. Только не совсем понятно, как этим методом пользоваться.
 
Ekolog, добрый день!
SetEventSink подключает объект-приемник событий от Zulu. В примере таким объектом является сама форма. При возникновении события вызывается метод OnZuluEvent объекта-приемника. Код события содержится в параметре EventID (см. набор констант politerm.com/zuludoc/zuluax/eZuluEvents_enum.htm)
 
День добрый!
Вставляю в форму примера SimpleFormPlugin кнопку и лейбл, добавляю код

Private Sub Command1_Click()

Dim aDoc As Document
Dim Map As MapDoc

Set aDoc = Zulu.ActiveDocument

If Doc.Type = eMapDoc Then
Set Map = aDoc.NativeDoc
Label1.Caption = Map.Layers.Active.UserName
End If

End Sub

Не работает! Выдаёт ошибку 424, Object required!

Что не так? Код взят из справки с одним исправлением. Открыта карта с одним слоем.
 
Добрый день! Возможно объект Zulu у Вас нигде не описан и не получен от Connector.
 
Разобрался. В выражении Set aDoc = Zulu.ActiveDocument пропущен объект Connector, т.е. должно быть вот так:
Set aDoc = Connector.Zulu.ActiveDocument

Видимо, Вы это мне и сказали, но я почему-то никак не могу связать вашу фразу с этим смыслом :(

Теперь другой вопрос: при попытке запустить ещё одну форму функцией Form_2.Show Зулу выдаёт сообщение "ошибка 406. Non-modal forms cannot be displayed in this host application from an ActiveX DLL, ActiveX Control , or Property Page"
Возможно каким-либо образом открыть ещё одну форму из плагина? Или нужно обходиться только одной формой?
 
почему-то не работают функции вида
Set newCheckbox = Controls.Add("VB.checkbox", ControlName, Form1)
ошибка "Type mismatch"
Возможно ли программно вставлять чекбоксы по количеству слоёв в карте?
Страницы: 1 2 3 4 След.