如何在Power Builder中应用串口通信
张佐东
Power Builder(以下简称PB)是一个非常好的数据库管理系统的开发工具。它能够处理纷繁复杂的数据、提供优异的报表集成方式,并且具有灵活、友好、方便和快捷等特点,非常适用于不同的数据库管理系统。但是,许多应用程序既包含了复杂的数据处理,又需要进行计算机通信的控制,如门禁系统、点名系统以及接见系统等。这些应用程序中必须使用计算机的串口进行通信,而PB没有直接控制计算机串口的控件; 而VB中虽然带有串口控件,但是对于习惯使用PB的程序员来说,使用VB来处理大量复杂数据有时会感到不便。笔者在实际工作中利用OLE调用Mscomm.ocx控件,方便地解决了PB中的通信控制问题。
一、解决方法
1.在窗体中新建一OLE控件,在出现的“Insert Object属性”窗口中选择“Insert Control Tab”选项卡,在“Control Type”选项中选择“Microsoft Communications Control”选项(如果没有,说明此机器未注册安装此控件,安装注册的具体方法我们将在下面做详细的介绍),点击“OK”按钮后将控件放在窗体中任一位置(因为控件在实际运行时是不可见的,可以任意放置),系统中出现“Mscomm”控件图标,给此控件命名为“OLE_comm”。


图2 “Control Properties属性”对话框
2.控件的属性设置可以在“OLE Custom Control”对话框中的“OLE Control Properties”按钮中进行设置(如图1所示),您也可以鼠标右击控件菜单的“OCX Properties”选项,进入“Control Properties属性”对话框(如图2所示)。笔者推荐您最好在程序中使用编码设置,这样更加便于控制。
例如,在窗口OPEN事件中编程。
ole_comm.object._CommPort = 1 ole_comm.object.Settings = "57600,n,8,1" ole_comm.object.InputLen = 0 ole_comm.object.InBufferSize = 90 ole_comm.object.OutBufferSize = 60 ole_comm.object.SThreshold = 0 ole_comm.object.RThreshold = 9 ole_comm.object.Handshaking = 0 ole_comm.object.PortOpen = True ole_comm.object.InBufferCount = 0 ole_comm.object.DTREnable = true
其中:
CommPort 设置并返回通信端口号。
Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位以及停止位。
InputLen 从接收缓冲区中读取的字符数。设置InputLen值为“0”时,使用“Input”将使“MSComm”控件读取接收缓冲区中全部的内容。
InBufferSize 设置并返回接收缓冲区的字节数。
OutBufferSize 以字节的形式设置并返回传输缓冲区的大小。
Handshaking 设置并返回硬件握手协议。
PortOpen 设置并返回通讯端口的状态,也可以打开和关闭端口。
以上程序中设置的值均为本人在实际应用中所使用的值,其中的具体数值应根据您的实际应用情况进行设置。属性设置在PB的编程中需要在控件名称后加“.object”,这与VB等编程工具中稍有区别。
3.对控件的oncomm事件编程(以case 2为例)。
choose Case ole_comm.object.CommEvent
case 2 //ComEvReceive2 收到 Rthreshold个字符。该事件将持续产生,直到使用“Input”属性从接收缓冲区中删除数据。
//主要控制处理程序在此事件中由串口自动触发,避免占用系统资源。
//输入接收到数据后所要做的处理。
string ls_input,ls_output ls_input = ole_comm.Object.Input //取数据。 wf_oncomm(ls_input)//处理 //ls_output赋值 ole_comm.Object.output(ls_output) End choose
注意: 在PB编程中“case”后面只能使用数值,不能用字符串(在VB中可以使用),具体数值的含义可以在MSDN中查找。
4.根据实际工作中的经验,为了避免信号干扰等原因造成通信错误,程序在开始使用串口或者出现错误时要有对串口进行复位操作,复位编程如下。
ole_comm.object.dtrenable=false//关闭串口。 //延时,可通过Win32的Sleep函数实现。 首先声明Function Long Sleep(Long ms) Library 'kernel32' Sleep(1000)//延时1秒。 //简单一点的可以使用一空的for循环语句达到目的。 for i=1 to 1000 next ole_comm.object.input //清空缓冲区。 ole_comm.object.dtrenable=true//打开串口。
5.如何注册“Mscomm”控件。
可以单独制做一个注册程序,并打包到您的应用程序中。如果需要安装的目标计算机已经有“Mscomm”控件,则不需要进行任何工作。如果没有“Mscomm”控件,则需要运行这个注册程序。程序编码如下。
RegistrySet("HKEY_CLASSES_ROOT \Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905","", RegString!, "kjljvjjjoquqmjjjvpqqkqmqyky poqjquoun") run("regsvr32 mscomm32.ocx") messagebox('提示','请重新启动计算机')
这只是简单的编码,并且mscomm32.ocx文件在当前运行目录,注册成功即出现系统消息。为了使界面更友好,您可以做一步修饰,例如“run("regsvr32/s mscomm32.ocx")”,这样就可以使屏幕上不出现系统消息了。
您还可以利用API函数,通过“ExitWindowsEx”函数可以实现重新启动Windows系统,具体步骤如下。
1. 首先进行声明。
Function Long ExitWindowsEx(Long uflag,Long nouse) Library 'user32.dll'
2.在messagebox中增加一用户选择,如果用户现在立即重新启动,即调用函数ExitWindowsEx (2,0)。
3.在注册时可以获取当前目录或者Windows系统目录来注册控件,通过“GetCurrentDirectory”函数即可获取当前目录,该函数声明如下。
Function Ulong GetCurrentDirectoryA(Ulong buflen, ref String dir) Library 'kernel32.dll'
编码为:
String ls_currentdir
Ls_currentdir=Space(256) //置空变量。
GetCurrentDirectoryA(256, ls_currentdir)
4.通过“GetWindowsDirectory”和“GetSystemDirectory”这2个函数,获取Windows及系统目录,声明如下。
Function Uint GetWindowsDirectoryA(ref String dir,Uint buflen) Library 'kernel32.dll'
Function Uint GetSystemDirectoryA(ref String dir,Uint buflen) Library 'kernel32.dll'
另外,该程序根据需要还可以进行优化,在此不再详述。上述程序在Windows 98+Power Builder
6.5系统中测试通过。
二、小结
利用上述方法,我们既可以在PB中实现计算机的串口通信,又保持了PB的强大的数据处理功能,使您能随心所欲地使用PB编制计算机控制程序。
(作者地址:
南京市宏图高科技术开发公司软件部,210009)