aardio + VB 快速开发桌面软件
zhezhongyun 2025-04-27 17:34 28 浏览
这里说的是 VB6,如果是调用 .NET 建议改用 C# ,aardio 与 C# 混合开发更方便。
VB6 的开发环境在现代操作系统上安装困难,网上有安装教程可以尝试一下(不一定行)。如果不想麻烦,可以下载一个精简版本 VB6 —— 这个至少能跑起一些基本的简单功能,或者可以安装一个 XP的虚拟机来运行 VB6 完整版。
VB6 运行库至今仍然是各版本 Windows 系统自带的系统组件,所以 VB6 可以生成体积极小的执行文件( VC6 也有这个优势 )。
今天我们一起来玩一下 VB6,先用 VB6 写一个控件,步骤如下:
1、打开VB6,选择新建 ActiveX 控件。
2、在工具条里拖一个 Image 控件到默认的用户控件 UserControl1 上面。
3、双击 UserControl1 切换到代码,添加代码如下:
'声明一个普通变量
Dim TestPropertyValue As Integer
'声明一个事件,在 aardio 中可以响应这个事件,
'注意参数加了ByRef表示传址,在 aardio 中就可以修改这这个参数的值
Public Event OnImageClick(ByRef TestPropertyValue As Integer)
'这是VB6里点了Image图像控件触发的事件
Private Sub Image1_Click()
'触发 COM 控件的事件( 换句话说就是调用 aardio 中的函数 )
RaiseEvent OnImageClick(TestPropertyValue)
End Sub
'窗口调整大小触发这个函数,注意 aardio 控件都是非适应缩放的
Private Sub UserControl_Resize()
Image1.Width = UserControl.Width
Image1.Height = UserControl.Height
End Sub
'定义读属性 TestProperty 的函数,这是带参数的属性
Public Property Get TestProperty(Param As Integer) As Integer
TestProperty = TestPropertyValue + Param
End Property
'定义写属性 TestProperty 的函数,带参数属性(参数要跟上面一致)
Public Property Let TestProperty(Param As Integer, ByVal v As Integer)
TestPropertyValue = v - Param
End Property
'定义写属性 Picture 的函数,参数是一个 IDispatch 接口的 COM 对象
Public Property Let Picture(ByVal pic As Variant)
Image1.Picture = pic
End Property
'定义一个名为 Picture 的函数
Public Function Add(ByVal a As Integer, ByVal b As Integer)
Add = a + b
End Function
然后在 VB 里点击 IDE 主菜单“文件->生成 *.ocx ” 就可以了。
整体看起来还是非常简单对吧。不过我在 aardio 自带的这个范例里没写注释,因为 VB 使用 ANSI 编码(内部 Unicode 这种文字游戏解决不了实际问题),而现在 ANSI 编码的文件里用中文的话,很多编辑器打开都是乱码,所以我把注释删掉了。
VB 的乱码问题是一个大坑,例如把 ocx 放在简体中文目录下,或者 ocx 本身包含简体中文名,然后在繁体中文系统下打开就会崩溃。
不过没有关系,在 aardio 里我们可以轻松解决这个问题。在 aardio 里加下面的代码加载 VB 控件:
var dll = com.lite.appData("aardio\vb6\Vb6Control.ocx",#34;\.vb6\Vb6Control.ocx")
请注意第@2个参数的路径前有一个$字符,这会将 ocx 的二进制数据编译到代码里,发布后就不需要再带一个 ocx 了,VB的 ocx 并不支持内存加载,所以我们用 com.lite.appData() 函数将其自动复制到 %CommonAppData% 目录下,这个路径是全英文的,自动就解决了 VB6 控件遇到 Unicode 路径崩溃的大难题。
另外,其他需要访问文件路径的地方我们用 aardio 来实现,不用 VB6 干这事,这样就可以避免 VB6 踩到这个坑。
我们再看看我们在 aardio 中怎么创建这个控件:
import com.lite;
var dll = com.lite.appData("aardio\vb6\Vb6Control.ocx",#34;\.vb6\Vb6Control.ocx")
var vbUserControl = dll.createEmbedEx(winform.static);
非常简单,VB里怎么使用这个控件,在 aardio 里我们就怎么使用。其实我们可以在 dll.createEmbedEx() 的第@2个参数里指定 COM控件的 CLSID,但 VB 这个 CLSID 不好找,很多人是先注册控件再去注册表里查,问题是 VB6现在注册控件会报错失败 —— 不过好在 aardio 可以免注册调用 VB 控件,并且在 aardio 中可以省略 CLSID,aardio 会自己帮你找到正确的 CLSID 。这么贴心 —— 有没有被感动呢?!
上面参数指定的 winform.static 是COM控件宿主窗口(也是COM控件的父窗口),vbUserControl 并不是COM对象,而是 COM对象的容器,vbUserControl._object 才是 COM 对象。
调用 COM 对象的时候需要写
vbUserControl._object.xxxx () 是不是很吃力呢?!其实我们在 aardio 中通常不会这么写,vbUserControl 通常会添加大量的封装函数,通过这些函数再去访问 vbUserControl._object ,这样 vbUserControl 就成为了一个代理对象,这种好处是非常多的,一个最典型的例子就是标准库的 web.form 或者 com.flash。
但如果我们不想去过多的封装,只想直接使用 COM 对象呢?!一个非常简单的方法是这样写:
var comObject = vbUserControl._object
然后使用这个 comObject 就行了,不过能不能不写这句代码呢?!其实也是可以的,这就是我使用 dll.createEmbedEx() 而非 dll.createEmbed() 的原因了,这两个函数作用相同,但带 Ex 后缀的 dll.createEmbedEx() 多了一个功能,他返回的控件容器对象已经自动实现了一个简单的 COM 控件代理 —— 例如上面访问 vbUserControl 对象的成员就会自动转为调用 vbUserControl._object 的成员,等于将COM控件容器与 COM对象合二为一了。
控件容器对象还可以作为默认的事件监听器,记得我们前面 VB 代码中用 RaiseEvent OnImageClick(TestPropertyValue) 触发事件吗?在 aardio 代码中我们可以如下响应这个事件:
//控件容器也是默认的 COM 事件监听器,如下直接指定响应 COM 事件的函数
vbUserControl.OnImageClick = function(value){
winform.edit.print("VB控件里点击了图像,事件参数:"+value)
//VB里这个事件的参数声明为 ByRef,所以添加返回值可以修改参数
return 100
}
VB6 里这个事件的参数指定为 ByRef 传址,也就是说参数 value 是一个引用参数,在 aardio 中可以修改他的值,aardio 基于纯函数原则不会直接修改外部参数的值,而是通过增加返回值修改引用参数的值。这个事件函数没有返回值,也只有一个需要输出值的引用参数,所以增加一个返回值就可以了。
这个示例是用 VB 显示图像,我们就不要用 VB 来加载图像了,如果图像路径有中文或 Unicode 字符又不太好,但 aardio 是 UTF8 内核,没有这些问题,所以我们用 com.picture.loadObject( "~\codes\范例程序\D) 图形图像\.gdip.jpg" ) 加载图像再传给 VB, com.pictrue 的函数创建的都是 IPicture 对象,这是与 VB 兼容的,但我们通过 COM 接口不能传原生的 IPicture 过去,我们要用 com.picture.loadObject() 函数,右键点这个函数跳转到定义,看一下源代码你就明白了:
namespace com.picture{
loadObject = function(path){
return ..com.QueryObject( load(path) );
}
}
其实就是调用 com.pictrue.load() 加载图像,再用 com.QueryObject() 转换为 COM 对象( IDispatch 接口 ) ,然后就可以传给 VB了:
//修改VB控件的属性
vbUserControl.Picture = com.picture.loadObject( "~\codes\范例程序\D) 图形图像\.gdip.jpg" )
反正我在繁体系统下测试 VB控件直接加载上面的图像会出问题,但用上面的方法 —— 用 aardio 加载图像再传给 VB6 就完美解决。
至于调用 VB 函数这个很简单:
//调用 VB 函数
var c = vbUserControl.Add(2,3);
VB有一个比较有特色的参数化属性,例如看到这种写法是不是蒙了:
vbUserControl.TestProperty(2) = 123
千万别以为是给函数的返回值赋值,我们把上面的参数化属性赋值转换为 等价的 aardio 代码如下:
//修改VB控件的参数化属性,加上 set 前缀以函数形式调用
vbUserControl.setTestProperty(2,123)
在 aardio 里给属性加上 set 前缀就可以变成一个写属性的函数,当然也就支持多个参数了。同理,加上 get 前缀可以变成一个读属性函数,如下:
/*
带多个参数的属性加上get前缀并以函数形式调用,例如:
*/
var testProperty = vbUserControl.getTestProperty(2);
好吧下面我们看这个范例的完整 aardio 源码,直接复制就可以运行,直接复制就是一个独立的、完整的程序:
import win.ui;
/*DSG{{*/
var winform = win.form(text="免注册嵌入 VB 控件";right=706;bottom=274)
winform.add(
edit={cls="edit";left=356;top=20;right=665;bottom=243;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;vscroll=1;z=2};
static={cls="static";text="Static";left=21;top=20;right=330;bottom=243;dl=1;dt=1;transparent=1;z=1}
)
/*}}*/
import com.lite;
var dll = com.lite.appData("aardio\vb6\Vb6Control.ocx"
,#34;~\codes\范例程序\2) 调用其他语言\F) VB\.vb6\Vb6Control.ocx");
var vbUserControl = dll.createEmbedEx(winform.static);
//控件容器也是默认的 COM 事件监听器
vbUserControl.OnImageClick = function(value){
winform.edit.print("VB控件里点击了图像,事件参数:"+value);
return 100;
}
//修改VB控件的属性
vbUserControl.Picture = com.picture.loadObject( "~\codes\范例程序\D) 图形图像\.gdip.jpg" )
//修改VB控件的参数化属性,加上 set 前缀以函数形式调用
vbUserControl.setTestProperty(2,123)
//带多个参数的属性加上get前缀并以函数形式调用,例如:
var testProperty = vbUserControl.getTestProperty(2);
winform.edit.print("VB 控件 TestProperty(2) 属性:",testProperty);
//调用 VB 函数
var c = vbUserControl.Add(2,3);
winform.edit.print("调用 VB 控件函数返回值:",c);
winform.edit.print("请点击图像试试");
winform.show();
win.loopMessage();
最后不得不佩服一下,这个 VB 控件的体积是:24KB,对比一下现在用 Electron 什么的没写几个功能就几百MB是什么概念,这几百MB里有多少是你真正需要的东西?!不是说这些东西没有用,就像豪华大房车一定是有用的,但你明明骑个自行车能解决的问题,非要每次都开豪华大房车吗?!想想这个道理,就会明白 VB6 的好处在哪里。
图还是要补上的:
相关推荐
- DevExpress使用教程:GridView经验小结
-
下面是笔者自己总结的使用DevExpressGridview的一些经验小结,分享给大家:1、去除GridView头上的"Dragacolumnheaderheretogroup...
- ComponentOne 新版本发布,新增 .NET 6 和 Blazor 平台控件支持
-
ComponentOneEnterprise是葡萄城推出的一款内置300多种开发控件的.NET控件集,可满足WinForm、WPF、Blazor、ASP.NETMVC等平台下的系统开发...
- Wijmo5 Flexgrid基础教程:数据绑定
-
WijmoEnterprise下载>FlexGrid在JavaScript程序中启动添加Wijmo引用;添加wijmo控件的扩展;在JavaScript中初始化wijmo控件;(可选)添加cs...
- Wijmo5 Flexgrid基础教程:InlineEdit
-
WijmoEnterprise下载>对于flexgrid,可以直接在单元格内进行编辑。但另外还有一种编辑方式,即在一行添加按钮,统一的编辑和提交数据。本文主要介绍给flexgrid添加编辑按钮...
- WinForms Data Grid控件升级(winform devexpress控件)
-
告诉大家一个好消息:慧都将于近期隆重推出“DevExpress14.2新版发布会”。心动不如行动,赶快报名吧!我们期待与您相约DevExpress14.2新版发布会。>>新增Wind...
- XAML控件宽度为另一控件的一半、静态属性绑定
-
控件上当某些数据需要根据其他数据的变化而变化很多时候,想让某个控件的宽度或者高度是另一个已有控件的一半,一开始打算使用ObjectDataProvider来实现,因为在控件上当某些数据需要根据其他数据...
- 用 CSS Grid 布局制作一个响应式柱状图
-
最新一段时间比较喜欢玩弄图表,出于好奇,我想找出比较好的用CSS制作图表的方案。开始学习网上开源图表库,它对我学习新的和不熟悉的前端技术很有帮助,比如这个:CSSGrid。今天和大家分享我学到的...
- Grid 移动端双列瀑布流(移动端瀑布流布局)
-
预览图:原理合理使用Grid的属性:display:设置为grid指明当前容器为Grid布局grid-template-columns:定义每一列的列宽(百分比或绝对单位)grid-templa...
- DevExpress导出GridControl控件数据
-
前言:使用C#做桌面应用时,我们会常常使用Winform作为我们的开发界面,但是windows自带的控件由于长时间不更新,已经不能够满足当前开发需要所以使用DevExpress控件作为Winform...
- css grid 布局的那些事儿(css grid布局和flex布局)
-
CSSGrid是一种为Web开发创建网站布局的方式。它已经存在了很多年,随着更多浏览器的支持,它终于变得越来越流行。接下来我们将了解下CSSGrid及其工作原理。了解下它如何使用。CSS...
- Grid.js - 跨框架的前端表格插件(前端table框架)
-
只想简简单单画个表格,但React,Vue,Angular,…,这么多前端框架,各自都有不同的表格渲染库。就没有表格库能“一次画表,到处运行”吗?来看看Grid.js这个跨框架的前端表格插件吧!...
- WPF开发教程01-布局控件(wpf tablecontrol控件)
-
布局控件是用于进行控件布局的容器类控件,其内部控件按照一定规律自动排列,且在父控件改变大小时,会自动适应。常用布局控件如下:1.一维布局控件(StackPanel)其内部控件按照某个维度自动排列,排...
- wxPython - 高级控件之表格Grid(wxpython grid刷新数据)
-
实战wxPython系列-043wx.grid.Grid及其相关类用于显示和编辑表格数据。它们提供了一组丰富的功能,用于显示、编辑和与各种数据源交互。wx.grid.Grid是一个功能强大的但是又稍微...
- 前端 BFC、IFC、GFC 和 FFC,这些你都知道吗?
-
如果觉得我的文章不错,可以关注我,想要看其他的进阶知识可以查看我发布过的文章!编辑搜图请点击输入图片描述BFC(Blockformattingcontexts):块级格式上下文页面上的一个隔离的...
- 20多个好用的 Vue 组件库,请查收
-
在本文中,我们将探讨一些最常见的vuejs组件。你可以收藏一波。VueTables-2地址:https://github.com/matfish2/vue-tables-2VueTables2...
- 一周热门
- 最近发表
-
- DevExpress使用教程:GridView经验小结
- ComponentOne 新版本发布,新增 .NET 6 和 Blazor 平台控件支持
- Wijmo5 Flexgrid基础教程:数据绑定
- Wijmo5 Flexgrid基础教程:InlineEdit
- WinForms Data Grid控件升级(winform devexpress控件)
- XAML控件宽度为另一控件的一半、静态属性绑定
- 用 CSS Grid 布局制作一个响应式柱状图
- Grid 移动端双列瀑布流(移动端瀑布流布局)
- DevExpress导出GridControl控件数据
- css grid 布局的那些事儿(css grid布局和flex布局)
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- CSS 水平对齐 (Horizontal Align) (30)