В этой статье:
Запуск и отображение Fore.NET-формы
Использование компонентов продукта «Форсайт. Аналитическая платформа»
Номер статьи: KB000021
Данная статья предназначена для ознакомления прикладных разработчиков с функциональными особенностями использования Fore.NET в «Форсайт. Аналитическая платформа». Также рекомендуется изучить документы:
Примечание. Разработка с использованием языка Fore.NET, как и при использовании Fore, должна производиться на тестовой схеме. Для синхронизации тестового и промышленного репозитория предназначен менеджер обновлений.
Первое и принципиальное отличие Fore.NET от Fore заключается в том, что Fore.NET заключён в объект «.NET сборка», то есть Fore.NET-модули и Fore.NET-формы можно создавать и использовать только внутри Fore.NET-сборок.
Рассмотрим простой пример. Откроем интегрированную среду разработки и из навигатора проекта создадим Fore.NET-сборку. В результате будет создано 2 объекта: непосредственно Fore.NET-сборка и Fore.NET-модуль «Program» со следующим кодом:
Imports System;
Public Class StartParams
Private m_Metabase: Prognoz.Platform.Interop.Metabase.IMetabase;
Public Property Metabase: Prognoz.Platform.Interop.Metabase.IMetabase
Get
Begin
Return m_Metabase
End Get
Set
Begin
m_Metabase := Value;
End Set
End Property Metabase;
End Class;
Public Class Program
[STAThread]
Public Shared Sub Main(Params: StartParams);
Begin
End Sub;
End Class;
Это отличается от того, что было в Fore.
Введём определение:
Точка входа в программу на языке Fore.NET - это опубликованный статический метод «Main» класса «Program» пространства имён <Идентификатор запускаемой .NET сборки>.
Точка входа имеет параметр типа StartParams, который содержит в себе ссылку на текущий репозиторий. Данная ссылка заменяет метод MetabaseClass.Active, который в Fore.NET недоступен из-за отсутствия в COM статических методов и свойств. Нужно отметить, что при создании Fore.NET-сборки в список ссылок автоматически добавляется ссылка на сборку «Metabase».
В Fore.NET есть несколько типов сборок: EXE, DLL. EXE в свою очередь разделяется на WindowsApplication и ConsoleApplication. По умолчанию Fore.NET-сборке при создании устанавливается тип DLL, что позволяет запускать её из навигатора объектов в текущем процессе «Форсайт. Аналитическая платформа», а также подключать Fore.NET-сборку по ссылке к другим Fore.NET-сборкам.
В отличие от обычной Fore-сборки сборку Fore.NET можно запустить из навигатора объектов (команда контекстного меню «Открыть»), при этом вызывается её точка входа.
Как и в Fore, Fore.NET-сборку можно запустить на отладку из среды разработки. Отладка так же осуществляется в отдельном процессе платформы. Скорость запуска аналогична скорости в Fore.
В отличие от Fore для запуска только что созданной пустой Fore.NET-формы необходимо написать дополнительный код.
Рассмотрим пример созданной Fore.NET-формы:
Imports System;
Imports System.Collections.Generic;
Imports System.ComponentModel;
Imports System.Data;
Imports System.Drawing;
Imports System.Text;
Imports System.Windows.Forms;
Imports Prognoz.Platform.Forms.Net;
Namespace <Идентификатор_Сборки>
Public Partial Class <Идентификатор_Объекта_Формы>Form: Prognoz.Platform.Forms.Net.ForeNetForm
Public Constructor <Идентификатор_Объекта_Формы>Form();
Begin
InitializeComponent;
End Constructor;
End Class;
End Namespace;
Для формы автоматически сгенерировался конструктор без параметров, в котором происходит вызов метода InitializeComponent. Если перейти к определению данного метода, то откроется другой модуль со следующим кодом:
Imports System;
Imports System.Collections.Generic;
Imports System.ComponentModel;
Imports System.Data;
Imports System.Drawing;
Imports System.Text;
Imports System.Windows.Forms;
Imports Prognoz.Platform.Forms.Net;
Namespace <Идентификатор_Сборки>
Public Partial Class <Идентификатор_Объекта_Формы>Form: Prognoz.Platform.Forms.Net.ForeNetForm
Private components:
System.ComponentModel.IContainer = null;
Protected Override Sub Dispose(disposing: boolean);
Begin
If (disposing And (components <> null)) then
components.Dispose();
End If;
Inherited Dispose(disposing);
End Sub;
Private Sub InitializeComponent();
Begin
Self.components := New Container();
Self.Text := "<Наименование_Формы>";
Self.Font := New System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((204) As Byte));
Self.ResumeLayout(False);
End Sub;
End Class;
End Namespace;
Нетрудно видеть, что в методе InitializeComponent происходит непосредственное создание формы со всеми её компонентами. Это даёт более чёткое представление о том, в какой момент происходит создание компонентов формы.
Данный модуль (<Наименование_Формы>.Designer) является дизайном формы: он хранит в себе размещённые на форме компоненты, их стиль, настройки и т.д. Модуль входит в Fore.NET-сборку точно также как и другие модули и формы, только его содержимое генерируется дизайнером формы автоматически.
При создании Fore.NET-формы определяются два класса с одинаковыми именами: <Идентификатор_Объекта_Формы>Form - один в модуле дизайнера, другой в модуле формы. На самом деле это один и тот же класс, подобная возможность обеспечивается ключевым словом Partial, которое стоит в определении класса формы (подробнее о частичных классах см. «Спецификация языка Fore.NET»).
Логика работы Fore.NET-сборок заключается в том, что запускается сама сборка, а не её отдельные модули или формы, поэтому чтобы запустить форму необходимо её создать и отобразить в точке входа Fore.NET-сборки:
Public Shared Sub Main(Params: StartParams);
Var
Forma: <Идентификатор_Объекта_Формы>Form = New <Идентификатор_Объекта_Формы> Form() = [<Идентификатор_Объекта_Формы> Form];
Begin
Forma.Metabase := Params.Metabase;
Forma.Show(); // либо Forma.ShowDialog();
End Sub;
Данный код создаёт объект формы, затем заполняет для него свойство Metabase и отображает на экране. Таким образом, внутри кода формы вместо MetabaseClass.Active будет использоваться свойство Metabase базового класса ForeNetForm.
Отдельные модули .NET-сборки могут содержать несколько реализаций точек входа, указание той точки, которая будет выполнена при запуске .NET-сборки осуществляется в параметрах сборки. Также в качестве объекта запуска .NET-сборки может быть указана какая-либо форма, в этом случае точки входа игнорируются.
Для открытия .NET-формы модально относительно другой .NET-формы используется метод ShowDialog. Модальные формы всегда отображаются поверх своих родительских форм. При работе с модальной формой необходимо учитывать следующую особенность: при закрытии модальной формы ее ресурсы не уничтожаются, форма просто скрывается. Ее можно повторно открыть заново вызвав метод ShowDialog. Для уничтожения ресурсов модальной формы необходимо принудительно вызвать метод Dispose или при инициализации модальной формы использовать оператор Using:
Public Partial Class TESTForm: Prognoz.Platform.Forms.Net.ForeNetForm
Public Constructor TESTForm();
Begin
InitializeComponent();
End Constructor;
about: ForeNetForm;
Public Sub ShowModalForm();
Begin
about := New CustomDialogForm();
about.ShowDialog();
End Sub;
Public Sub ShowModalForm1();
Begin
Using about := New CustomDialogForm() Do
about.ShowDialog();
End Using;
End Sub;
Public Sub ShowModalForm2();
Begin
about := New CustomDialogForm();
about.ShowDialog();
about.Dispose();
End Sub;
Public Sub ReuseModalForm();
Begin
If (about <> Null) And (Not about.IsDisposed) Then
about.ShowDialog();
End If;
End Sub;
End Class;
Методы ShowModalForm, ShowModalForm1 и ShowModalForm2 открывают модальное окно. Если окно было открыто при вызове метода ShowModalForm, то после его закрытия все ресурсы окна останутся в памяти компьютера. Окно можно будет открыть заново с помощью метода ReuseModalForm. Если окно было открыто при вызове метода ShowModalForm1 или ShowModalForm2, то после его закрытия все ресурсы освобождаются.
Помимо стандартных .NET-компонентов (это всё, что находится в пространстве имён System.Windows.Forms), Fore.NET позволяет использовать компоненты, известные по Fore. Они расположены в окне «Панель компонентов» на вкладках «Data Access» и «Common Controls». Данные компоненты определены в системной сборке Forms.Net. Работа с ними аналогична Fore, но имеется ряд особенностей.
Рассмотрим на примере компонента RdsDictionaryBoxNet. В нём определены следующие свойства: Columns, CanElementLevelUp, CanElementDown, CanElementUp, FocusedElement, Source, UiSource, CtrlBox. Все свойства, кроме UiSource и CtrlBox, присущи обычному Fore-компоненту RdsDictionaryBox. Такое же соответствие и в событиях. Рассмотрим новые свойства:
UiSource. Ссылка на источник данных: UiRdsDictionaryNet.
CtrlBox. Ссылка на объект IRdsDictionaryBox, который встраивается в RdsDictionaryBoxNet для отображения на Fore.NET-форме. В этом свойстве доступны все методы и свойства COM-интерфейса IRdsDictionaryBox, в том числе и скрытые для Fore. Поэтому использовать данную ссылку надо с особой осторожностью.
Ошибки (Exceptions) в Fore.NET условно можно разделить на два типа:
Пользовательские ошибки. Например, NullReferenceException, InavalidCastException и другие, которые обрабатываются стандартным образом и выводятся в следующем виде:
В экземпляре объекта
не задана ссылка на объект.
Класс ошибки: NullReferenceException
___________________________________
Стек вызовов:
в OBJ18283.Program.kuku() в OBJ18284:строка 32
в OBJ18283.OBJ18762Form.test() в OBJ18761:строка 23
Ошибки, генерируемые методами и свойствами используемых классов и интерфейсов ядра «Форсайт. Аналитическая платформа». На текущий момент выводится следующий текст ошибки:
В результате вызова компонента COM возвращена ошибка в формате HRESULT E_FAIL
Если вы получили такой текст ошибки, то следует добавить Defect с примером.
Fore.NET-сборки можно использовать для хранения внешних .NET-сборок. К примеру, есть готовые классы/компоненты, написанные на C# (или любом другом .NET-совместимом языке) и их можно записать в Fore.NET-сборку, а затем использовать эту сборку по ссылке в других Fore.NET-сборках.
Для загрузки внешней сборки в объект репозитория «Fore.NET-сборка», необходимо использовать метод IForeNetAssembly.LoadExternal(FileName: String):
Sub Test;
Var Asm: IForeNETAssembly; //тип для net-сборки, определён в системной сборке ForeNet
Begin
Asm := MetabaseClass.Active.ItemById(<Идентификатор_Созданной_NET-сборки>).Edit As IForeNETAssembly;
Asm.IsExternal := True;
Asm.LoadExternal(<Путь_К_Внешней_Сборке>);
If Asm.AssemblyTarget <> 1 Then
Asm.AssemblyTarget := 1; // устанавливаем тип сборки dll
End If;
(Asm As IMetabaseObject).Save;
End Sub Test;
Для использования в Fore.NET типов, определённых в Fore.NET-сборке (внешней или обычной), в Fore необходимо по ссылке подключить сборку Fore.NET и использовать следующие интерфейсы и типы:
ForeNETAssemblyClass, IForeNetAssembly, IForeNetAssemblyRuntime, IForeNetForm, IForeNetRuntimeType и т.д.
Например, есть класс, написанный на Fore.NET и сохраненный, в какой-либо .NET-сборке:
Imports System;
Imports System.Windows.Forms;
Public Class Foo
Public Sub Test();
Begin
MessageBox.Show("Fore.NET метод");
End Sub;
End Class;
Рассмотрим пример вызова метода Test из Fore:
Sub Button1OnClick(Sender: Object; Args: IMouseEventArgs);
Var run: IForeNETRuntime;
asm: IForeNETRuntimeAssembly;
typeFoo: IForeNETRuntimeType;
obj: IForeNETRuntimeObjectInstance;
res: Variant;
Begin
run := ForeNETAssemblyClass.Runtime; //Получаем Runtime, в котором будет выполняться net код
asm := run.Assembly(MetabaseClass.Active.ItemById("<Идентификатор_NET-сборки>").Bind As IForeNETAssembly); //Получаем скомпилированную .NET-сборку
typeFoo := asm.Type("<Идентификатор_NET-сборки>.Foo"); //Получаем класс Foo
obj := typeFoo.CreateInstance; //Создаём объект класса Foo
res := typeFoo.InvokeMethod("Test", obj, New Variant[0]); //Вызываем метод данного класса
End Sub Button1OnClick;
Для использования типов, определённых в Fore-модулях/формах, в Fore.NET необходимо подключить сборку Fore и использовать следующие интерфейсы и типы:
IForeClass, IForeObject, IForeAssembly, IForeSub и т.д.
Например, есть класс и метод, написанные на Fore:
Public Class Foo: Object
Public Constructor CreateEx(X: Integer; Y: Integer);
Begin
End Constructor CreateEx;
Public Sub Test;
Begin
WinApplication.InformationBox("Fore-метод");
End Sub Test;
Public Sub TestWithParams(X: Integer; Y: Integer);
Begin
WinApplication.InformationBox("Fore-метод с параметрами");
End Sub TestWithParams;
End Class Foo;
Рассмотрим пример вызова двух методов через Fore.NET:
Imports System;
Imports Prognoz.Platform.Interop.Metabase;
Imports Prognoz.Platform.Interop.Fore;
Public Class Program
//Вызов процедуры Test
Private Shared Sub InvokeMethod(mb: IMetabase);
Var
svc: IForeServices;
rnt: IForeRuntime;
assm: IForeAssembly;
ifs: IForeSub;
ifc: IForeClass;
ifo: IForeObject;
result: object;
Begin
svc := Mb As IForeServices; //Получаем объект для работы с Fore
rnt := svc.GetRuntime(); //Получаем Runtime, в котором будут выполняться методы Fore
rnt.LoadAssembly("<Идентификатор_Модуля_Fore>"); //Загружаем модуль Fore
assm := rnt.BindToAssembly("<Идентификатор_Модуля_Fore>"); //Получаем скомпилированную сборку
ifc := assm.BindToClass("Foo"); //Получаем Fore класс
ifo := ifc.CreateObject(); //Создаём объект класса Foo
ifs := ifc.BindToMethod("Test"); //Получаем метод этого класса
ifs.Self := ifo; //Указываем объект
ifs.Invoke(); //Вызываем метод Fore
End Sub;
//Вызов функции TestWithParams с передачей значений двух параметров
Private Shared Sub InvokeMethodWithParams(MB: IMetabase; x: integer; y: integer);
Var
svc: IForeServices;
rnt: IForeRuntime;
assm: IForeAssembly;
ifconst, ifs: IForeSub;
ifc: IForeClass;
ifo: IForeObject;
result: object;
Begin
svc := Mb As IForeServices; //Получаем объект для работы с Fore
rnt := svc.GetRuntime(); //Получаем Runtime, в котором будут выполняться методы Fore
rnt.LoadAssembly("<Идентификатор_Модуля_Fore>"); //Загружаем модуль Fore
assm := rnt.BindToAssembly("<Идентификатор_Модуля_Fore>"); //Получаем скомпилированную сборку
ifc := assm.BindToClass("Foo"); //Получаем Fore-класс
ifo := ifc.CreateObject(); //Создаём объект класса Foo
//Конструктор
ifconst := ifc.BindToMethod("CreateEx");
ifconst.Self := ifo;
ifconst.Params.Item(0).Value := -1; //Указываем первый параметр
ifconst.Params.Item(1).Value := -1; //Указываем второй параметр
ifconst.Invoke();
//Метод
ifs := ifc.BindToMethod("TestWithParams"); //Получаем метод этого класса
ifs.Params.Item(0).Value := x; //Указываем первый параметр
ifs.Params.Item(1).Value := y; //Указываем второй параметр
ifs.Self := ifo; //Указываем объект
ifs.Invoke(); //Вызываем метод Fore
result := ifs.ResultValue; //Получаем результат выполнения
End Sub;
[STAThread]
Public Shared Sub Main(Params: StartParams);
Begin
InvokeMethod(Params.Metabase);
InvokeMethodWithParams(Params.Metabase, 1, 100);
End Sub;
End Class;
Возможности прямого доступа (раннего связывания) между Fore и Fore.NET нет, то есть подключать по ссылке сборки Fore и Fore.NET друг к другу и использовать типы, определённые в них, на этапе компиляции нельзя.
См. также:
База знаний разработчиков | Интегрированная среда разработки | Компоненты дизайнера форм .NET | Раннее и позднее связывание