VB程序中如何处理随机事件_VB.net_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

VB程序中如何处理随机事件

作者:黑客防线网安VB教程基地 来源:黑客防线网安VB教程基地 浏览次数:0

本篇关键词:随机事件处理如何
黑客防线网安网讯:在程序设计过程中,如何轻松地处理众多的随机事件,往往是制作大型系统首先要考虑的问题之一。用C语言开发Windows程序时,可以方便地使用消息机制(Message),但是,设计VB程序时,就没有这...
在程序设计过程中如何轻松地处理众多的随机事件往往是制作大型系统首先要考虑的问题之一用C语言开发Windows程序时,可以方便地使用消息机制(Message),但是,设计VB程序时,就没有这样的方便条件了例如,多个窗口同时打开同一个表(Table),当在一个窗口中对数据进行了修改,而其他的窗口也能够随之进行数据更新,这时就需要有一条说明数据改变了的消息在所有的窗口间进行广播。如果使用的语言是C,只需要定义一条用户消息(UserMessage),就可以实现这一点。可是如果是用VB编程,做起来就不是那么简单了,最初我是试着这样实现的:

  自定义了一个消息结构(VbMsg),并在程序的主窗体内,建立一个消息广播引擎,主要由一个消息队列和一个定时消息广播器所组成。消息广播器固定隔一定时间检查一次消息队列,如果有消息存在,就将其发送给所有的打开的窗口,并将该消息从队列中删除。如此再定义一个全局的消息发送过程(SendMsg),将要发送的消息(VbMsg)送入消息队列。这样当需要广播消息时,只需填充好消息结构,调用SendMsg过程即可。这里较为复杂的是消息广播器如何将消息发送到各窗口:这需要作个硬性规定,就是每一个窗体都必须定义一个形式完全相同的消息接收函数(RecMsg),在这个函数中对接收到的消息进行处理,当然也可以什么都不做。有了这样的规定之后,消息广播器在进行广播时,就可以是利用VB系统定义的全局变量Forms,遍历所有的窗体,并调用一遍每个窗体的消息接收函数,其样子大致如下:

PublicSubSendMsgToForms(msgasVbMsg)

DimfrmasForm

ForEachfrmInForms

frm.RecMsgmsg

Nextfrm

EndSub

  通过上面的这些过程,就可以实现在独立的程序中,对随机事件进行异步处理。这一方法我曾经在早期开发的几个系统中使用,效果基本还是令人满意的。但是它有几个较大的局限性,当开发更大一些的系统时,就显得不能够满足需要。主要有以下几点:

定时检查消息队列,需要利用Timer控件进行触发。这在程序运行时,就必然要牺牲一部分效率;

消息广播的范围限定在一个程序模块内,如果整个系统分成多个大的模块,那么存在于动态连接模块(.DLL)中的窗体,将不能直接接收到广播消息。而要想实现进程间的消息传递,这一方法就更加不可能;

消息的接收者只能是窗体,而做为真正的基础单元--“类”却无法直接接收消息。
  为了打破上面的几点局限性,就必须寻找新的解决办法。非常庆幸的是,VB5.0企业版的推出,给VB增添了许多强有力的特性,有几点特性,正好可以帮助我们解决难题。先让我介绍一下这几个特性:
  用户自定义事件:在类模块中,可以使用Event关键字来定义用户自定义事件,使用RaiseEvent语句来产生该事件,这一机制给处理随机事件带来极大的方便。上面说的消息广播引擎,就可以不再使用Timer控件做支持,而是当收到需要广播的消息时,产生一个预定义的事件,而需要处理消息的客体对象,只需截获该事件,就完成了消息的传递。

ActiveXEXE部件:利用VB,可以方便地将共享代码封装在ActiveX部件之中。将消息广播引擎实现于一个ActiveX部件之中,不仅方便了在程序中使用,而且更为重要的一点是,可以实现跨进程间的消息传递。因为ActiveX部件有内部(DLL)外部(EXE)两种,对于外部部件,可以对模块内的全局数据实现共享(关于ActiveX两种代码部件的区别,请阅读VB的联机帮助文件)。

远程自动化连接:ActiveX部件,是一种标准的客户机/服务器结构,利用Windows平台的COM模型,VB已能方便地将这种结构扩展到整个网络的范围。所以,我们的消息广播设计,在实现了进程间的消息传递之后,进而实现网络上的消息传递,也成为可能。
  通过上面的几点介绍,这一方式的设计思想也就比较清楚了,在具体设计时,我通过四个模块之间的相互协作,完成了消息的发送、广播及接收,并将这四个模块封装在一个ActiveXEXE部件之中。下面就是这三个类模块的简单介绍及源代码:
  类模块之一:Msg.cls
  在该模块中,定义了消息数据结构VbMsg类,它是消息传递中的载体。这里只是一个简单的例子,如果想实现更多的功能,如建立两点间的数据通道,而不是单纯的广播消息,则可能需要对该结构进行一些扩充。
  

VERSION1.0CLASS

BEGIN

MultiUse=-1'True

END

AttributeVB_Name="VbMsg"

AttributeVB_GlobalNameSpace=False

AttributeVB_Creatable=True

AttributeVB_PredeclaredId=False

AttributeVB_Exposed=True

OptionExplicit

'    ---

'说明:

'

'消息类:定义全局的消息结构

'    ---

PubliciTypeAsLong'消息类型编号

PubliciNameAsString'消息名

PubliciSourceAsString'消息源说明

PubliciDescriptionAsString'消息说明

DimiTAsDate'消息发生时间

'返回日期型时间

PublicPropertyGetiTime()AsDate

iTime=iT

EndProperty

'返回字符型时间

PublicPropertyGetiTimeStr()AsString

iTimeStr=Format(iT,"yyyy.mm.ddhh:mm:ss")

EndProperty

'在对象被建立时,设置消息发生时间

PrivateSubClass_Initialize()

iT=Now()

EndSub
  

类模块之二:MsgCli.cls
  本模块是对客户接收端MsgClient类的定义,这相当于一个消息接收器。在这个类中定义的一个RecMsg事件,当接收器收到消息时(过程SetMsg被调用),就产生这一事件。接收器的建立者就截获这一事件,并处理消息。为了避免接收不必要的消息,声明了minMsg、maxMsg两个变量,以便对VbMsg中的iType属性进行过滤。
  

VERSION1.0CLASS

BEGIN

MultiUse=-1'True

END

AttributeVB_Name="MsgClient"

AttributeVB_GlobalNameSpace=False

AttributeVB_Creatable=True

AttributeVB_PredeclaredId=False

AttributeVB_Exposed=True

OptionExplicit

'    ---

'说明:

'

'客户消息接收类

'    ---

'

'定义接收消息事件,该对象的宿主类应截获该事件,并处理

'接收到的消息。

PublicEventRecMsg(ByValmsgAsVbMsg)

'

'通过设置消息的接收范围,可以过滤掉不需要的消息

PublicminMsgAsLong

PublicmaxMsgAsLong

'

'该对象的标志编号,使用时不应修改该值

PublicIDAsLong

'

'事件产生过程,只应由消息服务器(MsgServer)调用

PublicSubSetMsg(msgAsVbMsg)

Ifmsg.iType>=minMsgAndmsg.iType<=maxMsgThen

RaiseEventRecMsg(msg)

EndIf

EndSub

'

'根据ID,返回对象的关键字,

只应由消息服务器(MsgServer)调用

PublicPropertyGetKey()AsString

Key="ID:"&ID

EndProperty
  

类模块之三:Global.bas
  本模块声明了两个全局变量,一个是接收器(MsgClient)列表(Clients),一个是接收器计数器,以为每个接收器分配一个唯一的ID标志。把变量放在单独的模块中,是为了实现数据在进程间的共享,是跨进程间消息传递的关键所在。(应保证在编译时工程是单限程的,否则数据共享则不能实现。)。
  

AttributeVB_Name="modGlobal"

OptionExplicit
  '说明:
  '消息服务器全局变量
  '    ---
  消息接收客户列表

PublicClientsAsNewCollection

'消息接收客户ID计数器

PublicCliCountAsLong
  

类模块之四:MsgSrv.cls
  本模块中定义了消息服务器类MsgServer,该类是消息广播引擎的主体,它主要管理维护消息接收器列表(Clients),将发送来的消息(调用SendMsg过程)依次发送给列表中的所有接收器。注意,这个类被声明为公共全局类,这主要是为了方便使用(不必在每个程序中再建立该类,过程名全局有效)。
  

VERSION1.0CLASS

BEGIN

MultiUse=-1'True

END

AttributeVB_Name="MsgServer"

AttributeVB_GlobalNameSpace=True

AttributeVB_Creatable=True

AttributeVB_PredeclaredId=False

AttributeVB_Exposed=True

OptionExplicit

'    ---

'说明:

'

'消息服务器类

'    ---

'发送消息

PublicSubSendMsg(msgAsVbMsg)

DimcAsMsgClient

ForEachcInClients

c.SetMsgmsg

DoEvents

Nextc

EndSub

'

'增删消息接收客户

PublicSubAddMsgClient(cAsMsgClient)

CliCount=CliCount 1

c.Id=CliCount

Clients.Addc,c.Key

EndSub

PublicSubDelMsgClient(cAsMsgClient)

Clients.Removec.Key

IfClients.Count=0ThenCliCount=0

EndSub
  

  到这里,一个小巧灵活的消息广播引擎就完成了,它的使用范围很广,用起来也很方便,只需在工程中引入编译过的ActiveX部件,就可以直接调用SendMsg发送消息,可能在安装消息接收器(MsgClient)时会稍许有点麻烦,下面举一个简单的应用例子大致说明一下:
  在设计Windows程序时,往往会感觉到程序的实际运行过程与你想象的相差甚远,调试时就非常希望看到程序运行时后台的一些情况。利用VB的单步执行或Debug命令,都会受到一些限制。利用消息广播引擎,制作一个通用的实时消息事件查看程序,就可以很好地解决这一问题。查看程序的主要工作就是捕捉一组事先定义好的消息事件,并将消息的内容显示在列表框内,可以只用一个窗体完成,大体样子如下:

ConstMsgInfoID=101

PrivateWithEventsmClientAsMsgClient

PrivateSubForm_Load()

SetmClient=NewMsgClient

MClient.minMsg=MsgInfoID

MClient.maxMsg=MsgInfoID

AddMsgClientmClient

EndSub

PrivateSubForm_Unload(CancelAsInteger)

DelMsgClientmClient

EndSub

PrivateSubmClient_RecMsg(ByValmsgAsVbMsgSrv.VbMsg)

List1.AddItemmsg.iTimeStr&Chr(9)&msg.iName&Chr(9)&msg.iDescription

EndSub
  

  在被调试的程序中,为了调用方便,可以编写一个全局过程,象下面这个样子:
  

ConstMsgInfoID=101

PublicSubMsgInfo(iNameAsString,iDesAsString)

DimmsgAsNewMsgClient

Withmsg

.iName=iName

.iDescription=iDes

EndWith

SendMsgmsg

EndSub
  

  在程序的重点需要了解的环节插入MsgInfo过程,运行时信息就会在事件查看程序的窗口中被显示出来。这种方法尤其适合调试多程序协作的软件系统。当软件系统正式交给用户时,插入的MsgInfo过程也不一定要全部删掉,只要将实时查看变为写入日志文件,这些运行时的信息也是日后软件维护的第一手资料。 

->

    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-14549-1.html
网站维护教程更新时间:2012-04-03 01:09:10  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer