Script.NET的很多界面都是采用的Tcl+Html的方式编写的,现在越来越多的本地应用程序中都采用了类似的html作为界面表现形式的方法,例如: Visual Studio 7以上的起始页面、Outlook的起始页面、QQ程序中的很多界面、
CodeGear Delphi for PHP的起始页面等等。
我觉得用Html做本地界面有下面几个好处:
1、Html界面通过Javascript、图片等修饰之后可以做的很漂亮,而且很方便就可以做到各种动态效果;
2、代码简单,并且有大量可以参考的例子,用C++写一大堆代码可能Html只有短短的几行就可以做到了;
3、修改方便,改一下页面文件就可以马上看到效果。

当然也有很多缺点:
1、本地代码和页面之间的交互比较困难;
2、有时候本地代码很简单可以实现的,在Html中可能很复杂或者基本无法实现,对于这部分代码可以在本地代码中实现,由Html来调用;
3、页面的局部刷新比较困难(如果要解决可以参考AJAX的思路)。

Script.NET从1.0版本开始就已经大量采用了这种编程方法,并封装了一个简单的Tcl库,我在自己负责开发的几个项目中都应用了这种方法。Script.NET 2.0版本中对这种方法进一步完善,封装了一整套本地web界面开发的类库(TclFace),关于TclFace的详细原理和用法以后会详细说明,下面主要介绍Script.NET 1.0中的TPageMake界面生成类。

Script.NET页面编程是指在Script.NET环境下编写基于Html页面的应用,这和动态网页(ASP/PHP/JSP等) 的概念有些类似,不同的是动态网页是基于网络的应用,动态网页脚本是在服务器端运行的,由服务器端脚本生成WEB页面之后送到客户端浏览。Script.NET页面编程则是完全在客户端运行的一种动态网页,由Script.NET客户端的某种脚本(目前只支持Tcl脚本)直接在客户端生成页面,然后在Script.NET中浏览。这种客户端动态生成页面的好处是可以不用花费很大的精力去编写各种复杂的界面,而是一律用页面的形式来表示各种界面,因为Html页面内容非常丰富,可以满足各种复杂界面需求,而且界面风格统一,可以象做网页那样做出非常好看的界面,修改起来也非常方便,工作量相比C++来说应该会小一些。

Script.NET页面编程的原理是将通过Html模板和用户数据来生成页面,生成一个页面需要由模板文件、用户脚本、用户数据、页面生成器几个部分来配合完成。模板文件就是Html页面的模板,一般是由网页开发人员先创作一个原型页面,然后将原型页面改造为模板,改造的方法是按照Script.NET页面模板的要求在页面中加一些特殊标记。用户数据可能是来源于用户的某个数据库或别的地方,例如做一个日志的页面应用,则用户数据就是日志数据库,对数据库的读写操作可以通过ADO等方式,Script.NET 中封装了一个Tcl的ADO模块,可以方便的通过Tcl脚本来访问各种数据库。用户脚本负责将模板和用户数据组合在一起生成最终的页面,页面生成器则负责最终的页面生成,是被用户脚本来调用的。

一般来说一个页面对应了两个模板文件,后缀分别是.tph和.tpf,.tph文件是原型页面经过改造后的文件,生成的页面就是在tph文件的基础上替换其中一些标记和生成的,tpf文件是一些标记的替换集合,存储的是每一种标记对应的一段替换文本,这些替换文本也可以存在其他的标记,实际上如果不要tpf文件也是可行的,但是这样就要把替换内容都写到生成脚本中,灵活性就会降低,因为如果写到 tpf文件中,则只要修改tpf文件中的替换内容,就可以修改生成的页面的风格。

tph文件中替换标记的格式为"%标记名%",也就是用两个%包围的一个标记名字,例如下面这一段中的 %TABLE_ALL%:

<TABLE cellSpacing=0 cellPadding=5 width="100%" border=0>
%TABLE_ALL%
</TABLE>

tpf文件中每一个用于替换的段落用[替换名]...内容...[/替换名]来表示,在各个替换段之间可以有注释,注释的格式为#开头的文字,例如下面这一段就是tpf文件中的一个替换段,替换名为TR_VAR_LINE,并且其中还可以有替换标记:

# 用于表示变量的表格行
[TR_VAR_LINE]
<TR>
<TD class=text_all bgColor=#ffffff>%NAME%</TD>
<TD class=text_all bgColor=#ffffff>%VALUE%</TD>
</TR>
[/TR_VAR_LINE]

可以参考FtpClient演示工程中的FTP页面的模板文件。

页面生成器为一个iTcl类,类定义如下:

#-------------------------------------------------------------
# TPageMake class define
#-------------------------------------------------------------
::itcl::class  TPageMake {
constructor {targetHtml templateHtml templateFile} {};
destructor {};
### data member ###
private variable _targetHtml;   #目标页面
private variable _templateHtml; #模板页面
private variable _templateFile; #模板文件
private variable _tclTr;        #存储Tr的Tcl内部变量
private variable _targetVarList;#存储目标页面中所有变量
### public methods ###
#添加表格项到内部标记变量_tclTr
public method  AppendItemFromTpf {tagTr {names ""} {values ""}}
#标记段存储到目标缓冲区中
public method  SaveToTargetBuf {tagTr {cleartag "-cleartag"}}
#替换目标缓冲区中的一个标记
public method  ReplaceTargetTr {tagTr replaceTr}
#创建目标页面
public method  MakeTargetHtml {}
#从目标页面中读取所有变量信息
public method  LoadTargetHtmlVar {}
#将指定变量信息写入目标缓冲区
public method  SaveTargetVar {varName varValue}
#获取目标页面中指定变量的值
public method  GetTargetVar {varName}
}

构造函数的参数有3个,分别为要生成的目标页面文件、tph文件和tpf文件。除了一些用于生成页面的函数之外,这个类还有一些函数用于存取目标页面中存储的一些变量,这些变量存放在html文件的注释中,这样对页面是没有任何影响的,之所以提供在页面中存储变量的方法,是因为这种页面编程中,脚本的作用创建页面,一旦一个页面创建完成,则脚本就会结束,而脚本解释器中的内部状态信息等变量也会随着脚本的结束而消失,下一次生成页面再调用脚本的时候也就无法记住以前的信息,但有时候我们确实需要获得以前的信息,例如FTP应用中需要记住FTP的地址和上一次的访问路径,因此才提供了这种在页面中保存变量的方法,在脚本结束之前把变量存储在目标页面的注释中,下一次启动脚本以后就可以从页面中读取上一次存储的信息。存储的变量的格式为如下:

<!-- varName=varValue -->

下面是一个页面编程的应用实例,tph模板文件如下:

<HTML><HEAD><TITLE>表格演示</TITLE>
<BODY>
<TABLE>
%TABLE_ALL%
</TABLE>
</BODY>
</HTML>

其中%TABLE_ALL%是用于替换的标记,这个例子中tph文件已经搭了一个表格的框架,只要填内容就可以了,因此我们的目的就是将%TABLE_ALL%替换为一个表格的内容。

tpf模板文件如下:

# 表格的标题行
[TABLE_WITH_TITLE]
<TR>
<TD>%COL1%</TD>
<TD>%COL2%</TD>
</TR>
%ROW%
[/TABLE_WITH_TITLE]
# 表格行
[TABLE_ROW]
<TR>
<TD>%COL1%</TD>
<TD>%COL2%</TD>
</TR>
[/TABLE_ROW]

这里有两种替换段,分别是表格的标题和内容。

生成脚本的例子如下:

source "$platform_path/lib/plat/pagemake.tcl";
#-------------------------------------------------------------
#   main
#-------------------------------------------------------------
if {[itcl_info objects pageMake -class TPageMake] != "pageMake"} {
set _htmlCurrentFile "$platform_path/Samples/page/demo1.htm"
TPageMake pageMake  "$ _htmlCurrentFile" /
"$platform_path/Samples/page/demo1.tph" /
"$platform_path/Samples/page/demo1.tpf";
}
# 创建标题行
set value [list "列1" "列2" "%TABLE_ROW%"];
pageMake AppendItemFromTpf "TABLE_WITH_TITLE" {"COL1" "COL2" "ROW"} $value;
pageMake SaveToTargetBuf "TABLE_ALL" -append;
# 创建表格内容行
set value [list "1-1" "1-2"];
pageMake AppendItemFromTpf "TABLE_ROW" {"COL1" "COL2"} $value;
set value [list "2-1" "2-2"];
pageMake AppendItemFromTpf "TABLE_ROW" {"COL1" "COL2"} $value;
pageMake SaveToTargetBuf "TABLE_ROW";
# 存储到缓冲区
pageMake SaveToTargetBuf "TABLE_ALL";
# 生成页面
pageMake MakeTargetHtml;
# 释放生成器
::itcl::delete object pageMake;
::itcl::delete class TPageMake;
# 设置页面转移
set _htmlNewURL "$platform_path/Samples/page/demo1.htm";

最后创建的页面如下所示:

列1 列2
1-1 1-2
2-1 2-2

 Script.NET 1.0采用Tcl+Html的方式编写的一些界面截图如下:

Script.NET 1.0版本的Tcl+Html界面编程原理相关推荐

  1. 创建界面_《魔兽世界》智慧烈风buff延长 9.0版本角色创建界面改动

    据暴雪发布的消息,原定于下周一结束的<魔兽世界>100%经验buff活动时间将会延长.此外,外媒报道称9.0版本的角色创建界面做出了一些改动,一起来了解下吧. 在3月末<魔兽世界&g ...

  2. Jeecgboot-Vue3 v1.2.0 版本正式发布,企业级低代码平台

    项目介绍 Jeecgboot-Vue3 采用 Vue3.0.Vite. Ant-Design-Vue.TypeScript 等新技术方案,包括二次封装组件.utils.hooks.动态菜单.权限校验. ...

  3. Tvori推出2.0版本,让VR动画制作更简单

    升级后的Tvori已经变成了一个VR动画制作利器. VR动画制作工具Tvori去年一上线,便得到不少创作者的认可.最近,Tvori迎来了2.0版本,其操作界面.场景以及功能都发生了重大的改变,这一次将 ...

  4. PDF阅读器 2.0.0.0版本

    仿WPS PDF阅读器 2.0.0.0版本 文章目录 仿WPS PDF阅读器 2.0.0.0版本 简述 功能 1.0.0.0版本功能 2.0.0.0版本功能 效果图 工程文件 结尾 PDF 1.0.0 ...

  5. 打造沉浸空间,vivo i音乐10.0版本回归音乐本质

    近日,OriginOS原系统下赋能的vivo i音乐携无缝播放与动效收藏两大核心功能点再度上新,以用户体验为出发点,vivo i音乐在让用户体验变的更加轻盈流畅.深度沉浸的同时,也凭借简洁轻快的版本设 ...

  6. 多多自走棋改动_《多多自走棋》2.0版本有哪些改动 2.0版本更新改动内容汇总...

    导 读 多多自走棋将于近期进行一次大型改版,全新的2.0版本会在体验服更新,完成测试后就会在正式服实装了.那么,多多自走棋2.0版本有什么新内容呢?下面就是多多自走棋体验服更新前瞻了,小伙伴们都来看看 ...

  7. ecshop 商品颜色尺寸仿淘宝选择功能教程(2.7.0版本)

    牵涉到的修改文件(default模板为例) /themes/default/style.css /themes/default/goods.dwt 注:此路径待修改模板路径. 修改步骤: 一:控制样式 ...

  8. 大华供应链管理平台_files_锦江全球采购平台SRM系统2.0版本上线 打造更智能的供应链...

    近期,由甄云科技携手全球知名酒店品牌供应链企业上海锦江联采供应链有限公司,共同打造的SRM2.0项目,在双方的不懈努力下,成功上线,意味着上海锦江联采供应链有限公司正式迈入采购数字化新时代. 锦江全球 ...

  9. 飞机大战小游戏1.0版本

    小时候大家应该都玩过飞机大战吧,这就是仿的一个飞机大战,但是没有写的很全,只能玩一次,死掉之后需要刷新页面玩第二次,话不说多,上代码: 初始页面: 整个的html代码还是很少,如下: <div ...

  10. pytorch gather_【Pytorch】Pytorch-1.1.0 版本新特性

    2019年05月01日,Pytorch 1.1.0 版本正式发布啦~https://github.com/pytorch/pytorch/releases/tag/v1.1.0 主要的几个功能: 1. ...

最新文章

  1. 2020腾讯广告算法大赛分享(冠军)
  2. Linux中的进程之初步了解
  3. 从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析
  4. iOS10 CallKit简单开发
  5. winfrom导出DataGridView为Excel方法
  6. Docker学习文档之三 其他相关-Docker常用命令
  7. 高德上线 “家人地图”功能 家人可随时查看彼此的位置
  8. 公益图书馆-学习笔记五-jquery来动态设置div高度
  9. 301重定向错误(细心就不应该出错)
  10. 淘宝面试题:小白鼠与毒药
  11. 移动技术--从网页游戏谈起1--网页游戏的兴起和现状
  12. android热敏打印机图片乱码,小票打印机常见故障及解决方法,小票打印机打印乱码怎么办...
  13. 计算机组成原理中CPI、MIPS、CPU执行时间、主频等计算
  14. 如何使用一键回录游戏视频
  15. java 合并pdf_用iText分割和合并pdf文件
  16. 【7gyy】高手分享辨别电脑病毒技巧
  17. 清橙OJ 1082 查找第K小元素 -- 快速排序
  18. 电子商务时代的网络营销
  19. android 轨迹生成图,Android自定义View实现公交成轨迹图
  20. Android多语言切换(兼容安卓9、10)

热门文章

  1. oracle solaris 10 是什么,Oracle Solaris 10 操作系统
  2. 最新Axure谷歌浏览器Chrome扩展程序安装方法
  3. VS Code 运行时会弹出Unins000.Exe目标目录创建文件错误
  4. rollup函数 和cube函数 的区别?
  5. 交通灯控制——汇编小设计
  6. python云台控制原理_python伺服云台摄像头图像作为背景
  7. 机器学习算法——决策树3(CART决策树算法)
  8. C4.5和CART决策树对比
  9. Opencv摄像头相关参数
  10. CentOS7镜像安装与下载