
- •Добавление к com-серверу поддержки событий
- •Создание модели взаимодействия приложения хоста с плагинами
- •Описание com-интерфейсов, связанных с поддержкой плагинов
- •Создание com-интерфейсов, связанных с поддержкой плагинов
- •Создание com-классов, связанных с поддержкой плагинов
- •Создание класса, отвечающего за взаимодействие с плагинами
- •Код класса Plugin.Cs
- •Внесение косметических изменений в серверную часть
- •Строим своё меню с плагинами и идентификаторами
- •Вносим изменения в главную форму сервера
- •Создание первого плагина
- •Импорт типов с сервера
- •Создание класса для хранения внутреннего представления точек
- •Создание форм редактирования данных о точках
- •Реализация форм редактирования данных о точках
- •Реализация класса первого плагина
- •Создание третьего плагина
- •Делаем наш плагин com-видимым
- •Создание главной формы плагина
- •Реализация класса третьего плагина
- •Создание инсталлятора для плагина
- •Создание второго плагина
- •Создание главной формы плагина
- •Создание библиотеки типов
- •Реализация формы второго плагина
- •Реализация класса второго плагина
- •Добавление метода GetComClassName
- •Data Execution Prevention и его отключение
- •Тестирование совместной работы клиента и плагинов
- •Исходный код
Реализация класса первого плагина
Реализуем класс плагина. Открываем файл ZigzagPlugin.cs. Если вы помните, то мы условились, что плагины в управляемом коде без COM-серверов должны содержать класс ZigzagPlugin, в котором должны быть все методы IPlugin. Проблема в том, что сейчас наш класс расположен в неймспейсе Plugin1. Удалите его упоминание в этом файле.
В принципе, наверняка его можно было тоже унаследовать от IPlugin, но я что-то затупил и обошелся даже без него.
Теперь можно писать класс. Добавим в него необходимые переменные.
/// <summary> Переменная, дающая доступ к серверу. </summary>
static ZigzagServer.IZigzagControl zigzagControl;
/// <summary> Список действий плагина. </summary>
static List<ZigzagServer.IPluginAction> actionsList;
/// <summary> Форма редактирования точек.. </summary>
static Plugin1.ZigzagEditorForm zigzagEditorForm;
Обратите внимание: так как этот класс работает по сценарию «Managed, без COM», то все методы, доступные через интерфейс IPlugin помечены как public static. Сам класс, кстати говоря, от IPlugin не наследуется.
Далее реализуем метод подключения:
/// <summary>
/// Осуществляет подключение плагина.
/// </summary>
/// <param name="iZigzagControl">Интерфейс IZigzagControl объекта ZigzagControl.</param>
/// <param name="iPluginConnectionInfo">Интерфейс IPluginConnectionInfo. Передавайте сюда object, плагин должен его инициализировать на своей стороне.</param>
/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>
public static int Connect(object iZigzagControl, ref object iPluginConnectionInfo)
{
try
{
zigzagControl = (ZigzagServer.IZigzagControl)iZigzagControl; // Сохраним переменную, дающую контроль над сервером.
actionsList = new List<ZigzagServer.IPluginAction>(); // Создадим список доступных из плагина действий.
actionsList.Add(new PluginAction(0, "Показать форму редактирования", "Отображает форму редактирования точек ломаной на экране")); // Добавим туда единственное действие.
iPluginConnectionInfo = new PluginConnectionInfo("Zigzag redactor", "Редактор точек ломаной", actionsList.ToArray()); // Зададим информацию о плагине через PluginConnectionInfo.
zigzagEditorForm = new Plugin1.ZigzagEditorForm(zigzagControl); // Создадим главную форму плагина.
return 0;
}
catch (Exception exc) // Если возникла какая-то ошибка, вернём код, отличный от нуля.
{
System.Windows.Forms.MessageBox.Show(exc.Message + "\r\n" + exc.StackTrace, "Exception occured");
return -1;
}
}
Тут всё очевидно из комментариев. Сначала мы копируем переменную ZigzagControl, затем создаём список доступных действий, создаём действия при помощи наших классов-наследников IPluginAction, создаём тем же образом PluginConnectionInfo и возвращаем его, инициализируем форму редактирования точек. Плюс обрабатываем возможные исключения.
Реализуем метод отключения плагина. В нём мы будем освобождать переменную сервера и уничтожать нашу форму:
/// <summary>
/// Метод отключения плагина от приложения-хоста.
/// </summary>
/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>
public static int Disconnect()
{
try
{
((IDisposable)zigzagControl).Dispose(); // Освободим переменную ZigzagControl, чтобы сервер мог уменьшить счётчик выданных COM-экземпляров.
zigzagControl = null;
zigzagEditorForm.Close(); // Уничтожим главную форму.
zigzagEditorForm.Dispose();
zigzagEditorForm = null;
}
catch
{ }
return 0;
}
И теперь реализуем метод выполнения запрошенного действия.
/// <summary>
/// Метод выполнения действия плагина. Вызывается приложением-хостом.
/// </summary>
/// <param name="actionId">Числовой уникальный идентификатор действия.</param>
/// <returns>Возвращает код ошибки или 0, если ошибок не было.</returns>
public static int PerformAction(int actionId)
{
switch (actionId)
{
case 0:
zigzagEditorForm.Show();; // Отобразим главную форму плагина.
return 0;
default:
return -1; // Действия с запрошенным actionId не существует. Такие дела.
}
}
Действие возможно только одно, потому метод небольшой.
Всё, первый плагин готов, можно строить и тестировать. Постройте проект плагина, запустите сервер, выберете в меню пункт «Connect plugin…» и укажите путь к нашей dll-ке. Если всё прошло гладко и плагин подключился, то в меню появился ещё один пункт. Через него мы можем открыть окно плагина и протестировать его. Удостоверьтесь, что он работает так, как вы хотите.