Итак, наш элемент работает в проекте Шаблоны (Templates) пакета Core:
С помощью проекта этого типа можно сделать:
- редактор пользовательского свойства для элементов;
быстро отладить прототип будущей программы проекта Windows Forms;
компилировать, запускаемую на машине с предустановленным HiAsm.NET, сборку (.exe);
Может возникнуть вопрос: зачем создавать прототип программы в проекте Шаблоны? Для схемы из десятка элементов время сборки проектов будет отличаться незначительно, но для больших схем это будет очень заметно. Поэтому, для отладки прототипа программы комфортнее это делать в проекте Шаблоны, а уже финальное тестирование в проекте Windows Forms. Это означает что элементы пакета Core должны уметь одинаково работать в обоих проектах. Значит следущим шагом мы сделаем необходимые дополнения для нашего элемента, чтобы он смог работать в проекте Windows Forms. Для этого надо создать скрипт, который в процессе построения нашего приложения, будет возвращать C# код, реализующий функционал нашего элемента. Создадим в папке C:\HiAsm.NET\elements\_base\code файл с именем wfExample.cs со следующим содержимым:
//css_ref System.Core;
//css_ref Microsoft.CSharp;
using System;
using codegen;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;
using System.Resources;
using System.IO;
using System.Text;
using System.Dynamic;
using System.Threading.Tasks;
using System.Threading;
public class Example : TElementObject
{
public override bool init(object entry)
{
Debug.WriteLine("{0}.init()".fString(this.codename));
sys.add_var(this, "local", "string", "Hello World!".toLiteral());
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
sys.blk.println(@this.local, " = ", d("Data"), ";");
@event("onGreeting", new TValue(@this.local, true));
return TValue.empty;
});
@this.Greeting = (Func<TArgs, TValue>)((data) =>
{
return new TValue(@this.local, true);
});
return base.init(this);
}
}
//css_ref System.Core;
//css_ref Microsoft.CSharp;
using System;
using codegen;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;
using System.Resources;
using System.IO;
using System.Text;
using System.Dynamic;
using System.Threading.Tasks;
using System.Threading;
//css_pc wfPrecompiler.cs;
public class Example : TElementObject
{
...
}
public override bool init(object entry)
{
...
return base.init(this);
}
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
...
return TValue.empty;
});
@this.Greeting = (Func<TArgs, TValue>)((data) =>
{
...
return TValue.empty;
});
public override bool init(object entry)
{
Debug.WriteLine("...");
...
}
public override bool init(object entry)
{
...
sys.add_var(this, "local", "string", "Hello World!".toLiteral());
}
В методе точки doSayHello мы читаем данные, пришедшие в элемент через левую или верхнюю точки и сохраняем их в нашу переменную local:
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
sys.blk.println(@this.local, " = ", d("Data"), ";");
...
});
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
...
@event("onGreeting", new TValue(@this.local, true));
...
});
@this.Greeting = (Func<TArgs, TValue>)((data) =>
{
return new TValue(@this.local, true);
});
После того, как мы полностью отладим скрипт, мы можем поместить его в ресурсы нашего элемента и использовать напрямую оттуда. Делаем это так же как мы добавляли иконку в ресурсы элемента (смотрите первый пост темы). В результате добавления мы получим следующий вид ресурсов сборки:
Теперь файл C:\HiAsm.NET\elements\_base\code\wfExample.cs нужно убрать в другое место или удалить с диска, так как его наличие в папке \code является приоритетным перед ресурсами сборки и при построении программы будет использован именно он. Кстати, таким образом может быть «изменена» работа любого элемента проекта Windows Forms.

Наконец, оптимизируем скрипт для использования из ресурсов сборки. Заменим код скрипта до определения класса его эквивалентом в виде тегированного комментария:
//css_pc wfPrecompiler.cs;
public class Example : TElementObject
{
public override bool init(object entry)
{
Debug.WriteLine("{0}.init()".fString(this.codename));
sys.add_var(this, "local", "string", "Hello World!".toLiteral());
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
sys.blk.println(@this.local, " = ", d("Data"), ";");
@event("onGreeting", new TValue(@this.local, true));
return TValue.empty;
});
@this.Greeting = (Func<TArgs, TValue>)((data) =>
{
return new TValue(@this.local, true);
});
return base.init(this);
}
}

