Pascal fpCEF3:在Free Pascal中嵌入Chromium的强大框架
项目概述
fpCEF3是一个基于Free Pascal的Chromium Embedded Framework(CEF)封装库,它允许Pascal开发者在自己的应用程序中嵌入完整的Chromium浏览器引擎。该项目由开发者dliw创建并维护,为Pascal社区提供了一个强大而现代的Web集成解决方案。
核心特性
1. 完整的CEF功能封装
fpCEF3封装了CEF3的主要功能,包括: - 完整的浏览器控件支持 - JavaScript与Pascal代码双向通信 - Cookie管理 - 开发者工具集成 - 多进程架构支持
2. 跨平台兼容性
- 支持Windows、Linux和macOS
- 与Lazarus IDE完美集成
- 兼容多种Free Pascal编译器版本
3. 简化的API设计
- 提供直观的Pascal接口
- 减少CEF原生API的复杂性
- 包含丰富的示例代码
安装与配置
系统要求
- Free Pascal 3.0.0或更高版本
- Lazarus IDE(推荐)
- CEF3二进制文件
安装步骤
- 克隆项目仓库:
text
git clone https://github.com/dliw/fpCEF3.git
- 下载CEF二进制文件:
- 从CEF官方网站下载对应平台的CEF二进制包
- 将文件解压到项目目录中
- 配置Lazarus:
- 将fpCEF3目录添加到Lazarus的库路径
- 在项目选项中包含必要的单元文件
基础使用示例
示例1:创建简单浏览器窗口
text
program SimpleBrowser;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces,
Forms,
uSimpleBrowser;
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
text
unit uSimpleBrowser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs,
cef3types, cef3api, cef3lib, cef3intf, cef3own;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FBrowser: ICefBrowser;
FClient: TCefClientOwn;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.FormCreate(Sender: TObject);
var
WindowInfo: TCefWindowInfo;
Settings: TCefSettings;
BrowserSettings: TCefBrowserSettings;
Url: ustring;
begin
// 初始化CEF
CefLoadLibrary;
CefInitialize(@Settings, nil, nil);
// 创建浏览器窗口
FillChar(WindowInfo, SizeOf(WindowInfo), 0);
WindowInfo.style := WS_VISIBLE or WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_TABSTOP;
WindowInfo.parent_window := Handle;
WindowInfo.x := 0;
WindowInfo.y := 0;
WindowInfo.width := ClientWidth;
WindowInfo.height := ClientHeight;
FillChar(BrowserSettings, SizeOf(BrowserSettings), 0);
BrowserSettings.size := SizeOf(BrowserSettings);
Url := 'https://www.example.com';
// 创建浏览器实例
FBrowser := CefBrowserHostCreateBrowserSync(@WindowInfo, FClient, @Url, @BrowserSettings, nil);
end;
end.
示例2:JavaScript与Pascal交互
text
unit uJSInteraction;
interface
uses
Classes, SysUtils, cef3intf, cef3types, cef3api;
type
TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
protected
function OnProcessMessageReceived(const browser: ICefBrowser;
sourceProcess: TCefProcessId; const message: ICefProcessMessage): Boolean; override;
end;
TCustomBrowser = class
private
FBrowser: ICefBrowser;
// 处理来自JavaScript的消息
procedure HandleJSMessage(const message: ICefProcessMessage);
public
procedure ExecuteJavaScript(const code: ustring);
procedure SendMessageToJS(const name: ustring; const args: array of const);
end;
implementation
procedure TCustomBrowser.ExecuteJavaScript(const code: ustring);
var
Frame: ICefFrame;
begin
if Assigned(FBrowser) then
begin
Frame := FBrowser.MainFrame;
if Assigned(Frame) then
Frame.ExecuteJavaScript(code, 'about:blank', 0);
end;
end;
procedure TCustomBrowser.SendMessageToJS(const name: ustring; const args: array of const);
var
Message: ICefProcessMessage;
List: ICefListValue;
i: Integer;
begin
Message := TCefProcessMessageRef.New(name);
List := Message.ArgumentList;
for i := Low(args) to High(args) do
begin
case args[i].VType of
vtInteger: List.SetInt(i - Low(args), args[i].VInteger);
vtBoolean: List.SetBool(i - Low(args), args[i].VBoolean);
vtString: List.SetString(i - Low(args), ustring(args[i].VString^));
vtAnsiString: List.SetString(i - Low(args), ustring(AnsiString(args[i].VAnsiString)));
vtUnicodeString: List.SetString(i - Low(args), ustring(UnicodeString(args[i].VUnicodeString)));
end;
end;
FBrowser.SendProcessMessage(PID_RENDERER, Message);
end;
procedure TCustomBrowser.HandleJSMessage(const message: ICefProcessMessage);
var
MessageName: ustring;
begin
MessageName := message.Name;
if MessageName = 'buttonClicked' then
begin
// 处理按钮点击事件
ShowMessage('按钮被点击了!');
end
else if MessageName = 'formSubmitted' then
begin
// 处理表单提交
// 可以从message.ArgumentList中获取数据
end;
end;
示例3:自定义资源处理
text
unit uResourceHandler;
interface
uses
Classes, SysUtils, cef3intf, cef3types, cef3api;
type
TCustomResourceHandler = class(TCefResourceHandlerOwn)
private
FStream: TMemoryStream;
FStatus: Integer;
FStatusText: ustring;
FMimeType: ustring;
protected
function ProcessRequest(const request: ICefRequest; const callback: ICefCallback): Boolean; override;
procedure GetResponseHeaders(const response: ICefResponse; out responseLength: Int64;
out redirectUrl: ustring); override;
function ReadResponse(const dataOut: Pointer; bytesToRead: Integer;
var bytesRead: Integer; const callback: ICefCallback): Boolean; override;
public
constructor Create(const browser: ICefBrowser; const frame: ICefFrame;
const schemeName: ustring; const request: ICefRequest); override;
destructor Destroy; override;
end;
implementation
constructor TCustomResourceHandler.Create(const browser: ICefBrowser;
const frame: ICefFrame; const schemeName: ustring; const request: ICefRequest);
begin
inherited;
FStream := TMemoryStream.Create;
end;
destructor TCustomResourceHandler.Destroy;
begin
FStream.Free;
inherited;
end;
function TCustomResourceHandler.ProcessRequest(const request: ICefRequest;
const callback: ICefCallback): Boolean;
var
Url: ustring;
HtmlContent: string;
begin
Result := True;
Url := request.Url;
// 根据URL生成自定义内容
if Pos('custom://app/dashboard', Url) > 0 then
begin
HtmlContent := '<html><head><title>仪表板</title></head>' +
'<body><h1>欢迎使用自定义应用</h1>' +
'<p>这是通过fpCEF3提供的自定义内容</p></body></html>';
FStream.WriteBuffer(Pointer(HtmlContent)^, Length(HtmlContent));
FStream.Position := 0;
FStatus := 200;
FStatusText := 'OK';
FMimeType := 'text/html';
end
else
begin
FStatus := 404;
FStatusText := 'Not Found';
FMimeType := 'text/plain';
end;
callback.Cont;
end;
procedure TCustomResourceHandler.GetResponseHeaders(const response: ICefResponse;
out responseLength: Int64; out redirectUrl: ustring);
begin
response.Status := FStatus;
response.StatusText := FStatusText;
response.MimeType := FMimeType;
responseLength := FStream.Size;
end;
function TCustomResourceHandler.ReadResponse(const dataOut: Pointer;
bytesToRead: Integer; var bytesRead: Integer; const callback: ICefCallback): Boolean;
begin
bytesRead := FStream.Read(dataOut^, bytesToRead);
Result := bytesRead > 0;
end;
高级应用场景
1. 桌面应用现代化
- 将传统Pascal应用界面迁移到HTML/CSS/JavaScript
- 创建混合桌面应用
- 集成现代Web技术栈
2. 嵌入式Web视图
- 在现有应用中嵌入Web内容
- 创建配置界面
- 显示实时数据仪表板
3. 应用内浏览器
- 实现自定义浏览器功能
- 控制导航和页面加载
- 管理用户会话和数据
优势与挑战
优势
- 性能强大:基于Chromium引擎,提供现代浏览体验
- 功能丰富:支持HTML5、CSS3、WebGL等最新Web标准
- 开发效率:使用熟悉的Pascal语言进行开发
- 社区支持:活跃的Pascal开发者社区
挑战
- 应用体积:需要包含CEF二进制文件,增加应用大小
- 内存占用:Chromium引擎相对占用较多内存
- 更新维护:需要定期更新CEF版本以获取安全补丁
最佳实践
- 资源管理:确保正确释放CEF资源
- 错误处理:实现完善的异常处理机制
- 性能优化:合理使用多进程架构
- 安全考虑:实施适当的内容安全策略
结语
fpCEF3为Pascal开发者打开了一扇通往现代Web技术的大门。通过这个框架,开发者可以在保持Pascal开发习惯的同时,充分利用Chromium引擎的强大功能。无论是现代化遗留应用,还是创建全新的混合应用,fpCEF3都提供了一个可靠且功能丰富的解决方案。
项目持续活跃开发中,建议关注GitHub仓库以获取最新更新和示例代码。对于希望将Web技术集成到Pascal应用中的开发者来说,fpCEF3无疑是一个值得尝试的优秀工具。
fpCEF3.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载




还没有评论,来说两句吧...