从Delphi到Lazarus——在Lazarus中使用ActiveX控件(导入类型库)
0.前言
Lazarus的设计目标是应用Free Pascal,所以所有凡是Free Pascal能运行的平台,Lazarus都可以运行。通俗地说就是Lazarus追求的是跨平台编程,致力于“一次编写,到处编译”。
Lazarus最初是一个基于Free Pascal的Delphi仿制品。Lazarus作为一个可能代替Delphi的集成开发环境,从诞生以来表现出顽强的生命力和高速的发展势头,支持的平台越来越多。尽管如此,我们不是专业的程序员,作为业余编程爱好者或者仅仅是为了自己工作需要而编程的人,我们绝大多数人能够用到的操作系统可能只有一种,这样的情况下跨平台编程对于我们来说是没有意义的,最多也就是为了满足好奇心而适当地学习和探讨一下罢了。
我们选择使用Lazarus的目的可能仅仅就是为了避免不喜欢Delphi的某些限制或者麻烦,而不是因为Delphi不够优秀。
作为一种跨平台的程序开发环境,Lazarus有其天然的不足。跟其他一些跨平台开发环境一样,为了能够使得用它编写的程序在移植到其他操作系统时有尽可能少的修改,保留了各种平台共有的东西,而操作系统独有的一些功能却被舍弃,而这些独有的功能有时候恰恰是我们需要用到的。
支持某种操作系统下独有的功能,我们可能有以下方法:
- 使用仅在某种操作系统下才能使用的组件
- 调用某种操作系统提供的API函数
- 使用ActiveX控件支持
在这篇文章里,我将重点讲述Lazarus中使用ActiveX控件的方法。主要内容如下:
- Lazarus对ActiveX控件的支持
- 用你的电脑中安装的ActiveX控件创建组件(导入类型库)
- 在你的程序中使用你自己创建的ActiveX的组件
- 测试结果分析及其他使用ActiveX的文章推荐
- 结束语
1.Lazarus对ActiveX控件的支持
ActiveX 是一种 Microsoft Windows 技术,只能在该平台上使用。
Lazarus提供了一个名为LazActiveX 0.1的软件包,用于提供对ActiveX的支持。这个软件包在Lazarus安装文件夹下的components\activex文件夹中。要想在Lazarus中使用ActiveX,就需要先安装这个软件包。安装LazActiveX 0.1的软件包的方法可以打开以下链接,参照其中的[3.安装整合IDE界面的软件包]的步骤,选择安装LazActiveX 0.1:
从Delphi到Lazarus——安装最新版的Lazarus - lexyao - 博客园
LazActiveX软件包包含 TActiveXContainer 组件和必要工具的 IDE 集成,以便从类型库或直接从对象(exe 或 dll)创建 ActiveX 组件。安装完成后组件面板中增加了一个AxctiveX页面,在这个页面中你会看到一个图标
,这就是TActiveXContainer 组件。
Delphi 中使用AxctiveX的方法是通过组件 OleServer,而Lazarus使用的则是TActiveXContainer组件。似乎Lazarus提供的方法使用起来更加方便。
2.用你的电脑中安装的ActiveX控件创建组件(导入类型库)
在Delphi中使用过Activex的人都不会陌生,除了Delphi已经包装了的ActiveX控件之外,你要使用ActiveX的第一步的操作就是导入类型库。在Lazarus中也是需要先导入类型库。Lazarus中导入类型库的操作步骤如下:
- 在Lazarus的安装文件夹下建立一个名为ActiveX的文件夹
- 点击主菜单[工具->导入类型库…],打开[导入类型库]窗口
- 在窗口的列表①中选择你要使用的ActiveX控件。Lazarus将ActiveX控件分为两组,一组是可视的(Visual Controls),一组是不可视的(ActiveX References),你可以通过选项卡②切换选择
- 窗口下边③有三个选项,分别是“创建可视化组件”、“创建包”、“转换相关的typelibs”,建议都要选中。将来熟悉了之后你可以自己决定选或者不选

- 点击[确定]按钮,弹出[选择文件夹]窗口
- 这里以Microsoft Internet Controls为例,所以在[选择文件夹]窗口中找到你刚才创建的ActiveX文件夹,并在其中创建文件夹SHDocVw,然后选中这个新创建的文件夹点击确认。这时如果你用文件资源管理器打开SHDocVw文件夹,你会看到其中有三个文件:SHDocVw_1_1_TLB.pas、SHDocVw_1_1_TLBP.lpk、SHDocVw_1_1_TLBPreg.pas,这就是导入类型库后生成的软件包
- 确认了选择文件夹后弹出[软件包]窗口。你会发现这个窗口与点击主菜单[软件包->打开软件包…]打开一个软件包后的窗口是一样的。点击窗口中的[使用->安装]
- 在弹出的[重新构建Lazarus?]窗口中点击[是]按钮,等待Lazarus重新编译、构建、运行……
当你看到重新运行的Lazarus后,你导入类型库的操作就算是完成了。这时你再打开组件面板中的ActiveX页,你会看到增加了几个图标,这就是你导入类型库后生成的组件。你将鼠标悬停在图标上,你会看到组件的名字。

需要说明一点:建立一个名为ActiveX的文件夹是我的建议,不是必须的,你可以决定是不是要这样做。默认情况下Lazarus导入类型库后生成的软件包放置在系统的临时文件夹下,不利于今后的使用和管理。建立一个独立的ActiveX文件夹后你使用就方便多了。
3.在你的程序中使用你自己创建的ActiveX的组件
当你决定要使用ActiveX的时候,我会认为你已经知道了使用ActiveX控件的方法。按着Microsoft提供的资料,使用ActiveX有先期绑定和后期绑定两种形式。在Lazarus中,你可以遵循这种理念,但具体的操作可能要比你想象的简单了许多。下面我将通过一个例子向你展示在Lazarus中使用ActiveX的方法。
第一步、创建项目
- 在Lazarus中点击主菜单[文件->新建…],在打开的[新建]窗口中选择[项目->应用程序],然后[确定],这时创建了一个名为project1的项目,它包含一个名为Form1的窗体。
- 在属性列表中将窗体的name由Form1改为frmMain
- 点击主菜单[文件->保存]保存项目到名为MyBrw的文件夹中。保存时将项目名称由project1.lpi改为MyBrowser.lpi、单元文件名由uint1.pas改为main.pas
第二步、向窗体中添加组件
- 向窗体中添加一个状态条StatusBar1: TStatusBar
- 向窗体中添加一个工具条ToolBar1: TToolBar,选中工具条,在属性列表中将它的AutoSize、ShowCaptions属性设置为true,将Wrapable属性设置为false
- 在工具条上点击鼠标右键,选择[新建按钮],选中工具条中新建的按钮,在属性列表中将它的name改为btnOpen,Caption改为“打开”
- 在工具条中添加一个单行文本组件,将它的名称改为edUrl: TEdit
- 从组件面板中选择TAxcWebBrowser添加在窗体的中间空白处,在属性列表中将组件AxcWebBrowser1的属性Active设置为true,将Align设置为alClient
以下是添加了组件后main.pas文件中的代码:
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls,
SHDocVw_1_1_TLB;
type
{ TfrmMain }
TfrmMain = class(TForm)
AxcWebBrowser1: TAxcWebBrowser;
edUrl: TEdit;
StatusBar1: TStatusBar;
ToolBar1: TToolBar;
btnOpen: TToolButton;
private
public
end;
var
frmMain: TfrmMain;
implementation
{$R *.lfm}
end.
在Lazarus的代码编辑器中用鼠标点击“TAxcWebBrowser”,再点击鼠标右键,从弹出菜单中选择“查找TAxcWebBrowser的定义”,你会看到打开的SHDocVw_1_1_TLB单元文件中TAxcWebBrowser类的定义代码。
TAxcWebBrowser = Class(TActiveXContainer)
Private
FServer:IWebBrowser2;
……
从代码中可以看出,TAxcWebBrowser继承自TActiveXContainer,这也是在向窗体添加组件时不用添加TActiveXContainer而直接添加TAxcWebBrowser的原因。
第三步、添加代码
在“对象查看器”中选择窗体组件frmMain: TfrmMain,然后在[属性->事件]中双击OnCreate和OnResize给窗体添加两个事件处理函数,然后在代码编辑器中给这两个函数添加如下代码:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
Caption:='我的浏览器';
edUrl.Text:='在这里输入你要浏览的网页的网址';
end; procedure TfrmMain.FormResize(Sender: TObject);
begin
edUrl.Width:=ToolBar1.ClientWidth-edUrl.Left;
end;
在“对象查看器”中选择组件AxcWebBrowser1: TAxcWebBrowser,然后在[属性->事件]中双击OnStatusTextChange和OnTitleChange给TAxcWebBrowser组件添加两个事件处理函数,然后在代码编辑器中给这两个函数添加如下代码:
procedure TfrmMain.AxcWebBrowser1StatusTextChange(Sender: TObject; Text_: WideString);
begin
StatusBar1.SimpleText := Text_;
end;
procedure TfrmMain.AxcWebBrowser1TitleChange(Sender: TObject; Text_: WideString);
begin
Caption := '我的浏览器 -- ' + Text_;
end;
在“对象查看器”中用鼠标双击组件btnOpen: TToolButton,给组件btnOpen添加OnClick事件处理函数,然后在代码编辑器中给这个函数添加如下代码:
procedure TfrmMain.btnOpenClick(Sender: TObject);
var
Flags:OleVariant;
TargetFrameName:OleVariant;
PostData:OleVariant;
Headers:OleVariant;
begin
AxcWebBrowser1.OleServer.Navigate(edUrl.Text, Flags, TargetFrameName, PostData, Headers);
end;
第四步、运行测试
点击Lazarus工具栏中的绿色[运行]按钮,你编写的程序MyBrowser开始运行,你会看到如下图所示的窗口,这说明你的程序已经编制完成,并且经过编译后能正常运行了。

为了进一步测试MyBrowser的效果,再做两个测试。
第一个测试,在你的电脑中随便找到一个网页文件,双击后在浏览器中打开,从浏览器的网址栏中复制它的网址,粘贴到MyBrowser的网址栏中,点击[打开]按钮,你会看到打开网页的画面如下:

第二个测试,在你的电脑的浏览器中随便打开一个互联网上的网页,从浏览器的网址栏中复制它的网址,粘贴到MyBrowser的网址栏中,点击[打开]按钮,你会看到打开网页的画面如下:

4.测试结果分析及其他使用ActiveX的文章推荐
从上面编写的测试程序运行结果来看,第一个窗口看上去是正常的,这说明程序正常编译运行了。再看后面进一步测试的两个窗口截图,你会发现有两个问题:
第一个问题:标题栏中出现乱码。
本来在标题栏中应该显示“我的浏览器 -- <网页标题>”,但截图中看到的“我的浏览器”变成了乱码,而在Delphi中不会出现这样的现象。
只要需要把原来的代码做小小的改动,改成下面的代码,再次运行测试,会有什么效果呢?
procedure TfrmMain.AxcWebBrowser1TitleChange(Sender: TObject; Text_: WideString);
var
ss:String;
begin
ss := '我的浏览器 -- ';
Caption := ss + Text_;
end;
下面就是运行后重新测试的截图,看一下左上角,“我的浏览器”几个字正常显示,不再是乱码了。在Delphi中这样的代码修改是没有意义的,而在Lazarus中确实截然不同的两种结果。你会不会说:“这没道理啊!”

为什么这样呢?这个问题应该是Lazarus使用的字符串编码格式造成的,需要对字符串进行格式转换才能正常显示汉字。
Lazarus的字符串表示跟Delphi是不同的,关于Lazarus中字符串的说明可以从以下链接中了解到:
LCL Unicode Support/zh CN - Free Pascal wiki
Unicode Support in Lazarus - Free Pascal wiki
第二个问题:无法安全地打开网页。
正如截图中的网页标题所说的,“无法安全地连接到此页面”。
为什么这样呢?从截图中的文字应该了出现问题的可能原因,这不是Lazarus的问题,而是没有给TAxcWebBrowser组件设置正确的选项造成的。准确地说,是没有设置IWebBrowser的选项,这不是Lazarus的问题。
从以上问题可以看出,使用Lazarus和使用Delphi还是有区别的,而使用ActiveX控件还要了解这个ActiveX本身的设置要求。
5.结束语
Windows 中提供了大量的ActiveX 控件,具有很多丰富且实用的功能,这些强大的功能或许对你有用,但不是你编写程序时都能用得到的。
你可以选择导入类型库的方式使用Windows提供的ActiveX的强大的功能,这也意味着你放弃了开发跨平台应用程序的想法。如果你仅仅是在一个操作系统下使用你编写的程序,你完全可以不必介怀跨平台的问题。如果你将来有了跨平台的需求,可以考虑根据目标平台的要求修改受平台限制的代码,而不是在编写程序之初就考虑在遥远的将来才有可能出现的跨平台要求。
关于在Lazarus中使用ActiveX,在网上有一篇关于LazActiveX 0.1的软件包的更加全面的介绍,你可以点开下面的网址看一看,应该会有所收获。
LazActiveX - Free Pascal wiki(英文)
从Delphi到Lazarus——在Lazarus中使用ActiveX控件(导入类型库)的更多相关文章
- 在Qt中使用ActiveX控件
Qt的windows商业版本提供了ActiveQt这个framework,使用这个组件我们可以在Qt中使用ActiveX控件,并且也开发基于Qt的ActiveX控件.ActiveQt包含了两个组件QA ...
- Qt中使用ActiveX控件
(转自:http://blog.csdn.net/tingsking18/article/details/5403038) 在Qt中使用ActiveX控件 Qt的windows商业版本提供了Activ ...
- 如何向VS2010中插入ActiveX控件并且附带相应的类
上两篇文章中我们已经讲述了ActiveX控件的一些相关知识,本文中,简单说明一下如何在我们自己的程序中使用ActiveX控件.(仍以我们上节课的例子为例) 我们打开VS2010编辑器,新建一个基于对话 ...
- EXCEL2007出错了无法使用文档中的ActiveX 控件
EXCEL2007出错了无法使用文档中的ActiveX 控件虽说是很久之前的问题,但是正确的解决方法和原因如下!原因:系统update之后出现的问题解决方法:删除C:\Users\[username] ...
- 【VS开发】在VS2010中开发ActiveX控件设置测试容器的方式
在VS2010中开发ActiveX控件设置测试容器的方式 借鉴文章http://blog.csdn.net/waxgourd0/article/details/7374669 在VS2010中开发MF ...
- 如何在VS2010中添加ActiveX控件及使用方法
方法1: 1.首先在在项目上面右击添加类,如下图所示: 2.点击添加ActiveX控件中的MFC类 3.找到需要添加的ActiveX类. 4.点击完成即可. 5.此时转到资源视图,打开如下视图.可能工 ...
- 【转】Win32程序中调用ActiveX控件
#include "stdafx.h" #include <iostream> #include <windows.h> #include <comd ...
- IE中的activex控件
1.tree控件 DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HE ...
- VS.NET中的常用控件和类型的命名规范
表1 命名规范 VS名称 简写 VS名称 简写 数据类型 Array arr Boolean bln Byte byt Char Chr Date Time dtm Decimal dtm Doub ...
- Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)
一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32 ...
随机推荐
- 从零开始搭建一个LoRaWAN基站
先说两句 SX1301/SX1302是semtech公司推出的基站端射频基带芯片,其与SX127x/SX126x的主要区别在于: 只是个基带芯片,使用时需要加射频前端(SX125x/SAW/...) ...
- 神经网络之卷积篇:详解为什么使用卷积?(Why convolutions?)
详解为什么使用卷积? 来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括.和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀 ...
- 暑假集训PVZ提高模拟9
没关 exe 让这货挂了一天 UPD:又挂了一晚上,现在被我正义制裁了 A.大众点评 交互红题啊,交互会写,但是忘记判 \(n=1\) 了 这个题交互库函数实现起来还是挺简单的,我 Windows 不 ...
- .net6 使用gRPC示例
创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(客户端),测试项目结构如下: 公共模型 测试接口相关类,放在公共类库中,方便服务端和客户端引用相同模型 public class R ...
- 【赵渝强】使用二进制包部署Kubernetes集群
在一些企业的私有环境中可能无法连接外部的网络.如果要在这样的环境中部署Kubernetes集群,可以采集Kubernetes离线安装的方式进行部署.即:使用二进制安装包部署Kubernetes集群,采 ...
- 记一次Razor Pages无法编译问题及解决
解决方案写在前面:更新Visual Studio及相关组件,本人版本自17.8.0更新至17.11.4 缘起于公司的一个业务接口,在有一些信息需要在应用内嵌的webview中展示,信息不少,涉及的前端 ...
- LeetCode 1000. Minimum Cost to Merge Stones (区间 DP)
根据寒神题解 https://leetcode.com/problems/minimum-cost-to-merge-stones/discuss/247567/JavaC%2B%2BPython-D ...
- `std::packaged_task`、`std::thread` 和 `std::async` 的区别与联系
std::packaged_task.std::thread 和 std::async 的区别与联系 std::packaged_task.std::thread 和 std::async 都是 C+ ...
- 直播预告 | YashanDB 2023年度发布会正式定档11月8日,邀您共同见证国产数据库发展实践!
11月8日,YashanDB 2023年度发布会将于云端直播开启,发布会以 「惟实·励新」 为主题,邀请企业用户.合作伙伴.广大开发者共同见证全新产品与解决方案.届时发布会将在墨天轮社区同步进行,欢迎 ...
- ServiceMesh 3:路由控制(图文总结)
★ ServiceMesh系列 1 Istio部署 1.1 连接测试机 进入测试机服务器... 1.2 安装Istio 1.2.1 通过官方网站下载Istio # 下载最新版本的Istio $ cur ...