+7 (495) 9-555-137 info@cals.ru

Описание API

Введение в API PSS

Одной из важнейших возможностей системы PDM STEP Suite является возможность доступа к ее базе данных с помощью библиотеки функций (API). Используя API системы PDM STEP Suite можно без особого труда в кратчайшие сроки разработать специализированные приложения отточенные для решения конкретных задач предприятия, что позволяет значительно расширить функциональность системы и повысить эффективность ее использования.

Вся работа с данными выполняется с использованием класса СaplStepData (CaplNetStepData). Данный класс является объектной оберткой для стандартного интерфейса доступа к данным (SDAI) регламентированного стандартом ISO 10303-24 (ГОСТ Р ИСО 10303-24). С помощью методов данного класса можно выполнить любые операции с данными. Методы данного класса универсальны и не зависят от используемой схемы данных.

Обратной стороной универсальности методов класса CaplStepData является громоздкость программного кода использующего данный класс. Для упрощения работы с данными в API PSS предусмотрены специальные классы — Менеджеры. Это специализированные наборы методов для работы с определенными информационными объектами (менеджер категорий, менеджер изделий и т.д.). Использование менеджеров значительно снижает требования к знанию разработчика стандарта STEP, и умению работать с объектно-ориентированными базами данных.

Все менеждеры используют для работы класс СaplStepData. (Для того чтобы использование менеджера стало возможным экземпляр его класса необходимо, используя метод Attach, ассоциировать его с экземпляром CaplStepData. Такая ассоциация должна выполняться после каждой установки соединения с базой данных (функция Connect).)

Использование класса CaplStepData и менеджеров возможно только из Visual C++. Для доступа к данным PSS из других средств разработки используется ActiveX компонент AplStepManagerX. Данный компонент представляет предоставляет досуп к методам класса CaplStepData и менеджеров через ActiveX интерфейс. Данный компонент устанавливается и регистрируется вместе с системой PDM STEP Suite и входит во все варианты поставки, включая демонстрационную версию.

Следует заметить, что использование технологии ActiveX значительно замедляет работу с данными, поэтому для разработки приложений, быстродействие которых критично, желательно использовать класс CaplStepData и менеджеры.

Подробное описание способов использования элементов ActiveX следует смотреть в руководстве той среды разработки, которую Вы используете.

Интерфейс доступа к данным системы PDM STEP Suite

  1. Общие сведения об объектной модели данных
  2. Пример низкоуровневого интерфейса
  3. Функции для работы с хранилищем
  4. Высокоуровневый интерфейс

Высокие темпы развития компьютерной техники, существующие в настоящее время, приводят к компьютеризации все более новых отраслей человеческой деятельности. С ростом производительности вычислительных средств увеличивается и сложность решаемых ими задач, а значит, и сложность используемых моделей данных. Широко распространенные в настоящее время реляционные модели, ориентированные на машинное представление данных, уже не позволяют описать реальный мир с необходимым уровнем детализации. На смену реляционным методам моделирования приходят объектно-ориентированные, которые изначально предназначены для описания не машинного, а реального мира. Однако простота информационного моделирования в терминах объектно-ориентированного анализа оборачивается усложнением обработки объектных данных. Объектно-ориентированной методологии, адекватной реляционной алгебре, в настоящее время не существует. Тем не менее, богатые возможности обработки объектных данных заставляют мириться со сложностями и искать новые пути использования объектов.

Одной их областей, использующих довольно сложные информационные модели, является управление машиностроительным производством, основой для которого служит описание сложного изделия управляемой конфигурации. Современное высокотехнологическое изделие уже давно не определяется только статической геометрией. Оно может изменяться во времени, иметь громадное число модификаций и вариантов комплектации, и его можно описать с различных точек зрения различным числом взаимосвязанных моделей. Сложность описания высокотехнологического изделия настолько велика, что разработка стандарта на электронное представление данных об изделии ISO 10303 (STEP) потребовала создания специального объектно-ориентированного языка информационного моделирования – EXPRESS (ISO 10303-11). Данный язык оказался настолько удачным, что его стали использовать в целом ряде далеких от машиностроения прикладных областях. Кроме того, в настоящее время его описание переведено на русский язык и выпущено как российский стандарт ГОСТ Р ИСО 10303-11.

1. Общие сведения об объектной модели данных

Информационная модель (словарь данных) на языке EXPRESS состоит из объектов (ENTITY) и их атрибутов (ATTR) (Рис. 1) . В качестве значений атрибутов могут выступать как значения простых типов (INTEGER, REAL, STRING, BOOLEAN и т.д.), так и ссылки на экземпляры других объектов. Кроме того значения атрибутов могут быть списками (ARRAY, SET, LIST и BAG) других значений. Между объектами могут устанавливаться отношения наследования как единичного, так и множественного. Экземпляры объектов INSTANCE, которые могут объединяться в группы, называемые EXTENT. Каждый INSTANCE имеет свой уникальный идентификатор, который определяет не только атрибуты данного экземпляра, но и его тип.

Рис. 1. Взаимосвязь объектов словаря и данных

Язык EXPRESS имеет как текстовую, так и графическую нотацию. Графическая более удобна для восприятия человеком, но не позволяет отобразить все аспекты модели данных. В текстовой нотации можно описать не только модель данных, но и ограничения целостности данных и правила проверки их корректности. В некотором смысле текстовое описание модели данных на языке EXPRESS аналогично заголовочному файлу в программе на C++. Они определяют объекты, их атрибуты и связи между объектами. Например:

Описание на языке EXPRESS Аналог на C++
class point {
ENTITY point; public:
x : INTEGER; int x;
y : INTEGER; int y;
END_ENTITY; }
ENTITY color_point {
SUBTYPE OF (point); public:
color : STRING; char * color;
END_ENTITY; }
ENTITY 3d_point {
SUBTYPE OF (point); public:
z : INTEGER; int z;
END_ENTITY; }
class line {
ENTITY line; public:
p1 : point; point *p1;
p2 : point; point *p2;
END_ENTITY; }

В графической нотации, называемой EXPRESS-G, объекты отображаются в виде прямоугольников, внутри которых указывется имя объекта (рис.2). Атрибуты обозначаются тонкими линиями с именем атрибута и кружком на конце линии рядом с типом атрибута, в качестве которого могут выступать другие объекты или условные обозначения простых типов. Отношения наследования отображаются жирными линиями и кружком рядом с объектом — потомком.

Рис. 2. Модель данных в нотации EXPRESS-G

Следует заметить, что в данных примерах приведены только самые общие моменты информационного моделирования на языке EXPRESS, возможности которого гораздо богаче. Эти возможности настолько обширны, что далеко не все схемы данных, описанные на нем, можно напрямую транслировать в С++.

Для работы с элементами словаря данных в API системы PSS используются специальные классы:

Объект Используемый класс
ENTITY CaplEntity
ATTR CaplAttr
INSTANCE CaplInstance
ATTRVALUE CaplAttrValue
VALUE CaplValue

2. Пример низкоуровневого интерфейса

Низкоуровневый API системы PSS представляет собой реализацию SDAI для языка С (ISO 10303-24). Для удобства работы функции данного стандарта обернуты в оболочку (класс CaplStepData), а у части функций устранен ряд параметров (например, идентификатор сессии, который не передается функции, а берется ей из класса-оболочки. У функций отсутствует префикс sdai (принадлежность функций к низкоуровневому API видна не за счет префикса, а за счет принадлежности классу CaplStepData). Для удаленной работы с базой данных в API системы PSS существует класс CaplNetStepData, который наследует функциональность CaplStepData и дополняет ее сетевыми функциями (Connect, Disconnect, SaveChanges и др.). Все функции работающие с сетью имеют префикс «NET_».

Все функции SDAI используют понятие идентификатора. Каждый экземпляр объекта имеет свой уникальный идентификатор, присваиваемый ему при создании. Для создания объекта используется функция CreateInstanceBN, которой передается имя создаваемого объекта (имя ENTITY), а возвращает она указатель на класс CaplInstance, поле «id» которого содержит идентификатор созданного экземпляра объекта (INSTANCE).

Задавать значение атрибутов любого INSTANCE можно с помощью функции sdaiPutAttrBN, а читать с помощью функции GetAttrBN. Этим функциям передается идентификатор INSTANCE, имя атрибута и адрес памяти по которому считывется значение (PutAttrBN) или в который записывается значение (GetAttrBN). Обе функции возвращают код ошибки или ноль в случае корректного выполнения. Удаляет объекты функция DeleteInstance, единственным параметром которой является идентификатор удаляемого INSTANCE. Для любого INSTANCE с помощью функции IsKindOfBN, которой передается идентификатор, можно узнать, является ли его тип наследником другого типа объекта и имя типа. Получить список экземпляров объектов (instance) определенного типа можно с помощью функции GetEntityExtentBN, передав ей имя ENTITY. Данная функция возвращает список INSTANCE как переданного ей типа, так и его потомков. Вот, пожалуй, и весь минимальный набор функций, необходимых для работы с объектно-ориентированными данными без привязки к какой-либо схеме данных.

Описание всех перечисленных функций в языке СИ будет выглядеть следующим образом:

CaplInstance *CreateInstanceBN (const char *type_name);
// создает Instanсе типа type_name
bool DeleteInstance (CaplInstance *inst);
// удаляет inst из БД
bool GetEntityExtentBN (const char *ent_name, aplExtent &extent);
// возвращает в extent набор Instance типа ent_name
bool GetAttrBN (CaplInstance *inst, const char *attr_name, CaplValue *value);
// возвращает в value значение атрибута attr_name взятого у inst
bool PutAttrBN (CaplInstance * inst, const char *attr_name, CaplValue value);
// записывает в inst значение value как значение атрибута attr_name
bool IsKindOfBN (CaplInstance *inst, const char *type_name);
// возвращает true если inst является экземпляром типа

Использование SDAI можно проиллюстрировать на следующем примере:

В базе данных, построенной по вышеописанной модели (см. рис.2) необходимо все цветные точки сместить влево по оси X на 5, а все остальные точки, находящиеся выше прямой Y=3, сместить вверх на 7. Программа, выполняющая данную операцию, имеет вид:

#include <aplNetStepData.h> // включение описания функций SDAI

int i=0; // счетчик
int x,y; // координаты
aplExtent ext; // массив для всех точек
CaplInstance *inst; // идентификатор INSTANCE
CaplStepData data; // класс для работы с данными INSTANCE
data.LoadFromFile(“data.stp”); // открытие файла сданными
data.GetEntityExtentBN(“point”,&ext); // чтение списка всех точек
for(i=0 ;i<ext.GetSize();++i) // цикл по i-м элементам списка
{
    inst=ext[i]; // получение i-го элемента списка
    if(data.IsKindOfBN(inst,”colorpoint”)) // i-я точка является цветной
    {
        data.GetAttrBN(inst,”x”, &x); // чтение координаты x для i-й точки
        x-=5; // смещение точки влево по оси X на 5
        data.PutAttrBN(inst,”x”, x); // запись новой координаты x для i-й точки
    }
    else // i-я точка не является цветной
    {
        data.GetAttrBN(inst,”y”, &y); // чтение координаты y i-й точки
        if(y>3) // если точка выше Y=3
        {
            y+=7; // смещение точки вверх по оси Y на 7
            data.PutAttrBN(inst,”y”,y); // запись новой координаты y i-й точки
        }
    }
}
data.sdaiSaveChanges(); // сохранение изменений (завершение транзакции)

В данной программе помимо проверок на ошибки используется большое число строковых операций. Каждое чтение атрибута или проверка на тип приводит к поиску переданного имени атрибута в словаре. Однако каждому элементу словаря данных в классе CaplStepData соответствует экземпляр определенного класса (CaplEntity или CaplAttr). Ссылки на экземпляры данных классов можно использовать вместо задания имен объектов, а получить их можно с помощью функций:

CaplEntity *GetEntityBN (char *name);
// получение ENTITY по его имени
CaplAttr *GetAttrDefinitionBN(char *entity_name, char *attr_name);
// получение идентификатора атрибута по его имени и имени ENTITY.
CaplAttr *GetAttrDefinition(CaplEntity *entity, char *attr_name);
// получение идентификатора атрибута по его имени и элементу словаря.

Вызывать данные функции можно только после открытия файла с данными или установки соединения с базой данных.

Большая часть функций SDAI существуют в двух вариантах: для использования элементов словаря и для использования их имен. Функции использующие имена заканчиваются на BN (By Name), а функции использующие идентификаторы таких окончаний не имеют.

При использовании идентификаторов вместо имен приведенная выше программа будет иметь вид:

#include <aplNetStepData.h> // включение описания функций SDAI

int i=0; // счетчик
int x,y; // координаты
aplExtent ext; // массив для всех точек
CaplInstance *inst; // идентификатор INSTANCE
CaplStepData data; // класс для работы с данными INSTANCE
data.LoadFromFile("data.stp"); // открытие файла сданными

// получение элементов словаря
CaplEntity *ent_point=data.GetEntityBN("point"); // идентификатор объекта point
CaplEntity *ent_colorpoint= data.GetEntityBN("color_point"); // идентификатор объекта color_point
CaplAttr *a_point_x= data.GetAttrDefinition(ent_point, "x"); // идентификатор атрибута x
CaplAttr *a_point_y= data.GetAttrDefinition(ent_point, "y"); // идентификатор атрибута у

data.GetEntityExtent(ent_point, &ext); // чтение списка всех точек
for (i=0 ; i<ext. GetSize( ); ++i) // цикл по i-м элементам списка
{
    inst=ext[i]; // получение i-го элемента списка
    if(data.IsKindOf(inst, ent_colorpoint)) // i-я точка является цветной
    {
        // чтение координаты x i-й точки
        data.GetAttr(inst, a_point_x, &x);
        x-=5; // смещение точки влево по оси X на 5
        // запись новой координаты x i-й точки
        data.PutAttr(inst, a_point_x, x);
    }
    else // i-я точка не является цветной
    {
        // чтение координаты y i-й точки
        data.GetAttr(inst, a_point_y, &y);
        if(y>3) // если точка выше Y=3
        {
            y+=7; // смещение точки вверх по оси Y на 7
            // запись новой координаты y i-й точки
            data.PutAttr(inst, a_point_y, y);
        }
    }
}
data.SaveChanges(); // сохранение изменений (завершение транзакции)

Вариант программы использующий идентификаторы будет работать гораздо быстрее за счет сокращения числа строковых операций выполняемых в цикле. Но это только один аспект быстродействия SDAI­-программ. Другим, не менее важным аспектом является способ работы в сети. Если для чтения или записи каждого атрибута каждого объекта обращаться к базе данных через сеть, то это приведет к значительным накладным расходам. Более удобно считывать или записывать сразу по несколько значений атрибутов. Такую работу можно довольно легко организовать используя механизмы кэширования данных на клиенте.

3. Функции для работы с хранилищем

Для работы с базой данных по сети в API PSS существует класс CaplNetStepData являющийся потомком CaplStepData.

Для работы с удаленной базой данных необходимо установить соединение с помощью функции NET_Connect(…). При установке соединения на клиенте создается кэш данных. Все изменения (функции PutAttr, CreateInstance и DeleteInstance) проводятся в кэше аналогично работе с файлом. Сохранение изменений в БД происходит при вызове функции NET_SaveChanges(). Разрыв связи осуществляется с помощью функции NET_Disconnect(). При разрыве связи все изменения, произошедшие после последнего вызова NET_SaveChanges(), теряются.

Чтение данных функциями GetAttr и GetEntityExtent осуществляется из кэша. Если установить режим автоматической докачки данных (по умолчанию он выключен) вызовом функции SetAutoDownloadMode(true), то при чтении атрибута (функция GetAttr) его значение будет при отсутствии в кэше закачено к кэш. Работать в таком режиме не рекомендуется, так как он сильно снижает быстродействие.

Данные могут быть закачены в кэш принудительно с помощью класса СaplLoadData, но в большинстве случаев этого не требуется, так как все функции высокоуровневого API PSS (менеджеров) все необходимые данные закачивают в кэш автоматически. Например, после вызова функции получения состава изделия все атрибуты всех входящих в изделие компонент будут закачены в кэш.

4. Высокоуровневый интерфейс

Для удобства работы в API PSS существует класс CaplAPI, который инкапсулирует в себе экземпляры класса источника данных (CaplNetStepData) и все менеджеры. Данный класс содержит функции Connect() и Disconnect(), которые помимо установки (разрыва) связи инициализируют все менеджеры, ассоциируя их с содержащимся в CaplAPI источником данных.

При использовании класса CaplAPI каркас приложения выглядит следующим образом:

#include <apl_api.h> // включение заголовочного файла API PSS
...
CaplAPI api; // Создание экземпляра класса PSS API
if ( !api.Connect() ) return error;
CaplInstance *prd,*pdf; // Выбор версии изделия из БД
pdf= api.m_prd_mgr.SelectInstance(APL_MODE_SELECT_PDF); // Проверка на ошибку
if ( pdf==0 ) return error;
CString id,ver;
CaplInstance ; // Чтение атрибута у выбранной версии изделия
api.m_data.GetAttrBN(pdf, "of_product", prd); // Чтение атрибута у полученного по версии изделия
api.m_data.GetAttrBN(prd, "id", id);
AfxMessageBox(id); // Вывод сообщения с обозначением изделия
...
api.Dissconnect(); // Разрыв соединения

Создание модулей расширения

В системе PDM STEP Suite существует возможность подключать к модулю PDM расширения (plug-in) разработанные сторонними разработчиками. Такой модуль представляет собой DLL, содержащую множество функций, вызываемых из контекстных меню объектов или основного меню приложения. Для подключения к системе такая DLL должна соответствовать ряду требований:

  1. Содержать экспортируемую функцию с именем «GetFunctionList», возвращающую информацию о встраиваемых функциях.
  2. Содержать встраиваемые функции, поддерживающие определенные параметры.
  3. Корректно работать с собственными ресурсами (это требование касается всех DLL, а не только модулей расширения PSS).

Установка модулей в систему

Для подключения модуля расширения путь к нему необходимо прописать в текстовом файле «psm.add», находящемся в каталоге системы PSS (как правило, в C:\Program Files\PSS). В каждой строчке данного файла должен содержаться путь только к одному модулю. Если модуль расширения находится в каталоге системы PSS, то допускается указывать только имя файла без пути к нему.

Параметры функции «GetFunctionList»

При инициализации модуля расширения в нем вызывается функция «GetFunctionList», которая должна вернуть информацию о встраиваемых функциях. Данная функция должна  быть указана в экспортном списке def и иметь следующий вид:

__declspec(dllexport) bool GetFunctionsList(CArray<CaplItemInfo*, CaplItemInfo*> *strArray);

Функция «GetFunctionList» должна возвращать в strArray массив экземпляров класса CaplItemInfo: class CaplItemInfo
{ public:
aplAddInItemType m_type // равен aplPopUp всегда
CString m_treeItemType // тип элемента дерева
CString m_menuName // строка вида "[позиция] имя пункта меню"
CString m_functionName //имя функции
int m_funcParamType // тип параметров функции
int m_image // иконка для пункта меню
CString m_description //Описание пункта меню
};

type — тип элемента массива. В настоящее время поддерживается только один тип: aplPopUp (элемент меню).

treeItemType – тип элементов дерева объектов, в контекстное меню которых добавляется вызов функции. Например, если этот параметр равен “Product”, то в контекстное меню для изделий будет добавлен пункт с именем m_menuName. Если параметр не задан (пустая строка), пункты добавляются в главное меню модуля PDM. Допустимые значения параметра:

Значения параметра Тип в дереве объектов
Categories Категория
Folder Папка
Product Изделие / Версия изделия
Document Документ/ Версия документа
Lot Партия изделия
PrdInst Экземпляр изделия
Characteristic Характеристика
BP Бизнес-процесс
BPRes Ресурс бизнес- процесса
Approval Статус
Activity Действие
Task Задание
ProcessTmpl Шаблон
Process Процесс

m_menuName — наименование меню. Представляет собой перечень разделенных символом ‘\’ наименований пунктов подменю, последний из которых (может быть единственный) — наименование пункта меню, при выборе которого будет вызвана функция m_functionName. Каждое наименование может начинаться с номера указанного в квадратных скобках. Данный номер определяет позицию, под которой будет добавлен пункт меню. Если номер равен -1 или указан некорректно, пункт меню добавляется в конец (если не указан, добавляется в начало). Если в имени меню указывается пустая строка, в меню добавляется разделитель и пункт m_functionName игнорируется. При обработке пунктов подменю, в исходном меню ищется подменю с заданным именем. Если такое подменю существует, то пункт меню добавляется в него, в противном случае подменю с таким именем создается. Пример наименования меню: "[13]Добавление\\Примеры\\[]Пример использования”.

m_functionName — имя функции, которая вызывается при вызове пункта меню m_menuName.

m_funcParamType — в данной версии не используется.

m_image — в данной версии не используется.

Формат функций в модуле расширения

В модуле расширения вызываемые функции должны быть объявлены следующим образом:

__declspec (dllexport) bool YourFunction(CaplAPI* api, aplExtent& ext, bool check);

api — указатель на основной класс пользовательского программного интерфейса, предоставляющий доступ к базе данных и менеджерам высокоуровнего API системы PSS.

ext — массив экземпляров объектов (Instance), определяющих элемент выделенный в дереве объектов модуля PDM.

check — флаг, который показывает, какая операция — обработка или обновление интерфейса — запрашивается из PSM. Если значение false — запрашивается обработка массива экземпляров объектов, если true — требуется возвратить доступность этой функции для массива экземпляров объектов (т.е. если функция вернет false — пункт меню будет недоступен, если true — доступен).

Все экспортируемые функции необходимо указать в списке экспортируемых функций в файле с именем [YourAddInProject].def

Подключение собственной закладки в «Панель навигатора» модуля PSM

В модуле PSM существует возможность подключения собственных закладок в «Панель навигатора». Для этих целей дополнение должно соответствовать следующим требованиям:

  1. Дополнение должно содержать экспортируемую функцию CreateTabViews, которая создает виды и проводит необходимую инициализацию и регистрацию закладки в модуле PSM.
  2. Дополнение должно содержать экспортируемую функцию GetTabViews, передающую данные об экспортируемых закладках.
  3. Базовым классом для класса закладки (вида) должен быть CView или производный от него.
  4. Для обмена информацией с модулем PSM вид должен обрабатывать сообщение, которое модуль передает при вызове функции CreateTabViews.

Параметры функции «CreateTabViews»

При инициализации модуля дополнения PSM вызывает экспортируемую функцию CreateTabViews, которая должна быть указана в экспортном списке def. В реализации функции необходимо создать один или несколько видов для отображения в «Панели навигатора» модуля PSM. Данная функция имеет следующий вид:

__declspec(dllexport) bool CreateTabViews(CWnd* parent, RECT rect, UINT msg, CaplAddinViews *views);

parent — указатель на родительское окно вида;

rect — размер вида;

msg — сообщение, которое используется для обмена данными между модулем PSM и видом дополнения.

views — указатель на переменную класса CaplAddinViews, который служит для регистрации пользовательских закладок в модуле PDM. Для регистрации закладок класс CaplAddinViews имеет в своем составе функцию AddView, которая имеет следующий вид:

void AddView(CView*view, DWORD type, int pos=-1, CString name="", CString descr="", bool show = true)

vew — указатель на класс регистрируемой закладки;

type — тип элементов дерева «Панели навигатора» модуля PSM, для которых должна отображаться закладка. Может принимать одно или совокупность значений из списка:

Значения параметра

Тип в дереве объектов

APL_CATEG_ITEM Категория
APL_CATEG_REVISION_ITEM Версия категории
APL_FOLDER_ITEM Папка
APL_PDF_ITEM Версия изделия
APL_PRD_ITEM Изделие 
APL_DOC_ITEM Документ
APL_DOC_REVISION_ITEM Версия документа
APL_CHARACT_ITEM Характеристика
APL_BP_ITEM Бизнес-процесс
APL_BP_REVISION_ITEM Версия бизнес-процесса
APL_ACTIVITY_ITEM Действие
APL_TASK_ITEM Задание
APL_PROCESS_TMPL_ITEM Шаблон
APL_PROCESS Процесс
APL_ORG_ITEM Организация 
APL_PERSON_ITEM Сотрудник

pos — позиция закладки в «Панели навигатора», куда будет вставлена закладка;

name — наименование закладки (отображается в «Панели навигатора» или диалоге настройки дополнений);

descr — краткое описание закладки (отображается в диалоге настройки дополнений);

show — флаг, который указывает отображать или нет закладку (данный параметр используется для настройки отображения закладки из диалога настройки дополнений и всегда должен принимать значение true).

После создания закладки необходимо вызвать функцию класса CaplAddinViews, которая регистрирует закладку в модуле PDM.

Пример функции создания закладки и ее регистрации в PSM

__declspec(dllexport) bool CreateTabViews(CWnd* parent, RECT Rect, UINT msg, CaplAddinViews *views)
{
if (parent==0) // если родительское окно не задано,ничего не делать.
CMyView* view = (CMyView*)(RUNTIME_CLASS(CMyView)->CreateObject()); // создание объекта
if (view ==0) return false ;// если объект не создан, то далее ничего неделать.
HINSTANCE hI = AfxGetResourceHandle (); // получить идентификатор экземпляра приложения PSM
AfxSetResourceHandle (module _instance); // установить свой идентификатор, для использования своих ресурсов.
view->Create(0, 0, 0, Rect, parent ,ID_VIEW,NULL); // создание вида
view->OnInitialUpdate (); // вызов функции начальной инициализации вида.
view->ShowWindow (SW HIDE); // спрятать окно вида (обязательно!).
view->m msg = msg; // передать сообщение для обмена информацией с PSM.
views->AddView(view, APL_PDF_ITEM, -1, "Наименование закладки", "Описание закладки"); // Регистрация закладки в PSM.
AfxSetResourceHandle (hI); // устанавливаем идентификатор экземпляра приложения PSM.
return true;
}

Параметры функции «GetTabViews»

Для настройки отображения закладок в диалоге настройки дополнений, используется экспортируемая функция GetTabViews, которая должна быть указана в экспортном списке def.

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

__declspec(dllexport) bool GetTabViews(CaplAddinViews *views)

где views — указатель на объект класса CaplAddinViews.

Пример реализации функции

__declspec(dllexport) bool GetTabViews(CaplAddinViews *views)
{
views->AddView(0, APL_PDF_ITEM, 0, "Наименование закладки", "Описание закладки.");
return true;
}

Обмен информацией между закладкой и модулем PSM

Для обмена информацией между PSM и закладкой используется сообщение, которое регистрируется при запуске модуля PSM и передается при вызове функции дополнения CreateTabViews (параметр msg).

Обновление информации в виде
Для обновления информации о выделенном объекте модуль PSM посылает закладке сообщение, в котором в качестве wParam будет задано значение APL_UPDATE_INST_ITEM — сообщение о необходимости обновить вид, а в качестве lParam — указатель на класс CaplUpdateItem.

Проверять значение wParam надо обязательно! Модуль PSM использует это сообщение также для внутреннего обмена информацией. Поэтому если такую проверку не проводить, возможно появление исключительных ситуаций, а также падение программы.

class CaplUpdateItem
{
public
CaplAPI* api; // указатель на текущий m_api (CaplAPI)
CaplInstance* inst; // указатель на выделенный в дереве PDM объект базы данных (CaplInstance*)
};

Для того чтобы обрабатывать данное сообщение в своем виде можно переопределить функцию WindowProc например так:

LRESULT CMyView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == m update msg) // если это наше сообщение,проверяем событие которое надо осуществить.
{
if (wParam == APL_UPDATE_INST_ITEM) // если это наше событие, преобразуем lParam в указатель на класс CaplUpdateItem и вызываем функцию, которая обновляет вид.
{
CaplUpdateItem* item = (CaplUpdateItem*)lParam;
UpdateTreeItem(item);
}
return 0;
}
else
return CFormView::WindowProc(message, wParam, lParam);
}
Обновление информации в дереве объектов PSM

Если в реализации вида производятся какие-либо изменения данных, то для обновления модуля PSM родительскому окну необходимо послать сообщение msg, у которого: 

- wParam — должно быть значение APL_UPDATE_DOC

- lParam — не используется и может быть любым.

Использование ресурсов в модуле расширения

Любая DLL, использующая ресурсы (диалоги, иконки и т.д.), должно использовать их так, чтобы не вступать в конфликт с ресурсами PSM.

Для управления  ресурсами в DLL обычно используют функции AfxGetResourceHandle и AfxSetResourceHandle. Перед использованием ресурсов DLL вызывают функцию  AfxSetResourceHandle и передают ей уникальный идентификатор (handle). После этого выполняют необходимые манипуляции с ресурсами DLL (например, вывод диалога или чтение из таблицы строк), а затем возвращают ресурсы в исходное положение.

Для упрощения использования ресурсов в модулях расширения PSS существуют две функции: SetResources и ResetResources. Перед использованием ресурсов необходимо вызвать SetResources, которая сохранит текущий источник ресурсов и переключит его на ресурсы DLL. После завершения работы с ресурсами необходимо вызвать ResetResources, которая источник ресурсов в исходное состояние.

Пример:

SetResources();
CMyDialog   dlg;
int res=dlg.DoModal();
ResetResources();
if (res==0) …

Пример модуля расширения

Модуль расширения можно создавать на основе каркасного приложения, которое находится в папке \PSS\developer\AddIn\aplAddIn на компакт-диске с дистрибутивом системы.

Все используемые структуры определены в файле «CommonClasses.h».