2023年2月



回顾
Visio
的对象

l

Application 对象

l

Window 对象

l

Document 对象

l

Page 对象

l

Master 对象

l

Shape 对象

l

Cell 对象




Visio
对象还有

l

Selection 对象

l

Connects 对象

l

Style 对象

l

Keyboard

l

Mouse

l

DataRecordset



Application
对象的事件

l

右键菜单: MarkerEvent

l

程序退出前: BeforeQuit

l

模态窗口关闭后: AfterModal

l

模态窗口出现前: BeforeModal

l

Visio 事件完成:
NoEventsPending

l

程序激活: AppActivated

l

程序挂起前: BeforeSuspend

l

进入获取退出 ScopesEnterScope/ExitScope

l

用户动作响应提示: QueryCancelQuit

l

… …



Window
对象的事件

l

窗口打开: WindowOpened

l

窗口改变: WindowChanged

l

窗口关闭前: BeforeWindowClosed

l

窗口关闭取消: WindowCloseCanceled

l

窗口选区 Shape 被删除: BeforeWindowSelDelete

l

窗口页面改变前: BeforeWindowPageTurn

l

窗口页面改变后: WindowTurnedToPage

l

Visio 窗口改变:
WindowActivated

l

… …



Document
对象事件

l

文档添加: DocumentAdded

l

文档创建: DocumentCreated

l

打开文档: DocumentOpened

l

文档改变: DocumentChanged

l

文档保存: DocumentSaved

l

文档关闭: BeforeDocumentClose

l

… …



Page
对象事件

l

页面添加: PageAdded

l

页面改变: PageChanged

l

页面删除: BeforePageDelete

l

取消页面删除: PageDeleteCanceled

l

… …



Shape
对象事件

l

Shape 删除前:
BeforeShapeDelete

l

Shape 添加:
ShapeAdded

l

Shape 改变:
ShapeChanged

l

Shape 删除后:
ShapesDeleted

l

Shape 文本编辑:
BeforeShapeTextEdit

l

Shape 文本编辑退出:
ShapeExitedTextEdit

l

Shape 连接添加:
ShapeLinkAdded

l

Shape 连接删除:
ShapeLinkDeleted

l

Shape 组合变化:
ShapeParentChanged



Master
对象事件

l

模具添加: MasterAdded

l

模具改变: MasterChanged

l

模具删除: BeforeMasterDelete

l

取消模具删除: MasterDeleteCanceled

l

模具删除提示: QueryCancelMasterDelete

l

… …



Cell
对象事件

l

Cell 的值改变:
CellChanged

l

Cell
formula
改变:
FormulaChanged



Selection
对象事件

l

选区删除前: BeforeSelectionDelete

l

选区删除提示: QueryCancelSelectionDelete

l

选区增加: SelectionAdded

l

选区改变: SelectionChanged

l

选区取消: SelectionDeleteCanceled

l

… …



Connects
对象事件

l

连接添加: ConnectionsAdded

l

连接移除: ConnectionsDeleted



Style
对象事件

l

Style 添加:
StyleAdded

l

Style 改变:
StyleChanged

l

Style 删除前:
BeforeStyleDelete

l

Style 取消删除:
StyleDeleteCanceled

l

Style 删除提示:
QueryCancelStyleDelete




Keyboard
对象事件

l

KeyDown

l

KeyPress

l

KeyUp



Mouse
对象事件

l

MouseDown

l

MouseMove

l

MouseUp



事件的处理

l

实现接口 IVisEventProc

n

public class EventSink : IVisEventProc

l

使用 AddAdvise 建立事件侦听

n

documentEvents.AddAdvise( (unchecked((short)VisEventCodes.visEvtAdd) + (short)VisEventCodes.visEvtShape), (IVisEventProc)this, sink, "ShapeAdd");

l

实现 object IVisEventProc.VisEventProc() 函数,和具体处理函数挂钩

随着信息技术的发展,传统的关系数据库(如关系型数据库)功能已不能满足当今信息系统中对时态信息处理能力的需求。而时态数据库理论的完善和发展为解决时态信息处理问题提供了一个很好的解决方案。

什么是时态数据库?
区别于传统的关系型数据库(RDBMS),时态数据库(Temporal Database)主要用于记录那些随着时间而变化的值的历史,而这些历史值对应用领域而言又是重要的,这类应用有:金融、保险、预订系统、决策支持系统等。
目前时态数据库还没有像如Oracle、SQL Server等大型关系数据库那样的产品。在当前时态数据库技术尚未完全成熟的现状下,DBMS提供商不会轻易把时态处理功能引入现有的DBMS中,因此,利用成熟的RDBMS数据库,建立时态数据库的中间件,在现阶段是一个较好的选择,因此就应运而生TimeDB和TempDB了。
国外的TimeDB(

http://www.timeconsult.com/Software/Software.html
)是一种结合关系型数据库来实现时间数据库应用的技术,它支持时态数据库脚本:ATSQL2 [SBJS96a,SBJS96b,SBJS98]。它可以认为是关系数据库的一个前端,把时态数据库语句转换为关系型数据库的脚本进行执行,它的运用场景如下所示。
TimeDBArchiture.jpg
国内的TempDB也是一种类似的技术应用,支持ATSQL2,和TimeDB类似,都是基于目前非常成熟的关系型数据库基础上的应用。
时态数据库中间件不改变现有商业DBMS的结构和功能,而是作为一个上层构件添加到商业DBMS之上,应用程序之下,形成一个中间层结构。这个中间层结构能处理时态结构化查询语言(ATSQL2),把它转换成下层DBMS能理解的标准SQL语言(如P-SQL)并在商业DBMS中执行。

时态数据库理论的基本概念
时态数据库理论提出了三种基本时间:用户自定义时间、有效时间和事务时间。同时把数据库分为四种类型:快照数据库、回滚数据库、历史数据库和双时态数据库。
时态数据库理论提出了三种基本时间:用户自定义时间、有效时间和事务时间。同时把数据库分为四种类型:快照数据库、回滚数据库、历史数据库和双时态数据库。

用户自定义时间
:指用户根据自己的需要或理解定义的时间。时态数据库系统不处理用户自己定义的时间类型。因此,用户自定义时间是和应用相关的,不在时态数据库处理的范围之内。

有效时间(Valid-Time):
指一个对象在现实世界中发生并保持的时间,即该对象在现实世界中语义为真的时间,包含Valid-From和Valid-To两个值。它可以指示过去、现在和未来。例如,考虑事实“小明从2003年到2007年是大学生”,那么时间区间[2003, 2007]是事实“小明是大学生”的有效时间区间,该事实在该时间区间内为真。有效时间可以是时间点、时间点的集合、时间区间或者时间区间的集合,或者是整个时间域。有效时间由时态数据库系统解释并处理,在查询的过程中对用户透明。用户也可以显式地查询和更新有效时间。

事务时间(Transaction-Time):
指一个数据库对象发生操作的时间,是一个事实存储在数据库、或者在数据库中发生改变的时间,包含Transaction-From和Transaction-To两个值。当用户对数据库状态进行更改时,会产生各种操作历史,事务时间真实地记录了数据库状态变更的历史。有时也称事务时间为系统时间。

快照数据库:
快照数据库是反映现实世界某一瞬间情况的数据模型。它记录了特定时刻的数据库状态。快照数据库采用这样的假设:一个存储在数据库中的元组,一定是真实世界中的有效事实。
 历史数据库:数据库中被管理对象的生命周期是对象的有效时间,每一个元组记录了数据的一个“历史”状态。历史数据库中没有约束时间的表示方法,可以是时间点的集合、时间区间或者区间集合等形式表示。

回滚数据库:
数据库中被管理对象的生命周期是事务时间的数据库。它保存了数据库中事务提交、状态演变的历史状态。

双时态数据库:
数据库中元组包含一个系统支持的有效时间和一个系统支持的事务时间的数据库,称为双时态数据库。双时态数据库具备了快照数据库、历史数据库和回滚数据库的特点,存储了现实世界和数据库系统的变更历史。

Now:
Now的中文意思是当前时间,是一个时间变元,随着当前时间的变化而变化,记录了随时间变化的信息,它的有效值依赖于当前时间。

时态数据库脚本ATSQL的使用
时态数据处理构件根据ATSQL2的语法引入了Now、Beginning和Forever三个变元。Beginning和Forever分别表示时态数据处理构件所能表示的时间起点和终点。Now表示当前时间。每次执行操作时必须使Now绑定到一个固定的值(操作执行的当前时间),这样后继操作才能正常进行。在下面的ATSQL2中表示的这几个单词是具有具体的含义的。
ATSQL2的数据定义语句包括以下几项功能:创建表、创建视图、删除表、删除视图。
ATSQL2语言和普通SQL语句一样,使用“create table”关键字创建数据库表,关键字“as validtime”用于指示系统创建具有有效时间支持的数据库表。

1. 创建员工表Employee, 是在标准的创建表SQL结尾,加入AS VALIDTIME关键字即可。


CREATE

TABLE
Employee(

ID

VARCHAR
(
30
)
NOT

NULL
,

NAME

VARCHAR
(
50
)
NOT

NULL
)

AS
VALIDTIME;

2. 插入一条记录的ATSQL, 需要通过VALIDTIME PERIOD来指定一个时间范围的,其他部分和标准SQL一样


VALIDTIME PERIOD
[
1981-1985) Insert into Employee values ('112', 'Jack');


3. 记录查询:
查询所有记录,在标准
SQL
前加
VALIDTIME
关键字即可,
查询指定时间段的记录,可以通过
PERIOD
关键字指定时间区间

VALIDTIME
SELECT

*

FROM
Employee;

VALIDTIME PERIOD

[
1983-1986)  SELECT * FROM Employee;

VALIDTIME PERIOD [1983-forever) SELECT * FROM Employee;

4. 向员工表里添加人员信息插入记录前后分别如表 3-1和表 3-2所示


VALIDTIME period
[
date "2008-1-1" – now)

Insert into Staff Values ( 132202, 'Zhang Jinning', '信息部');

ATSQL2.JPG

5. 为employee表创建一个视图,该视图包含所有1999-9-9前离职的工人信息,其中VALIDTIME(R)表示取元组R的有效时间区间:
Create view employee_v as
Validtime select * from employee
Where VALIDTIME(employee) before date "1999-9-9";

6. 删除员工表的ATSQL和一般的SQL语句一样,如下
DROP TABLE Employee;

几个查询相关的概念

快照查询:查询当前时刻的数据库状态。对于非时态表(快照数据库),快照查询是一种向上兼容的查询方式,可以查询非时态数据库的数据。对于时态表(历史数据库或回滚数据库),快照查询截取当前数据库状态,返回当前状态下的查询结果。

顺序查询:顺序查询是一种时态查询,通过关键字VALIDTIME或者TRANSACTIONTIME指示系统执行哪个时间维(有效时间维、事务时间维,或者两个维度)的时态查询。在这种查询中系统运用时态代数操作自动处理元组的时间戳(有效时间、事务时间,或两者的结合)。

非顺序查询:执行非顺序查询时,系统不再根据时态代数操作解释时间戳,只是把有效时间和事务时间当作普通的用户定义属性对待。非顺序查询适合特殊的查询需求,例如查询条件涉及状态的变化的查询。
时态归并:时态归并是作用于时态数据库的一种重构操作[23] 。归并把具有相同属性值并且时间戳相邻或重叠的元组合并成一个元组,归并的过程保持时态数据库的状态不被改变。


时态数据的变元
时态数据处理构件根据ATSQL2的语法引入了Now、Beginning和Forever三个变元。Beginning和Forever分别表示时态数据处理构件所能表示的时间起点和终点。Now表示当前时间。每次执行操作时必须使Now绑定到一个固定的值(操作执行的当前时间),这样后继操作才能正常进行。
时态数据处理构件使用重写底层比较过程的方法绑定Now的语义。它把Now、Beginning和Forever分别用以下三个具体的时间值表示:
Now = ‘9999-01-01 00:00:00’;
Beginning = ‘1000-01-01 00:00:00’;
Forever = ‘9999-12-31 23:59:59’.
因为使用了特殊值表示这三个变元,一方面使得时态数据处理构件能处理的时间范围比原商业数据库能处理的时间范围小,另一方面使得原商业数据库底层对时间类型数据的比较算子有了新的意义。例如,如果当前时间是2007年12月1日,考虑“2009-1-1>Now”的意义时,应当先把Now替换为2008-07-18,比较结果为真。
在TimeDB中Now只是当前时间的别名。在时态插入语句的执行过程中,Now作为一个标记被替换为语句执行的当前时间。
注:本文部分内容引用了黄永钊的《时态数据处理构件的性能优化研究与实现》

前面介绍了TimeDB(
http://www.timeconsult.com/Software/Software.html
)是一种结合关系型数据库来实现时间数据库应用的技术,它支持时态数据库脚本:ATSQL2 [SBJS96a,SBJS96b,SBJS98]。它可以认为是关系数据库的一个前端,把时态数据库语句转换为关系型数据库的脚本进行执行,它的运用场景如下所示。
TimeDBArchiture.jpg

TimeDB是传统的数据库管理系统的前端软件,应用程序中使用的时态ATSQL语句,通过TimeDB转换后形成标准的SQL语言和操作,这些标准SQL语句和操作传入到后台数据库中操作实际的数据。TimeDB支持ATSQL2语言和时态模型,实现了时态查询、时态更新、时态视图和部分的时态完整性约束等基本的时态功能。
TimeDB 2.0版本使用Java语言开发,具有平台无关的有点;基于JDBC访问数据库,目前仅支持Oracle、Sybase和IBM的Cloudscape’s JBMS三种数据库,下一版本可能支持Microsoft's Access、SQL Server 7.0、Informix等数据库;具有较友好的用户界面;优化了辅助表的创建过程;具有可以供Java应用程序调用的接口TDBCI,可供Java应用程序调用以执行ATSQL2语句。TimeDB2.0的程序运行界面如下:
timeDB.jpg


TDBCI提供的接口函数如下所示


//
设置访问参数


public

boolean
setPrefs(String Path,
int
DBMS, String JDBCDriver, String URL);

//
初始化/清除 执行ATSQL语句所需的表


public

boolean
createDB();

public

boolean
clearDB();


//
打开或者关闭数据库


public

boolean
openDB(String Login, String Password);

public

void
closeDB();


//
执行 ATSQL语句


public
ResultSet execute(String stmt);

其中setPrefs是用来设置TimeDB的相关访问参数的,如下所示


if
(t.setPrefs(
"
C:\\TimeDB 2.2\\
"
,
//
Path to TimeDB2.0 directory



1
,
//
Using Oracle DBMS


"
oracle.jdbc.driver.OracleDriver
"
,
//
Oracle's JDBC driver



"
jdbc:oracle:thin:1521:ORCL
"
))
//
URL


createDB是用来创建一些基础表,以便支持执行ATSQL的,而clearDB则是清除这些表,对数据库而言,只需要开始的时候调用createDB一次即可。
openDB 和closeDB有点类似于我们操作数据库的时候,打开Connection连接的操作,每次查询事务,都需要先执行openDB的操作,事务提交后,调用closeDB来关闭数据库。
执行 ATSQL语句只有一个函数execute,它返回的是TimeDB定义的ResultSet对象,而ResultSet对象可以获取每一个ResultRow对象,ResultRow对象通过row.getColumnValue(i)和row.getColumnType(i)函数调用只能拿到列的值和对应值的类型,结果类型是字符类型。
返回的类型名称有:
• number • smallint •float• numeric •integer •double
• longint •real• interval • date•period •char•varchar

如何应用TimeDB的时间数据库技术
由于我们的产品技术主要是基于.NET基础上开发的,而TimeDB是基于Java的应用技术,因此可以考虑通过包装TimeDB成为WebService的应用,然后通过.NET客户端进行访问,实现时间数据库技术的应用。
TimeDBUsage.jpg

初始化数据库基础信息
TimeDB是基于关系型数据库之上的一个模块,在做时间数据库相关的脚本(ATSQL)解析前,它需要一些基础表和记录来存储相关的信息,因此需要初始化所建立的数据库。
初始化数据库可以通过执行安装目录下的SQL脚本而进行(位置为X:\TimeDB 2.2\scripts\initDB),如Oracle调用initOracle脚本,Sybase数据库调用initSybase脚本。
另外,也可以通过调用TDBCI的接口createDB创建这些基础表。

使用Java创建基于TimeDB查询操作的WebService
TDBCI公开了一些供Java应用程序调用的API函数,为了使得.NET的应用程序也能在TimeDB中执行ATSQL脚本,我们把对TDBCI的调用封装成了WebService。
开发环境:MyEclipse6.01、Tomcat5.5、Java SDK1.6、Oracle 10g、TimeDB2.0。
实现步骤:
1、 使用MyEclipse创建WebService项目,配置好Tomcat服务器
2、 引用Oralce的JDBC类和TimeDB开发所需的类
3、 创建具体的WebService服务类,提供返回结果查询和无结果的查询接口,并实现接口函数
4、 部署WebService到Tomcat中

使用.NET客户端对WebService进行访问,执行ATSQL
实现步骤:
1、 引用包装好的WebService
2、 调用相应的接口,使用ATSQL语句创建业务表
3、 调用相应的接口实现ATSQL数据操作(查询、插入、删除等)
创建业务表:
和在关系数据库(如Oracle)中创建表不同,创建时间数据库表需要调用TimeDB的接口,执行ATSQL而实现。ATSQL2是一个SQL标准,具体使用请参考相关文档。

前面介绍的Visio开发知识,都是基于Winform的Visio的开发知识,图纸的展示都是基于Winform方式展示的。但很多时候,如果能够通过Web方式可以查看最新的图纸信息,那么系统将更加趋向完美,你说是不是呢?
通过Web方式查看Visio图纸实现起来也是很容易的,首先需要在IE客户端安装一个Visio Viewer的ActiveX控件支持(微软提供),然后剩下来的就是编码展示了,展示的方式和其他的ActiveX控件展示方式差不多。先看看总体的界面实现思路,让大家有一个较好的理解后,然后我们在一步步分析如何实现。
ViewVisio1.jpg
单击查看馈线图的按钮后,新开一个窗口展示Visio的图纸(是不是和Winform看到的效果差不多呢?呵呵)
ViewVisio2.jpg

下面介绍下如何实现这个功能:
1、第一个页面的实现很简单,你指定一个链接指向新的页面(VisioContainer.aspx),该页面包含Visio View的ActiveX控件,连接中带一些参数过来,指明是查看那个图纸的就OK了。
2、这个页面(VisioContainer.aspx)实现很关键,在此页面放置一个Visio Viewer的ActiveX控件,这个控件最重要的一个变量是SRC,它需要指向一个Visio的文件路径,如果Visio图纸是文件的话,直接赋值就可以显示了。但是,我们的系统是基于数据库存储的,所有的Visio图纸都是已二进制的方式存储在数据库的,那该如何实现呢?先看页面代码



Code


其中我们需要动态指定SRC的值,因此在页面(VisioContainer.aspx)后台代码中动态绑定了,这里我们使用了JavaScript的方式来加载Visio Viewer 的SRC路径信息。



Code


我们通过一个新的页面
VisioFile.aspx
来动态生成Visio文件,然后赋值给SRC属性即可实现了。
VisioFile.aspx的页面只需要实现PageLoad函数即可,如下所示



Code


这样我们就可以实现Web端展示Visio图纸的功能了。

有这样的需求,一个系统,包含Web端的后台和Winform的绘图客户端程序,用户需要在Web端能够启动绘图客户端,并且不需要重新登录(因为已经登录了Web端了)。
那么在IE的Web端,如何启动Winform做的绘图客户端程序呢?当然对于其他桌面应用程序也是一样的。
总体思路是:
1. 在asp.net页面中增加一个按钮或者菜单,连接是调用一个JavaScript函数实现启动程序
2. 客户端的用户的环境变量有该应用程序的目录路径信息
3. Winform的绘图客户端程序能够处理传递过来的命令行的参数,实现登录启动

详细操作介绍如下:
1、asp.net页面中Javascript的代码如下:



Code





Code


2、为了使得Web端的Javascript能够调用
EDNMS.UI.exe 的Winform程序,我们需要在安装Winform的时候,把安装路径加入到操作系统Path变量中,操作系统的Path变量的内容放置在注册表节点SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment的Path中,下面是自定义安装操作的代码。



Code


3、Winform的绘图客户端程序能够处理传递过来的命令行的参数,实现登录启动
首先介绍一个能够处理命令行参数的公共类,他可以接受参数并把它放置到字典中



Code


然后在程序的入口Main函数中,增加对参数化的登录解析,如下所示



Code





Code



至此,当客户端安装了绘图客户端后,Path的路径将加入安装的路径,在Web端通过javascript调用程序启动即能进行响应,并通过CommandLine辅助类解析参数后进行登录。
但要主要的是,Javascript能够调用本地的程序,是需要在IE中设置启用Javascript权限许可才可以。
VisioViewActiveX.jpg