Просмотр полной версии : Создание ActiveX компонента для MasterSCADA.
Добрый день.
Я всё глубже и глубже погружаюсь в изучение MasterSCADA.
Дошёл до создания ActiveX компонентов. Сделал пару простеньких всё отлично не работает.
Сейчас делаю кое что посложнее. Возникает несколько вопросов. Очень охота получить на них ответы.
Постараюсь описать ситуацию как можно подробнее.
Компонент представляет из себя комбоБокс и текстБокс.
У компонента 4 свойства
[DispId(1),
DisplayName("Список компонентов")]
public string Components
{
get { return componentsPath; }
set { componentsPath = value; }
}
[DispId(2),
DisplayName("Файл настроек")]
public string Settings
{
get { return settingsPath; }
set { settingsPath = value; }
}
[DispId(3),
DisplayName("Содержимое")]
public string Contets
{
get { return componentsCB.Text; }
set { componentsCB.Text = value; }
}
[DispId(4),
DisplayName("Время выгрузки")]
public string OpenTime
{
get { return openTimeTB.Text; }
set { openTimeTB.Text = value; }
}
1-е свойство - путь к файлу из которого будет загружаться Items комбоБокса
2-е свойство - путь к файлу в котором храниться конфигурация компонента
(тут остановимся подробнее. Компонент размещаем на мнемосхеме которая вызывается по умолчанию. На сколько я понял, когда я запускаю СКАДУ в рантайм, компонент создаётся заново. Т.е. он не видит значения своих свойств. Вызывается private void InitializeComponent(). Конструируются все контролы компонента.
Вызывается событие Load. В нём я читаю файл конфигурации. Т.е. какое значение было выбрано в комбоБоксе, и что написано в текстБоксе.
При изменении комбоБокса или текстБокса их содержимое сохраняется в файл конфигурации.)
3-е свойство - выбранный элемент комбоБокса - я хочу использовать ДИНАМИЗАЦИЮ для этого свойства. Хочу видеть в одной из переменных проекта ВЫХОД.
4-е свойство - содержимое текстБокса - я хочу использовать ДИНАМИЗАЦИЮ для этого свойства. Хочу видеть в одной из переменных проекта ВЫХОД.
т.е. я хочу использовать первые два свойства только для настройки, а вторые два - только для получения ВЫХОДА с них.
Как всё происходит на самом деле.
Я добавляю этот компонент в проект. Заполняю 1-е и 2-е свойства. 3-е и 4-е оставляю пустыми.
Открываю динамизацию выходов этого компонента. Связываю выход 3-го свойства с переменной Команда3.
ЗАПУСКАЮ проект.
По началу в комбоБоксе ничего не выбрано. В переменной Команда3 нет значения.
Разворачиваю комбоБокс - в нём элементы из файла указанного в 1-м свойстве (всё правильно).
Я выбираю какой-нибудь из элементов. Переменная Команда3 становится равна этому элементу. При этом в файле из 2-го свойства отражается изменения выбранного элемента. (всё правильно)
Теперь я ОСТАНАВЛИВАЮ скаду.
И снова ЗАПУСКАЮ.
Содержимое комбоБокса грузится из файла 1. Выбранный элемент грузится из файла 2. Т.е. комбоБокс отображается так как я и хочу.
НО в переменной Команда3 НИЧЕГО НЕТ.
Если я щелкну по комбоБоксу и выберу какой-нибудь элемент, переменная Команда3 начинает отображать значение.
Я так понял что переменной присваивается значение при вызове геттора 3-го свойства
[DispId(3),
DisplayName("Содержимое")]
public string Contets
{
get { return componentsCB.Text; }
set { componentsCB.Text = value; }
}
Хотелось бы его узнать когда он вызывается, и как его можно вызвать насильно?
Надеюсь кто-нибудь дошёл до конца и ответит мне на мои вопросы.
Правильно ли я объявил свойства?
Одинаково ли я должен объявить те свойства для которых я хочу использовать динамизацию и те для которых не хочу?
Когда первый раз после запуска скады первый раз вызывается геттер свойства моего компонента?
Могу ли я вызвать этот геттер насильно? или какие мероприятия я ещё могу провести для того чтобы при запуске проекта в переменной Команда3 я видел текст из комбоБокса?
Спасибо.
SCADAMaster
26.04.2012, 12:59
Вообще судя по описанию, контрол который вы сделали похож на ФБ "Выбор строки" из закладки "Работа с архивов" палитры ФБ. Может быть вам этот фб подойдет и ничего писать не надо?
По вашему вопросу - может быть вам просто связать команду с входом "Содержимое", и у команды установить "Восстановление при рестарте". Тогда команда будет устанавливать в поле введенное в последний раз значение.
SCADAMaster, ты красавчик!
Спасибо, "восстановление при рестарте" отлично подошло.
Но как-то это странно. Было бы неплохо, если бы MasterSCADA прочитывала бы все выходы всех блоков при запуске.
А вопрос про правильность объявления свойств. Могу ли я создать компонент у которого какие-то свойства доступны только из вкладок Динамизация входов, динамизация выходов.
И ещё, у любого свойства обязательно объявить и геттер и сеттер, или для свойств для которых я не хочу динамизировать вход я могу сеттер не объявлять?
Вообще судя по описанию, контрол который вы сделали похож на ФБ "Выбор строки" из закладки "Работа с архивов" палитры ФБ.
Вы имеете ввиду ФБ "Список строк"?
Мы пробовали его. Не очень понравился. Как-то он не очень удобен в эксплуатации. Приспосабливаться к нему надо.
К тому же, компонент о котором речь шла в первом работает совместно с текстБоксом. И при выборе чего-то в комбоБоксе запоминает выбор в файл.
Этот файл в другом месте используется.
У меня есть ещё один вопрос. Он немного оффтоп, но спрошу тут.
У нас есть демоверсия MasterSCADA. Мы разрабатываем проект на ней. Не будет ли у нас трудностей с переносом проекта на MSRT-500?
SCADAMaster
26.04.2012, 13:36
А вопрос про правильность объявления свойств. Могу ли я создать компонент у которого какие-то свойства доступны только из вкладок Динамизация входов, динамизация выходов.
Нет, так нельзя.
И ещё, у любого свойства обязательно объявить и геттер и сеттер, или для свойств для которых я не хочу динамизировать вход я могу сеттер не объявлять?
Должно быть можно. Можете попробовать.
Мы пробовали его. Не очень понравился. Как-то он не очень удобен в эксплуатации. Приспосабливаться к нему надо.
А чем именно не понравился? Там можно настроить - запретить ввод или удаление (через свойства контрола). Путь к файлу тоже задается, поэтому его можно использовать из других программы
У нас есть демоверсия MasterSCADA. Мы разрабатываем проект на ней. Не будет ли у нас трудностей с переносом проекта на MSRT-500?
Если не превышено количество точек, и не задействованы не приобретенные модули то нет. Не будет.
После завершения проекта у системы, на закладке "Общие" нажмите "Сформировать опции для заказа" у убедитесь что MSRt500 вам достаточно.
Ваши собственные библиотеки нужно будет перенести на этот компьютер и зарегестрировать. Как регистрировать без студии описано в документации по разработке ФБ.
Вот ещё один случай проблемы которую я описал в первом посте.
Делаю своеобразный аналог кнопки с фиксацией.
Компонент представляет из себя pictureBox, который обрабатывает событие Click. И при щелчке изменяет отображаемую картинку.
В классе компонента сделал объявления
private string imageOnPath; //Путь к изображению которое должно быть показано, если state == true
private string imageOffPath; //Путь к изображению которое должно быть показано, если state == false
private bool state; //Если нажата - TRUE; Не нажата - FALSE;
Код компонента привожу почти полностью
[DispId(1),
DisplayName("Изображение OFF")]
public string ImageOFF
{
get { return imageOffPath; }
set { imageOffPath = value; }
}
[DispId(2),
DisplayName("Изображение ON")]
public string ImageON
{
get { return imageOnPath; }
set { imageOnPath = value; }
}
[DispId(3),
DisplayName("Кнопка нажата")]
public bool BtnState
{
get { return state; }
set { state = value; }
}
//Происходит при щелчке по картинке
private void pictureBox_Click(object sender, EventArgs e)
{
state = !state;
if (state == false)
{
pictureBox.ImageLocation = imageOffPath;
}
else
{
pictureBox.ImageLocation = imageOnPath;
}
}
//При загрузке компонента должен считываться state, и загружаться нужное изображение
private void ButtonExControl_Load(object sender, EventArgs e)
{
if (BtnState == false)
{
pictureBox.ImageLocation = ImageOFF;
}
else
{
pictureBox.ImageLocation = ImageON;
}
}
В СКАДЕ создал переменную Команда1. Сделал ей "Восстановление при рестарте". Подал её на Выход и на Вход динамизации компонента.
запускаю СКАДУ, щёлкаю на компонент. меняется картинка. Команда1 становится ИСТИНА.
Останавливаю СКАДУ. Запускаю СКАДУ. Команда1 ИСТИНА, но компонент отображает картинку которую должен отображать если вход ЛОЖЬ. Т.е. не читает при запуске входа.
Щёлкаю по кнопке один раз. Картинка не меняется, Команда1 становиться ЛОЖЬ. (всё правильно). Щелкаю второй раз. Команда1 стаёт ИСТИНА, Картинка меняется. При следующих остановах-запусках скады, та же печаль.
Как быть? Как заставить компонент прочитать входы при запуске?
SCADAMaster
28.04.2012, 09:20
А чем вас не устраивает контрол дискретной команды - кнопка?
У него тоже можно рисунок назначить на состояние. И фиксацию можно включить.
SCADAMaster
28.04.2012, 09:30
Может быть вот так попробовать:
[DispId(1),
DisplayName("Изображение OFF")]
public string ImageOFF
{
get { return imageOffPath; }
set { imageOffPath = value; }
}
[DispId(2),
DisplayName("Изображение ON")]
public string ImageON
{
get { return imageOnPath; }
set { imageOnPath = value; }
}
[DispId(3),
DisplayName("Кнопка нажата")]
public bool BtnState
{
get { return state; }
set {
if (value == false)
{
pictureBox.ImageLocation = ImageOFF;
}
else
{
pictureBox.ImageLocation = ImageON;
}
}
}
//Происходит при щелчке по картинке
private void pictureBox_Click(object sender, EventArgs e)
{
state = !state;
if (state == false)
{
pictureBox.ImageLocation = imageOffPath;
}
else
{
pictureBox.ImageLocation = imageOnPath;
}
}
}
В компоненте "Кнопка с фиксацией" В качестве изображения можно использовать только файлы в формате .bmp. Нельзя уйти от прямоугольной формы кнопки.
Мне нужно чтобы у меня была округлая красивая кнопка, с прозрачным фоном.
Для этого я хочу сделать свой компонент и использовать в нём .png файлы.
Стандартный компонент "Рисунок" может отображать .png. Можно было бы использовать его, но он не обрабатывает события нажатие.
Сделал почти по вашему. Только добавил присвоение в конец. На то он и сеттер)
[DispId(3),
DisplayName("Кнопка нажата")]
public bool BtnState
{
get { return state; }
set {
if (value == false)
{
pictureBox.ImageLocation = ImageOFF;
}
else
{
pictureBox.ImageLocation = ImageON;
}
state = value; }
}
Вообщем наблюдается такая ситуация. С переменной проекта Команда1 всё заработало правильно.
Но если использовать на входе и на выходе ОРС тег, всё по старому.
Есть конечно выход. Добавить в проект переменную Значение1. Связать Значение1 с ОРС тегом. На ВХОД динамизации компонента подать переменную Значение1. А на ВЫХОД динамизации компонента связать с ОРС тегом.
Тогда всё работает так как мне надо. Но это как-то странно) Или я хочу странного?
На сколько я понял Load вызывается (компонент загружается) до того как СКАДА присваивает входам значения.
Опять оффтоп: выскажу пожелание.
Есть стандартный компонент "Мультфильм".
В него можно загрузить несколько изображений и он их последовательно воспроизводит когда вход Работа принимает значение ИСТИНА.
Вот например, хочу я отрисовать анимацию открытия клапана. Есть у меня рисунков штук пять. Использовать вход Работа нельзя. Потомучто он будет крутить анимацию бесконечно. Мне же надо чтобы он при появлении признака воспроизвёл картинки в порядке 1-2-3-4-5, а при исчезновении в порядке 5-4-3-2-1.
Это ничего. Я просто пишу ST в котором перебираю картинки при появлении признака на входе. И в компонент "Мультфильм" на вход подаю номер отображаемого кадра.
Довольно удобно.
Но мне опять хочется использовать красивую картинку с прозрачным фоном. Компонент "Мультфильм" видит .png файлы, но когда добавляешь .png файл с прозрачным фоном, он заменяет фон на ЧЁРНЫЙ!.
Приходится перегонять .png в .jpg. Делать например зелёный фон, и в компоненте "Мультфильм" устанавливать цвет прозрачности. При этом хоть фон и становится прозрачным, но края изображения неровные получаются.
Выход: Использовать для анимации компонент "Рисунок". Назвать файлы "valve001", "valve002" и так далее. И на ST писать блок у которого на выходе строка с именем файла.
В принципе нормально. Но хотелось бы как-нибудь попроще.
SCADAMaster
28.04.2012, 10:11
Стандартный компонент "Рисунок" может отображать .png. Можно было бы использовать его, но он не обрабатывает события нажатие.
Можно перекрыть его сверху контролом "Зона выбора" - данный контрол появляется у события, если вытащить правой кнопкой мыши. Можно задать фиксацию
Перекрываете данным контролом ваш рисуноков, а через входы динамизации меняете состояние рисунка.
Но если использовать на входе и на выходе ОРС тег, всё по старому.
Есть конечно выход. Добавить в проект переменную Значение1. Связать Значение1 с ОРС тегом. На ВХОД динамизации компонента подать переменную Значение1. А на ВЫХОД динамизации компонента связать с ОРС тегом.
Так и нужно делать. Мы не советуем связывать ОРС переменные с элементами мнемосхемы напрямую - это затрудняет тиражирование. Лучше создавать в дереве вспомогательные элементы (значения, повторители, команды).
На сколько я понял Load вызывается (компонент загружается) до того как СКАДА присваивает входам значения.
Попробуйте использовать метод Paint.
Можно перекрыть его сверху контролом "Зона выбора" - данный контрол появляется у события, если вытащить правой кнопкой мыши. Можно задать фиксацию
Перекрываете данным контролом ваш рисуноков, а через входы динамизации меняете состояние рисунка.
Я делал что-то подобное когда делал красивую кнопку без фиксации. Брал рисунок, накрывал его сверху "Кнопкой объекта".
Но опять же, что это вообще ""Зона выбора" - данный контрол появляется у события, если вытащить правой кнопкой мыши".
Всё что нужно - сделать такой компонент в которой можно загрузить любую картинку, в том числе .png, и у которого не будет никаких рамок. У компонента должен быть выход который реагирует на нажатие. И свойство, в котором можно задать нужно фиксировать выход, или нет.
Возможно имеет смысл сделать свойства "Изображение", "Изображение2", как у "Кнопки с фиксацией".
SCADAMaster
28.04.2012, 10:43
Но опять же, что это вообще ""Зона выбора" - данный контрол появляется у события, если вытащить правой кнопкой мыши".
Добавляете в объект "Событие" тащите его на мнемосхему правой кнопкой мыши, выбираете "Зона выбора", появится прозрачная рамка. При щелчке на нее в режиме исполнения на выходе события будет "Вкл". В свойствах рамки можно задать фиксацию.
Да я понял всё. Попробовал.
Я имел ввиду что это не удобно.
SCADAMaster
28.04.2012, 13:14
А чем неудобно? Тиражировать сложно?
Это можно легко решить. Создаете объект, у него создаете изображение на изображение кладете "Выбор изображения" и "Зона выбора" от события. Настраиваете динамизацию.
Теперь можно этот объект тиражировать и вытаскивать на мнемосхему изображение.
Пример в приложении
Спасибо. Сейчас посмотрю.
Мы очень ценим вашу оперативность и желание помочь.
Тут вы меня убедили. Будем пользоваться вариантом, который вы предлагаете.
Но всё равно, я так и не понял как сделать AciveX который будет работать так, как я хочу. В последнем варианте на котором мы сошлись тоже есть проблемы. Иногда (довольно часто), происходит следующие: я нажимаю на мою кнопку. Меняется изображение, меняется значение в ОРС, и тут же, очень резко компонент видимо прочитывает ВХОД из переменной Значение1, которая не успела ещё обновиться из ОРС. Переменная state компонента опять меняет значение, меняется картинка. ВЫХОД идёт в ОРС.
SCADAMaster
28.04.2012, 14:48
Вообще тут правильнее привязать и вход и выход динамизации на команду, и команду уже передавать в ОРС.
А для получения данные от ОРС использовать обратную связь.
Не понял. Что значит использовать обратную связь?
Нужно просто установить связь между командой и ОРС? Или ещё что-то нужно сделать?
SCADAMaster
03.05.2012, 08:47
Что значит использовать обратную связь?
У команд на закладке "Опрос выхода" есть поле "Обратная связь", в это поле можно перетащить выход ФБ или ОРС переменную.
Спасибо. Ваш совет опять помог.
Ещё вопрос по пользовательским ActiveX компонентам.
Я делаю компонент, у которого много свойств. Для каждого свойства задаю уникальные DispIdAttribute, DisplayNameAttribute. Причем DispIdAttribute даю по порядку (для первого свойства 1, для второго 2, для n-того - n).
Когда добавляю компонент в SCADA, его свойства располагаются в каком-то совершенно непонятном порядке. и не о алфавиту. И не по DispIdAttribute.
Знаете ли вы в каком порядке расположились свойства? Как мне расположить их в том порядке, в котором я хочу?
посоветуйте пожалуйста.
SCADAMaster
05.05.2012, 09:15
Если переключить в тулбаре панели свойств на режим без категорий и обратно, то включается сортировка внутри категорий.
Мы сделали, чтобы теперь изначально была сортировка внутри категорий.
В контроле можно в начало имени дописывать номер
01 CвойствоA
02 СвойствоB
Мы сделали, чтобы теперь изначально была сортировка внутри категорий.
Т.е. в новой версии так будет?
Было бы очень полезно.
А у меня подоспел ещё один вопрос.
Я разрабатываю свой ActiveX компонент на компьютере под Windows XP.
У окон и кнопок установлен "Стиль ХР".
Т.е. в Visual Studio всё выглядит красиво и современно.
Когда я добавляю компонент в SCADA, он приобретает "Классический стиль". Почти классический. Почему то background потемнее кажется.
Возможно ли как-нибудь изменить стиль окон и кнопок MasterSCADA, или хотя бы моих ActiveX компонентов?
И ещё есть у меня вопрос по отчётам.
Мы сформировали несколько отчётов.
Я умею открывать отчёт по нажатию кнопки. Но так получается, что для каждого отчёта мне нужна своя кнопка?
Можно ли как-нибудь с помощью одной кнопки осуществлять переход на разные отчёты. Например, название отчёта я мог бы выбирать из списка, или комбобокса.
Как-то сумбурно объяснился. Надеюсь вы меня поняли.
SCADAMaster
12.05.2012, 20:52
Можно ли как-нибудь с помощью одной кнопки осуществлять переход на разные отчёты. Например, название отчёта я мог бы выбирать из списка, или комбобокса.
Для каждого отчета создаете "событие", на закладке "Действие" создаете действие типа "открыть" и привязываете его к нужному отчету.
В формуле прописываете чтобы событие включилось когда нажата кнопка и выбран нужный номер в списке отчетов, примерно так:
номер=1 И кнопка_нажата=истина
SCADAMaster
13.05.2012, 09:05
Т.е. в Visual Studio всё выглядит красиво и современно.
Когда я добавляю компонент в SCADA, он приобретает "Классический стиль". Почти классический. Почему то background потемнее кажется.
У нас отключено свойство отображения стилей Visual Studio из-за некорректного отображения одного из контролов, но сейчас проблема решена.
Возможно мы снова включим отображения стилей в версии 3.5.
Спасибо) С отчётами разобрались. Сделали фильтры. Всё отображается. Всё красиво. Всё функционально. Генератор отчётов очень нам понравился. Все наши фантазии удалось воплотить в жизнь.
Возможно мы снова включим отображения стилей в версии 3.5.
Очень ждём. Было бы отлично. А ещё лучше чтобы можно было самому задавать стиль отображения окна (наверное некоторые хотят чтобы скада выглядела построже).
Подскажите пожалуйста, как переносить ActiveX компоненты на другой компьютер (Windows 7) без установки VisualStudio.
После копирования компонента его нужно зарегистрировать в системе. с помощью regsvr32. для облегчения можно добавить к реестру примочку
REGEDIT4
[HKEY_CLASSES_ROOT\.dll]
"Content Type"="application/x-msdownload"
@="dllfile"
[HKEY_CLASSES_ROOT\dllfile]
@="Dynamyc Link Library"
"AlwaysShowExt"=""
"EditFlags"=hex:01,00,00,00
[HKEY_CLASSES_ROOT\dllfile\DefaultIcon]
@="C:\\WINDOWS\\SYSTEM\\shell32.dll,-154"
[HKEY_CLASSES_ROOT\dllfile\Shell]
[HKEY_CLASSES_ROOT\dllfile\Shell\Register]
[HKEY_CLASSES_ROOT\dllfile\Shell\Register\Command]
@="regsvr32 %1"
[HKEY_CLASSES_ROOT\dllfile\Shell\UnRegister]
[HKEY_CLASSES_ROOT\dllfile\Shell\UnRegister\Command]
@="regsvr32 /u %1"
[HKEY_CLASSES_ROOT\.ocx]
"Content Type"="application/x-msdownload"
@="dllfile"
[HKEY_CLASSES_ROOT\ocxfile]
@="ActiveX Component"
[HKEY_CLASSES_ROOT\ocxfile\DefaultIcon]
@="C:\\WINDOWS\\SYSTEM\\shell32.dll,-154"
[HKEY_CLASSES_ROOT\ocxfile\Shell]
[HKEY_CLASSES_ROOT\ocxfile\Shell\Register]
[HKEY_CLASSES_ROOT\ocxfile\Shell\Register\Command]
@="regsvr32 %1"
[HKEY_CLASSES_ROOT\ocxfile\Shell\UnRegister]
[HKEY_CLASSES_ROOT\ocxfile\Shell\UnRegister\Command]
@="regsvr32 /u %1"
в контекстном меню проводника появяться команды для регистрации DLL и OCX файлов
SCADAMaster
30.05.2012, 09:17
Для этого нужно сделать bat файл который запускается файл netreg.
Посмотрите в документации по созданию ФБ на C# - там это описано.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot