3、监控实现过程
3.1 数据交换方式简述
(1)DDE(动态数据交换,Dynanic Data Exchange)
DDE主要是一个发送消息和接收消息的机制,DDE能使两个Windows应用程序通过发送或接收命令和数据进行相互之间的通信,它使应用程序之间能够实现共享数据,在远端执行命令以及检查错误状态等功能[3]。PowerBuildier 为实现DDE技术提供了相关的事件和函数,利用这些事件和函数,PowerBuildier应用程序可以向另一个支持DDE的应用程序发送消息,也可响应其他DDE应用的请求。
(2)OLE(Object Linking and Embedding, 对象链接与嵌入)
OLE技术提供了一种使Windows应用程序之间共享数据和程序的机制,利用OLE技术,不同的应用可以在一个统一的界面下协调工作。Powerbuilder以OLE控件作为容器(Containter)从中调用OLE服务器应用程序来显示及操纵OLE对象[3]。Powerbuilder中OLE控件是OLE对象的容器,用户可激活OLE控件,并使用由OLE服务器应用程序提供的功能编辑其中的OLE对象。也可以通过编程激活OLE对象,并向OLE服务应用程序发送命令使OLE交互自动化。PowerScript自动化可以使用于窗口中的可视OLE控件上,也可使用于引用存储在OLEObject变量中的不可视OLE对象上,利用OLEbject数据类型,可以创建一个OLE对象,而不必为它在窗口中提供可视OLE容器。
3.2 AutoCAD 2000二次开发工具ARX接口方法简介
利用Visual C++开发AutoCAD应用程序,其接口函数使用了三个关键函数,即:InitApp()、UnloadApp()、和acrxEntryPoint()。
通过对Object ARX应用开发工具的研究知道,Object ARX与AutoCAD 2000是通过专门的接口程序来实现的,因此,通过Object ARX开发工具不能直接与PowerBuilder进行通讯。但是,可以通过在其应用程序中增加参数接收机制,通过调用ARX应用程序时向它传送参数,以实现想要的功能。如:
const char *must_locklayer; //必须要加锁的图层
void NMYFWatchLayerReactor() //修改后的用户函数,可接收外部参数
{ char* hline1;
acedGetString(0,"\n",hline1);
if(hline1!=NULL)
{ must_locklayer=&hline1[0];
}else
return;
……
}
本系统就是在PowerBuilder中调用该函数,并通过该函数接收权限代码参数的。
3.3 系统接口及数据交换技术在审批流中的具体应用
系统要求在Powerbuilder中的命令和数据能在AutoCAD 中执行和接收,并能有效传递参数。由于在Powerbuilder窗口中并非要求一定要显示AutoCAD 文件,而Powerbuilder窗口中又必须能成功地通过按扭实现打开AutoCAD文件、传递 Powerbuilder参数的功能,因此,对Powerbuilder与AutoCAD服务应用程序接口方法,系统采用非可视OLE对象方法来定制打开AutoCAD文件的行为,并控制打开文件的方法。OLEObject是一个动态的对象类型,编译程序可以接受OLEObject对象类型的任何属性名、函数名及参数列表。
使用OLEObject变量包括以下步骤:
(1). 声明一个OLEObject 变量并初始化,为OLE变量分配内存空间
(2). 与服务器应用程序连接
(3). 根据需要使用服务器应用程序的属性和函数操纵该对象
OLEObject对象与AutoCAD2000服务器连接及通讯时,可利用VBA嵌入AutoCAD应用程序之中的特性,调用Active AutoMantion VBA所提供的函数为其服务。本系统采用两种方式打开文档,一种方式是用ConnectToObject函数,该函数以读写方式打开指明具体路径的文档,一般是用户以设计、校审方式打开文档,这是因为用户需要对文档进行改写操作,当系统使用该命令打开文件时,会直接调用AutCAD应用服务器,并以写方式打开文件;另一种方式是,首先启动OLE服务器然后手工确定AutCAD服务器的显示状态,然后按指定方式打开目标文件。
(4).关闭OLE对象的连接并销毁这个变量
当服务器应用程序运行结束时,就当关闭OLE对象与服务器应用程序的连接,并释放OLE对象所占用的内存空间。
(5).重要命令"SendCommand"的使用
"SendCommand"是一个非常重要的AuotoCAD服务器应用程序命令,通过这个命令可以操纵AutCAD的任何命令。在使用SendComand命令时,应特别注意,如果使用ConnectToObject命令连接服务器应用程序,直接用:
ole.Sendcommand()
但如果用ConnectToNewobject()命令直接打开某一文件,则要使用:
ole.ActiveDocument.SendCommand()
这是因为,使用ConnectToObject命令连接服务器应用程序时,AutoCAD已打开了一文档并自动将其激活;而用ConnectToNewobject()命令连接服务器应用程序时,其只是首先连接上了服务器应用程序,而未将相关文档激活,因此必须加上"ActiveDocument"以激活目标文档。
但是用SendCommand 直接调用AutoCAD命令时,要注意到这是一条典型的VBA命令,但Powerbuilder中却未发现该命令,在Powerbuilder中调用该命令时,其语法格式要作调整。
在VBA中SendCommand命令格式的原型是:
object.SendCommand(Command)
在Powerbuilder中,该命令的格式却是:
object.SendCommand("Command")
并且在调用时要做一些改动。
在VB应用程序中用SendCommand发送画圆命令至AutoCAD命令行用法如下:
ThisDrawing.SendCommand "_Circle" & vbCr & "2,2,0" & vbCr & "4" & vbCr
用vbCr表示在命令行中敲入了一个回车键。
由于VBA是直接嵌入到AutoCAD中的,它调用AutoCAD 时,只要按照语法规则加入合适的控制码就可实现想要的语法功能。
Powerbuilder中直接调用AutoCAD 命令不一样,它直接采用如下语法格式来调用AutoCAD命令:
OLE控件.ActireDocument.SendCommand("命令及参数列表")
例如:画一个圆:
OLE1. ActiveDocument SendCommand("-Cirde 0,2,3 4 ")
我们可以对比一下VBA的情况:
ThisDrawing.SendCommand "-Cirde2,2,3,4空格"
可以发现这两种语法不同之处:在Powerbuilder中调用须增加一对括号。
使用时为了可靠调用,语句中须增加ActiveDocument。
3.4 Powerbuilder加载AutoCAD应用程序的过程
在Powerbuilder中加载AutoCDA应用程序,却不能用以上语法来加载即:
OLE ActiveDocament SendCommand("arx l D:\Myarx\Myarx,arx ")
这是因为当输入最后一个参数时,空格不能认为是回车键。但是,可以利用在AutoCAD中用的"Command"指令一次性输完命令和参数的方法来加载应用程序:
OLE ActiveDocament SendCommand (‘(command "arx" "l" &
"D:\\LAYERCONTRL\\layermena\\Debug\\LOCKLAYER.arx") ‘)
可以看出,这一段语法命令及参数列表可以理解为:
String tempref
Tempref=‘(command "arx" "l" &
"D:\\LAYERCONTRL\\layermena\\Debug\\LOCKLAYER.arx") ‘
ole.SendCommand(tempref)
经过测试,如果参数"D:\\LAYERCONTRL\\layermena\\Debug\\LOCKLAYER.arx"
写成 "D:\LAYERCONTRL\layermena\Debug\LOCKLAYER.arx"
则在AutoCAD命令行参数输入栏会显示为:
"D:LAYERCONTRLlayermenaDebugLOCKLAYER.arx"
系统找不到文件。这是因为在VB中反斜杠"\"是控制符,只有成对出现才会表示为文件路径中的"\"。
这样,通过在PowerBuilder中动态加载AutoCAD的ARX程序就可全程监控用户所有操作行为。
正确加载应用程序后就可实现要进行的操作。如执行自行开发的应用程序中的创建新图层、指定颜色、线宽:
contact_ltr.ActiveDocument.SendCommand("createnewlayer 校对层 5 1 ")