Delphi APP 里面使用 HTML5 来做帮助文档
Delphi 自己的 TLabel 或者 TText 用来显示富文本,是不够的。要显示富文本,用 HTML 是一个比较好的选择。
最直接的做法,是将帮助文档用 HTML 的格式做好,在 APP 里面嵌入一个 TWebBrowser 来显示 HTML 页面。
HTML 页面的来源:标准做法,是开发一个 WEB 网站,把帮助文件放进去。APP 里面,打开浏览器去访问网站对应的 URL 就可以了。
但是,在手机不能联网的时候,打开帮助,就只能看到空白页面。用户体验不好。
问题:启动 APP,进入帮助界面,不管手机是否能上网,都要能看到帮助文档。
办法:将帮助文档的内容,和 APP 一起打包放进手机里面,浏览器访问本地文件。
问题:一个帮助页面,可能要引用很多文件,比如 css 文件,比如 js 文件,比如 jpg 文件。等等。这给 APP 发布打包带来很多麻烦。而且帮助页面可能是很多个页面,引用的文件会非常多。
办法:将页面内容(包括所有需要用到的文件)都放进一个数据库;在 APP 里面内置一个 WebServer 和一个自己写的 CGI,这个自己写的 CGI 代码负责响应浏览器页面请求,从数据库里获得相关文件输出给浏览器。这样只需要发布一个数据库文件就足够。
这里就是做一个 Stand-Alone 模式的 WebBroker 程序,这个程序内置了一个 Web Server 响应浏览器的 URL 的请求,不需要安装其它的 Web Server (比如 APACHE)
按照上述办法,开始构思和开发:
1. 数据库:Delphi 支持的在手机里运行的数据库是 SQLite 数据库。一个库文件,可以有多个表。这样,各种数据,一个文件搞定。APP 打包发布时简单很多。
1.1. 创建数据库,在数据库里面创建表,等等操作,有一个免费工具(个人使用免费,商业应用要购买):http://www.sqliteexpert.com/
1.2. 如果你对 SQLite 数据库很熟悉,也可以直接用 Delphi 代码来创建库和表:http://docwiki.embarcadero.com/RADStudio/Berlin/en/Mobile_Tutorial:_Using_FireDAC_and_SQLite_(iOS_and_Android)
1.3. 我这里创建了 2 个表。一个用于存放页面文件;一个用于存放页面里需要引用的文件诸如 css, js, jpg 等等。存文件的表的字段类型是 Blob。
1.4. 在 Delphi 底下访问 SQLite 使用 FireDAC 那套数据库控件。
2. 写一个简单的基于 VCL 的程序,用于将各种文件放进数据库。其实这里最核心的操作就是对存放文件的 Blob 字段做一个操作:TBlobField(FieldByName('HTML')).LoadFromFile('abc.html');
2.1. 将来在制作帮助内容的时候,将写好并调试好的页面,以及页面引用到的一些文件,全部用这个程序导入到数据库里面。
3. 新建一个 WebBroker 程序(这里选 Windows,而不是 Unix),在主界面上放一个 TWebBrowser。然后在 TWebModule1 里面写代码,响应浏览器的请求,根据请求的文件,去数据库里找到相关的内容,用 Response.Content 输出。
3.1. 因为是输出文件,直接用 Response.ContentStream := AStream 的方式。
3.2. HTML 页面内容,如果用 Response.Content := HTMLString; 的方式,用字符串输出,如果页面是 UTF8 的,出来一片乱码。因此,这里也直接输出页面的二进制文件流。不过这里要注意,不能写 Response.ContentType := 'text/html'; 写了,浏览器反倒无法判断 Charset 是 UTF-8 了,虽然页面头里面有关于 Charset 的设置。反而 Response.ContentType := ''; 空值,页面显示正常。
3.3. 在 Windows 底下开发,运行测试,很方便也很快速。
4. 重点来了:移植这个 WebBroker 程序到 FireMonkey APP 程序里面,稍微有点麻烦。Delphi 目前直接创建 WebBroker 的程序,只支持 Windows,编译选项里无法添加 Android 平台。
4.1. 新建一个 FireMonkey APP 的工程。这个工程是可以编译为 Android APP 的(当然也可以编译为 iOS APP);
4.2. 将之前开发的 WebBroker 程序的 TWebModule1 添加到工程里。
4.3. 因为这样的程序需要用到 Web.WebReq, IdHTTPWebBrokerBridge, Web.WebBroker 这三个单元,但这三个单元在编译目标设置为 Android 时,Delphi 干脆无法找到这三个单元,说明这三个单元只支持 Windows。因此:
4.3.1. 将这三个单元拷贝到这个工程的当前目录底下;然后将这三个文件都加入到工程里面。这样编译时就是直接使用当然工程目录下的源文件,而不是 Delphi 自己的目录底下的。
4.3.2. 将这三个单元里面的 Winapi.Windows 的声明,屏蔽掉。然后编译,发现直接通过。也就是它们的源代码里面并没有用到 Winapi.Windows 里面声明的东西。
4.4. 在 Delphi IDE 的菜单 Project - Deployement 出来的界面里,添加数据库文件,设置其 Remote Path 为 assets\internal\
4.5. 增加代码,让程序能够找到这个数据库文件。我的数据库文件名是:MyDoc.db,这里的代码是:
procedure TForm1.FDConnection1BeforeConnect(Sender: TObject);
begin
FDConnection1.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'MyDoc.db');
end;
4.6. 编译发布到手机里面,运行,直接闪退。
4.7. 既然能编译通过,说明之前修改的和 WebBroker 以及内置 Web Server 相关的代码并没有用到 Windows 的函数。那么,这个闪退是什么情况?
4.7.1. 在工程文件源代码里面设置断点,在 Debug 模式下连接手机运行代码,发现 Application.Initialize 出错。仔细检查,发现因为引用了 Web.WebBroker,这个单元里也有一个叫 Application 的东西。因此,将这里的 Application 都加上前缀变成 FMX.Forms.Application 避免名字冲突。搞定。运行正常了。
Delphi 自己的 TLabel 或者 TText 用来显示富文本,是不够的。要显示富文本,用 HTML 是一个比较好的选择。
最直接的做法,是将帮助文档用 HTML 的格式做好,在 APP 里面嵌入一个 TWebBrowser 来显示 HTML 页面。
HTML 页面的来源:标准做法,是开发一个 WEB 网站,把帮助文件放进去。APP 里面,打开浏览器去访问网站对应的 URL 就可以了。
但是,在手机不能联网的时候,打开帮助,就只能看到空白页面。用户体验不好。
问题:启动 APP,进入帮助界面,不管手机是否能上网,都要能看到帮助文档。
办法:将帮助文档的内容,和 APP 一起打包放进手机里面,浏览器访问本地文件。
问题:一个帮助页面,可能要引用很多文件,比如 css 文件,比如 js 文件,比如 jpg 文件。等等。这给 APP 发布打包带来很多麻烦。而且帮助页面可能是很多个页面,引用的文件会非常多。
办法:将页面内容(包括所有需要用到的文件)都放进一个数据库;在 APP 里面内置一个 WebServer 和一个自己写的 CGI,这个自己写的 CGI 代码负责响应浏览器页面请求,从数据库里获得相关文件输出给浏览器。这样只需要发布一个数据库文件就足够。
这里就是做一个 Stand-Alone 模式的 WebBroker 程序,这个程序内置了一个 Web Server 响应浏览器的 URL 的请求,不需要安装其它的 Web Server (比如 APACHE)
按照上述办法,开始构思和开发:
1. 数据库:Delphi 支持的在手机里运行的数据库是 SQLite 数据库。一个库文件,可以有多个表。这样,各种数据,一个文件搞定。APP 打包发布时简单很多。
1.1. 创建数据库,在数据库里面创建表,等等操作,有一个免费工具(个人使用免费,商业应用要购买):http://www.sqliteexpert.com/
1.2. 如果你对 SQLite 数据库很熟悉,也可以直接用 Delphi 代码来创建库和表:http://docwiki.embarcadero.com/RADStudio/Berlin/en/Mobile_Tutorial:_Using_FireDAC_and_SQLite_(iOS_and_Android)
1.3. 我这里创建了 2 个表。一个用于存放页面文件;一个用于存放页面里需要引用的文件诸如 css, js, jpg 等等。存文件的表的字段类型是 Blob。
1.4. 在 Delphi 底下访问 SQLite 使用 FireDAC 那套数据库控件。
2. 写一个简单的基于 VCL 的程序,用于将各种文件放进数据库。其实这里最核心的操作就是对存放文件的 Blob 字段做一个操作:TBlobField(FieldByName('HTML')).LoadFromFile('abc.html');
2.1. 将来在制作帮助内容的时候,将写好并调试好的页面,以及页面引用到的一些文件,全部用这个程序导入到数据库里面。
3. 新建一个 WebBroker 程序(这里选 Windows,而不是 Unix),在主界面上放一个 TWebBrowser。然后在 TWebModule1 里面写代码,响应浏览器的请求,根据请求的文件,去数据库里找到相关的内容,用 Response.Content 输出。
3.1. 因为是输出文件,直接用 Response.ContentStream := AStream 的方式。
3.2. HTML 页面内容,如果用 Response.Content := HTMLString; 的方式,用字符串输出,如果页面是 UTF8 的,出来一片乱码。因此,这里也直接输出页面的二进制文件流。不过这里要注意,不能写 Response.ContentType := 'text/html'; 写了,浏览器反倒无法判断 Charset 是 UTF-8 了,虽然页面头里面有关于 Charset 的设置。反而 Response.ContentType := ''; 空值,页面显示正常。
3.3. 在 Windows 底下开发,运行测试,很方便也很快速。
4. 重点来了:移植这个 WebBroker 程序到 FireMonkey APP 程序里面,稍微有点麻烦。Delphi 目前直接创建 WebBroker 的程序,只支持 Windows,编译选项里无法添加 Android 平台。
4.1. 新建一个 FireMonkey APP 的工程。这个工程是可以编译为 Android APP 的(当然也可以编译为 iOS APP);
4.2. 将之前开发的 WebBroker 程序的 TWebModule1 添加到工程里。
4.3. 因为这样的程序需要用到 Web.WebReq, IdHTTPWebBrokerBridge, Web.WebBroker 这三个单元,但这三个单元在编译目标设置为 Android 时,Delphi 干脆无法找到这三个单元,说明这三个单元只支持 Windows。因此:
4.3.1. 将这三个单元拷贝到这个工程的当前目录底下;然后将这三个文件都加入到工程里面。这样编译时就是直接使用当然工程目录下的源文件,而不是 Delphi 自己的目录底下的。
4.3.2. 将这三个单元里面的 Winapi.Windows 的声明,屏蔽掉。然后编译,发现直接通过。也就是它们的源代码里面并没有用到 Winapi.Windows 里面声明的东西。
4.4. 在 Delphi IDE 的菜单 Project - Deployement 出来的界面里,添加数据库文件,设置其 Remote Path 为 assets\internal\
4.5. 增加代码,让程序能够找到这个数据库文件。我的数据库文件名是:MyDoc.db,这里的代码是:
procedure TForm1.FDConnection1BeforeConnect(Sender: TObject);
begin
FDConnection1.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'MyDoc.db');
end;
4.6. 编译发布到手机里面,运行,直接闪退。
4.7. 既然能编译通过,说明之前修改的和 WebBroker 以及内置 Web Server 相关的代码并没有用到 Windows 的函数。那么,这个闪退是什么情况?
4.7.1. 在工程文件源代码里面设置断点,在 Debug 模式下连接手机运行代码,发现 Application.Initialize 出错。仔细检查,发现因为引用了 Web.WebBroker,这个单元里也有一个叫 Application 的东西。因此,将这里的 Application 都加上前缀变成 FMX.Forms.Application 避免名字冲突。搞定。运行正常了。
结果:在 Android 手机上运行正常,浏览器能正确显示页面内容。虽然 Delphi 没有直接支持在 Android APP 里面内置 Stand-Alone 的 WebBroker 程序的功能,但移植还是很容易的。
这个 APP 没有在 iOS 底下测试过。不过我在 iOS 底下测试了原生的 iOS APP 支持在手机本地打开一个 TCP Server 的端口并且外面能连接上这个端口。因此,理论上,本程序编译到 iOS 上是能够正常工作的。有谁在 iOS 下测试了请通知我。谢谢!
又及:源代码将发布到 csdn 的资源下载里面。