aardio + .Net 带来的好处:
1、aardio + .Net 生成的 EXE —— 再往 ILSpy 里一拖,ILSpy 瞬间歇菜啥也干不了,不像 .Net 自己生成的 EXE 可以瞬间还原出完整 C# 源代码。
2、aardio + .Net 兼容各流行系统自带 .Net 运行时,不需要额外安装。
3、aardio + .Net 可以非常方便地相互调用,代码简洁,并且可在运行时方便地编译 C# 代码导入 C# 对象。
4、aardio 可以内存加载 .Net 程序集,示例代码:
//内存加载程序集
var assembly = dotNet.loadFile($'~/MyyDLL.dll');
//导入 .Net 名字空间
TestClass = assembly.import('MyyDLL.TestClass')
只要在程集序路径前加一个 $ 号就可以将程序集直接嵌入目标程序了。
不过有些 .Net 写的程序集依赖外部 DLL,用上面说的内存加载会失败。用 ILMerge 合并得到的程序集 —— 也不支持内存加载。 为了解决这个问题,aardio 新版里加了一个强大的 dotNet.reference() 函数,下面我们先演示用法:
import dotNet;
dotNet.reference('test.mydll',$'\test.mydll.dll');
dotNet.reference('test.core',$'\test.core.dll');
//加载程序集
var assembly = dotNet.load('test.mydll');
dotNet.reference() 的第一个参数指定程序集名称,第二个参数指定实际要加载的程序集路径或内存数据,在路径前加 $ 号可以直接将 DLL 的数据编译到目标程序里(内存加载)。
也可以在 dotNet.reference 参数里一次配置多个 DLL,示例:
import dotNet;
dotNet.reference({
['test.mydll'] = $'\test.mydll.dll';
['test.core'] = $'\test.core.dll';
});
这样就可以让任意的 .Net 程序集自动从内存加载了,当然也就可以愉快地生成独立 EXE 文件了。
下面再说一下怎么在 aardio 窗体中嵌入 .Net 控件。首先我们用 C# 写一个简单的窗口程序( C# 源码这篇文章最底下 ),生成一个 WindowsFormsApp1.dll ,将其放到工程「用户库」目录以下位置:
/lib/win/ui/ctrl/netform/.res/WindowsFormsApp1.dll
然后我们添加一个控件库 win.ui.ctrl.netform,也就是新建以下源文件:
/lib/win/ui/ctrl/netform/_.aardio
并在这个 aardio 源文件中添加代码如下:
import dotNet;
import win.ui.ctrl.metaProperty;
dotNet.reference('WindowsFormsApp1',$'\lib\win\ui\ctrl\.res\WindowsFormsApp1.dll');
var WindowsFormsApp1 = dotNet.import('WindowsFormsApp1')
namespace win.ui.ctrl{
class netform {
ctor(parent,tParam){
this.form = WindowsFormsApp1.Form1();
//aardio 控件,只要在这个 hwnd 属性里指定窗口句柄就有效
this.hwnd = this.form.Handle;
//.Net 使用 GDI+ / ARGB 格式颜色值
this.form.BackColor = ..gdi.argbReverse(tParam.bgcolor);
//设为无边框窗口
this.form.FormBorderStyle = 0;
//添加委托回调
this.form.onButton1Click = function(){
if( this.oncommand ) this.oncommand();
}
}
@_metaProperty; //控件元表,定义了控件的公用方法
}
namespace netform{
_metaProperty = ..win.ui.ctrl.metaProperty(
//添加控件函数
setButtonText = function(txt){
//类外部定义元属性时使用 owner 代替 this
owner.form.button1.Text = txt;
}
);
}
}
其实非常简单,基本规则:
1、aardio 中的控件库都必须在 win.ui.ctrl 名字空间下。
2、控件元表必须用 ..win.ui.ctrl.metaProperty 创建。
3、在窗口创建好以后 —— 将句柄设置到 hwnd 属性中。.Net 窗口对象的 Handle 属性存的就是 hwnd,所以上面的代码中是这样写:
this.hwnd = this.form.Handle;
aardio 会自动调整自定义控件的窗口大小,也会自动嵌入为子窗口,这些代码都是不用写的。
关于自定义控件
Jacen He,公众号:aardioaardio 中最重要的控件:自定义控件教程
然后用起来就简单了,使用自定义控件的步骤:
1、添加代码 import win.ui.ctrl.netform 导入控件。
2、拖一个自定义控件到窗口上,并将自定义控件的类名修改为 'netform' 。
就这么简单。
import win.ui;
import win.ui.ctrl.netform;
/*DSG{{*/
var winform = win.form(text='aardio form';right=1047;bottom=634;bgcolor=10789024)
winform.add(
netform={cls='netform';text='自定义控件';left=26;top=23;right=799;bottom=416;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
winform.netform.oncommand = function(id,event){
winform.msgbox('点击了 C# 在 aardio 窗口里创建的按钮,在 C# 中调用 aardio 函数。');
winform.netform.setButtonText('点击了 C# 创建的按钮');
}
winform.show();
win.loopMessage();
以上代码运行效果如下:
生成 WindowsFormsApp1.dll 的 aardio + C# 源码如下:
import dotNet;
var compiler = dotNet.createCompiler('C#');
compiler.Parameters.CompilerOptions = '/optimize';
compiler.Reference(
'System.dll','System.Drawing.dll','System.Data.dll','System.Windows.Forms.dll'
);
compiler.Source = /******
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public class Form1: Form
{
//定义一个委托类型
public delegate void aardioCallback();
//定义一个委托类型字段
public aardioCallback onButton1Click;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
onButton1Click();
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
//无边框窗口
this.FormBorderStyle = FormBorderStyle.None;
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.button1.Location = new System.Drawing.Point(29, 18);
this.button1.Name = 'button1';
this.button1.Size = new System.Drawing.Size(343, 122);
this.button1.TabIndex = 0;
this.button1.Text = '这是 C# 创建的控钮';
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Name = 'Form1';
this.Text = 'Form1';
this.ResumeLayout(false);
}
private System.Windows.Forms.Button button1;
}
}
******/
compiler.CompileOrFail('\lib\win\ui\ctrl\.res\WindowsFormsApp1.dll');
联系客服