RUS  ENG 

Подключение событий zulu в плагине

Страницы: 1
RSS
Подключение событий zulu в плагине
 
Доброе утро!
При разработке плагина на c# у меня возникла следующая проблема с подключением функции приема событий от zulu.
Подключение происходит с помощью функции SetEventCallback(), где параметром идет указатель на метод
в виде делегата: Marshal.GetFunctionPointerForDelegate(my_delegate)
Вроде бы все подключилось, но ловит события постоянно с EventID=0, что не нормально(
В другом случае, при подключении с помощью функции SetEventSink сообщения не ловит, в параметре
передавал интерфейс, но думаю что надо было не это...
Может кто нибудь сталкивался с такимим проблемами, надеюсь на помощью, заранее спасибо!
 
Добрый утро! Скажите, а как формируется делегат my_delegate? Это статический метод ? Напишите пример кода, чтобы можно было повторить под отладчиком и посмотреть что происходит.
И еще: возможно, чтобы не мучаться с делегатами, лучше воспользоваться методом SetEventSink, куда подставляется объект, поддерживающий IDispatch.
 
Douser, да, статический метод:
namespace ActiveXZulu
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public partial class MainForm : UserControl,IZuluMain
{
private Dfor_event my_delegate=new Dfor_event(OnZuluEvent);
public static int OnZuluEvent(int EventID,object source,object param1, object param2, object param3)
{
//smth code
return 1;
}
public int ConnectZuluPlugin(object Conn)
{
this.zulu_map=(IPluginConnector)Conn;
this.zulu_map.SetEventCallback((int)Marshal.GetFunctionPointerForDelegate(my_delegate));
return 1;
}
}
delegate int Dfor_event(int EventID,object source,object param1, object param2, object param3);
}

Попробовал с SetEventSink:
public int ConnectZuluPlugin(object Conn)
{
this.zulu_map=(IPluginConnector)Conn;
this.zulu_map.SetEventSink(new MainForm());
return 1;
}
public static int OnZuluEvent(int EventID,object source,object param1, object param2, object param3)
{
//smth code
return 1;
}
События не принимаются....
 
УРРРААА, спасибо!!! получилось с SetEventSink, только метод без static....вот теперь проблема с событиями, как я понимаю лучше методом научного тыка отлавливать в слепую нужные EventId, плюс по ходу для большего отсева ставить условие на требуемый интерфейс!?
 
Посмотрите
www.politerm.com.ru/zulu5doc/zuluax/eZuluEvents_enum.htm
Плюс в Object Browser'е можно посмотреть Zulu.eZuluEvents
 
Цитата:
Попробовал с SetEventSink:
public int ConnectZuluPlugin(object Conn)
{
this.zulu_map=(IPluginConnector)Conn;
this.zulu_map.SetEventSink(new MainForm());
return 1;
}
public static int OnZuluEvent(int EventID,object source,object param1, object param2, object param3)
{
//smth code
return 1;
}
События не принимаются....

А можно чуточку по подробнее про подключения обработки событий на C# а то не воспринимается у меня события.
 
Я так понимаю что никто так и не собирается ответить подробнее.
Спрошу по другому. что не так??
IZuluMain такого интерфейса нет есть IZuluEvents
Написал так
public partial class MainForm : Form,IZuluEvents

Переопределил OnZuluEvent
public void OnZuluEvent(int EventID,object source,object param1, object param2, object param3)
{
MessageBox.Show("" + EventID);
}


При загрузке формы
m_conn.SetEventSink(this);

В конструкторе забираю переменные из другова класса пока не случился Disconnect
m_mapdoc = ZuConnect.m_mapdoc;
m_app = ZuConnect.m_app;
m_conn = ZuConnect.m_conn;

Код класса в котором соединяемся с ZULU
public class ZuConnect
{

public MainForm form;
public static Zulu.IPluginConnector m_conn;
public static Zulu.IZulu m_app;
public static MapDoc m_mapdoc;

public bool ConnectZuluPlugin(object conn)
{
m_conn = conn as Zulu.IPluginConnector;
m_app = m_conn.Zulu;
return true;
}

public void DisconnectZuluPlugin()
{
m_app = null;
m_conn = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}

public void OpenForm()
{

Zulu.IDocument document;
document = m_app.ActiveDocument;

if (document != null && document.Type == eDocType.eMapDoc)
{
m_mapdoc = document.NativeDoc as ZuluLib.MapDoc;
form = new MainForm();
form.Show();
}
}
}

События не ловаться.
 
Necrolog, пришлите, пожалуйста пример плагина, который можно было скомпилировать и запустить, чтобы понять что не так.
Адрес: [email protected] (Дмитрий Озеров). Спасибо.
 
Спасибо за ответ разобрались.
Хотелось бы чтобы в описание констант eZuluEvents
Появилось поле значение константы в hex виде.
А то вылавливать руками что за оно очень не удобно =)
Благо для делфи кое-что описано...
 
Douser, хотелось бы и мне разъяснить, что да как с событиями (тот же С# и тоже не перехватывает). А то прямо ореол секретности!
Если всё заработает, то обещаю решение выложить на форум, пусть все интересующиеся, посмотрят.
С Вашего позволения посылаю Вам по почте "огрызки" модуля, который должен перехватывать события.
 
Начну с того, что модуль реализован так:
Функции подключения, отключения модуля реализованы в одном классе, а форма аддона в другом. Форма не является компонентом ActiveX.
Вызывающая функция, по которой должна появляться форма :

public void ShowAddonForm()
{
if (Connector != null)
{
if (Fform == null)
{
Connector.Lock();
Fform = new MainForm();
Fform.FormClosed += Fform_FormClosed;
Connector.SetEventSink(Fform);
Fform.Show();
}
}
}

То есть, чтобы "подключиться" к событиям Zulu я использовал метод SetEventSink(). Передавал в качестве параметра ссылку на форму. В классе формы заботливо поставил параметр [ComVisible(true)]. Да и в свойствах проекта - "Сделать сборку видимой для COM"
Следует обратить внимание на то, что перед вызовом конструктора формы вызывается метод Lock(), объекта типа IPluginConnector. И это очень важно, иначе просто вызовется DisconnectZuluPlugIn и никакие события приниматься не будут.
Форма должна реализовывать интерфейс IZuluEvents.
Ну соответственно метод, показывающий ID выделенного объекта в слое и реализующий OnZuluEvent:

public void OnZuluEvent(int EventID, object Source, object Param1, object Param2, object Param3)
{

if (EventID == (long)eZuluEvents.evMapObjectSelect)
{
MessageBox.Show(Param2.ToString());

}

}

Для того, чтобы после закрытия формы произошло уменьшение счетчика блокировок IPluginConnector, в классе модуля описываю реакцию на событие закрытие формы (хотя по правильному можно и к другому какому-то событию привязаться):

void Fform_FormClosed(object sender, FormClosedEventArgs e)
{
Connector.Unlock();
}

Вот такая общая концепция, после реализации которой, модуль на C# начинает реагировать на события Zulu.
Надеюсь кому-нибудь да пригодиться.
Неоценимую помощь в понимании общего алгоритма оказал <b>Douser</b>. Спасибо ему большое!
 
lihach, спасибо, по вашей инструкции все получилось!
Страницы: 1