VB程序中处理随机事件

VB程序中处理随机事件

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

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

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

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

消息广播的范围限定在一个程序模块内,如果整个系统分成多个大的模块,那么存在于动态连接模块(.DLL)中的窗体,将不能直接接收到广播消息.而要想实现进程间的消息传递,这一方法就更加不可能;消息的接收者只能是窗体,而作为真正的基础单元—“类”却无法直接接收信息。

——为了打破上面的几点局限性,就必须寻找新的解决方法。非常庆幸的是,VB5.0企业版的推出,VB增添了许多强有力的特性,有几点特性,正好可以帮助我们解决难题。先让我介绍一下这几个特性:

用户自定义事件:在类模块中,可以使用EVENT关键字来定义用户自定义事件,使用RAISEEVENT语句来产生该事件,这一机制给处理随机时间带来极大的方便。上面说的消息广播引擎,就可以不再使用TIMER控件做支持,而是当收到需要广播的消息是,产生一个预定义的事件,而需要处理消息的客体对象,只需截获该事件,就完成了消息的传递。

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

远程自动化连接:Active X部件,是一种标准的客户机/服务器机构,利用WINDOWS平台的COM模型,VB已能方便地将这种结构扩展到整个网络的范围。所以,我们的消息广播设计,在实现了进程间的消息传递之后,进而实现网络上的消息传递,也成为可能。

——通过上面的几点介绍,这一方式的设计思想也就比较清楚了,在具体设计是,我通过四个模块之间的相互协作,完成了消息的发送、广播及接收,并将这四个模块封装在一个Active XEXE部件之中。下面就是这三个类模块的简单介绍及源代码:

类模块之一:MSG.CLS

——在该模块中,定义了消息数据结构VBMSG类,它是消息传递中的载体。这里知识一个简单的例子,如果想实现更多的功能,如建立两点间的数据通道,而不是单纯的广播消息,则可能需要对该结构进行一些扩充。

类模块之二:MSGCLI.CLS

——本模块是对客户接收端MSGCLIENT类的定义,这相当于一个消息的接收器。在这个类中定义的一个RESMSG事件,当接收器收到消息时(过程SETMSG被调用),就产生这一事件。接收器的建立者就截获这一事件,并处理消息。为了避免接收到不必要的消息,声明了MINMSG,MAXMSG两个变量,以便对VBMSG中的ITYPE属性进行过滤。

类模块之三:GLOBAL.BAS

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

类模块之四:MSGSRV.CLS

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

到这里,一个小巧灵活的消息广播引擎就完成了,它的使用范围很广,用起来也很方便,只需在工程中引入编译过的Active X部件,就可以直接调用SENDMSG发送消息,可能在安装消息接收器(MSGCLIENT)时会稍许有点麻烦,下面举一个简单的应用例子大致说明一下:

——在设计WINDOWS程序时,往往会感觉到程序实际运行过程与你想象的相差甚远,调试是就非常希望看到程序运行时后台的一些情况。利用VB的单步执行或DEBUG命令,都会受到一些限制。利用消息广播引擎,制作一个通用的实时消息事件查看程序,就可以很好地解决这一问题。查看程序的主要工作就是捕捉一组事先定义好的消息事件,并将消息的内容显示在列表框内,可以只用一个窗体完成。

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

本文涉及的代码:

Public Sub SendMsgToForms(msg As VbMsgBoxResult)

Dim frm As Form

For Each frm In Forms

frm.recmsg msg

Next frm

End Sub

VERSION 1.0 CLASS

BEGIN

  multiuse = -1

  End

  attribute vb_name="vbmsg"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

  Option Explicit

  Public iType As Long

  Public iName As String

  Public iSource As String

  Dim iT As Date

  Public Property Get iTime() As Date

  iTime = iT

    End Property

  Public Property Get itimestr() As String

itimestr = Format(iT, "yyyy.mm.dd hh:mm:ss")

  End Property

  Private Sub class_initialize()

  iT = Now()

   End Sub

  '模块2:MSGCLI。CLS

  VERSION1.0 CLASS

  BEGIN

  Mulitiuse = -1

  End

  attribute vb_name="msgclient"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

Option Explicit

public event recmsg(buval msg as VbMsgBoxResult )

Public minmsg As Long

Public maxmsg As Long

Public ID As Long

Public Sub setmsg(msg As vbmsg)

If msg.iType >= minmsg And msg.itupe < maxmsg Then

    RaiseEvent recmsg(msg)

    End If

  End Sub

Public Property Get key() As String

 key = "id:" & ID

End Property

  '模块3:MSGCLI。CLS

attribute vb_name="modglobal"

Option Explicit

Public clients As New Collection

Public clicount As Long

VERSION1.0 CLASS

  BEGIN

  Mulitiuse = -1

  End

  attribute vb_name="msgserver"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

Option Explicit

Public Sub sendmsg(msg As VbMsgBoxResult)

Dim c As msgclient

 For Each c In clients

   c.setmsg msg

   DoEvents

 Next c

End Sub

Public Sub addmsgclient(c As msgclient)

 clicount = clicount + 1

 c.ID = clicount

 clients.Add c, c.key

End Sub

Public Sub delmsgclient(c As msgclient)

 clients.Remove c.key

If clients.Count = 0 Then licount = 0

End Sub

 comst msginfoid = 101

Private WithEvents mclient As msgclient

Private Sub form_load()

Set mclient = New msgclient

  mclient.minmsg = msginfoid

  mclient.maxmsg = msginfoid

    addmsgclient mclient

 End Sub

Private Sub Form_Unload(Cancel As Integer)

 delmsgclient mclient

End Sub

Deal with the chance event in VB procedure

Deal with the chance event in VB procedure In the course of designing program, how to deal with numerous chance events easily, One of the questions that often make large-scale system and considers at first. Language develop WINDOWS procedure, can use news mechanism conveniently( MESSAGE) with C. However, while designing VB procedure, there is no condition of facilitating like this. For example a lot of window open same form( TABLE) at the same time , act as among one window going on and fix to datum, And other window too can carry on data upgrade, at this moment on need one prove news that datum change go on and broadcast among all window thereupon. If the language used is C, only need to define a user's news( User Message), can realize this . Use VB programming , make and it stands up to be so getting simple initial I try and realize so:

--Have defined a news structure by oneself( VBMSG), and in the main window body of the procedure, sets up a news radio engine, A news formation and a timing news radio device make up mainly. News broadcast regular device check a news formation through sure time , if news exists, Send it to all open windows , and delete this news from the formation. The news of defining another the overall situation so sends the course( SENDMSG), the news( VBMSG) that will send is sent like the news formation. Look on as and need radio news, need and fill good news structure only , transfer course like this.

Comparatively a complicated one is how the broadcasting device of news sends news to every window here: This needs to make a hard and fast rule, it is the body of every window that must define a news with self-same form and receive function ( RECMSG), Dealing with the news that is received in this function, nothing OK. is done. Have after the such a regulation, news broadcast device at the time of carrying on radio, can utilize VB overall variable FORMS that system defined, All over all window body of calendar, and transfer news of each window body and receive function.

--Through the course, can realize in the independent procedure , deal with the chance event asynchronously. Used in several systems which I once developed of this method in early days, the result was basic or satisfactory. But it have several bigger limitation, as develop heavy system a little, Seem and can satisfy the demand. There are the following several points mainly: Check the news formation regularly, need to utilize the controlling part of TIMER to be touched off. When this procedure runs , must sacrifice some efficiency :

The range of news radio is limited in a procedure module , if the whole system divides into a lot of big module , The window body existing in the dynamic connection module( .DLL) , can't receive radio news directly. And want to realize that the news among the process is transmitted , this method is more impossible ; The recipient of news can only be the window body, but as the real basic unit -" kind" is unable to receive the message directly .

--In order to break some limitation above, must look for the new solution . The one that rejoiced very much is, the introduction of VB5.0 enterprise edition , VB has added a lot of powerful characteristics, There are some characteristics, can just help us to solve the difficult problem . Let me introduce these characteristics first:

Users define the incident by oneself: In a kind of module, can use EVENT key word to define users and define the incident by oneself , Using RAISEEVENT sentence to produce this incident, this mechanism is dealt with at random time brings great convenience. The news radio engine talked about above, can no longer use the controlling part of TIMER to be supported , As receive and need news of radio, produce one predetermined incident of justice, And need to deal with the object target of news, only need to intercept and capture this incident, finish the transmission of news

Active X EXE part: Utilize VB, can share code encapsulation in Active X part conveniently . Broadcast engine realize and among the part, help among procedure using not merely on one Active X news, But also a little even more important is, can realize and step the news among the process to transmit . Because there are outside( EXE) of inside( DLL) two kinds of Active X parts, to the outside part, can realize and share the overall data in the module ( about Active X difference between two kinds of code parts, please read the on-line help file of VB).

Long-range automation is joined : Active X part, is a kind of standard client / the organization of the server, utilizes COM model of WINDOWS platform, VB can already expand this kind of structure to the range of the whole network conveniently . So, our news broadcast and design, after realizing that the news among the process is transmitted, And then realize that the news on the network is transmitted , become possible .

--Recommending through several points above, the design philosophy of this way is clearer too, In concrete to it designs to be, I mutual cooperation between 4 pieces of module, finish sending, radio and receiving of news, And four module among one Active XEXE part encapsulation these. It is now the simple introductions of these three pieces of module and source code:

One of the kind of module: MSG. CLS --In this module, has defined data structure VBMSGs of news, it is a carrier in the news is transmitted . If a simple example of knowledge here, if want to realize more functions, Such as the data passway while setting up two o'clock, but not simple broadcast news, May need to carry on some expansion to this structure。

Second of kind of module : MSGCLI. CLS --This module is to the definition that the customer receives end MSGCLIENTs, this is equivalent to a receiver of news. An RESMSG incident defined in this each, when the receiver receives news( course SETMSG is transfered), Produce this incident . The setting-up of the receiver person intercepts and capture this incident , and deal with news. For avoid and receive arrive unnecessary news, declare MINMSG, MAXMSG two variable, In order to filter ITYPE attribute in VBMSG.

Third of kind of module : GLOBAL.BAS --Module this declare two overall variable, one tabulate receiver, one receiver counter, Thought that each receiver distributed an only ID sign . Put the variable in the single module , it is for realizing the sharing among the process of data, Step the key that news transmits among the process. ( should guarantee project single limit Cheng at the time of compiling, otherwise data share and can realize).

Fourth of kind of model : MSGSRV. CLS --Has originally defined server MSGSERVER of news in the model , this type is a subject of a radio engine of news, It manages and maintains the news receiver to tabulate mainly( CLIENTS), the news that will send is sent to all receivers while tabulating in proper order. Be careful, each this declare for public the overall situation, this for being convenient to use mainly( needn't set up and then this kind among each procedure, The course is famous the overall situation is effective).

Getting here, a small and exquisite and flexible news has broadcast the engine and has been finished , its use is in a very large range, It is very convenient too to use, only need to introduce Active X part compiled in the project, Can transfer SENDMSG and send news directly , perhaps will have a little trouble slightly at the time of installing the news receiver( MSGCLIENT), Now cite a simple application exampling roughlies proves :

- -At the time of designing WINDOWS procedure, often can feel procedure actual that course and you imagine to differ greatly operation, It is to hope to see some situations of the backstage supporter when the procedure operates very much to debug. Utilizing the single step of VB to carry out, or DEBUG is ordered, will receive some restrictions . Utilize the radio engine of news, make a real-time news incident in common use and look over the procedure , Can well solve this problem . Look over that the groundwork of the procedure is to catch one group and define the good news incident in advance, And show the content of news that can finish only with the body of a window in tabulating frames .

--Focal point in procedure need link that understand insert MSGINFO course in, news will look over window of procedure show in incident when operating. This hits the method and is especially suitable for debugging the software system that many procedures cooperate . When give the software system to users formally, MSGINFO course inserted might not all deleted either, So long as will look over and turns into writing into the daily record file in real time , the information at the time of the operation is the firsthand materials that the software will be maintained in the future

Letterpress deal with sound code:

Public Sub SendMsgToForms(msg As VbMsgBoxResult)

Dim frm As Form

For Each frm In Forms

frm.recmsg msg

Next frm

End Sub

VERSION 1.0 CLASS

BEGIN

  multiuse = -1

  End

  attribute vb_name="vbmsg"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

  Option Explicit

  Public iType As Long

  Public iName As String

  Public iSource As String

  Dim iT As Date

  Public Property Get iTime() As Date

  iTime = iT

    End Property

  Public Property Get itimestr() As String

itimestr = Format(iT, "yyyy.mm.dd hh:mm:ss")

  End Property

  Private Sub class_initialize()

  iT = Now()

   End Sub

  module  2:MSGCLI。CLS

  VERSION1.0 CLASS

  BEGIN

  Mulitiuse = -1

  End

  attribute vb_name="msgclient"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

Option Explicit

public event recmsg(buval msg as VbMsgBoxResult )

Public minmsg As Long

Public maxmsg As Long

Public ID As Long

Public Sub setmsg(msg As vbmsg)

If msg.iType >= minmsg And msg.itupe < maxmsg Then

    RaiseEvent recmsg(msg)

    End If

  End Sub

Public Property Get key() As String

 key = "id:" & ID

End Property

 Module 3:MSGCLI。CLS

attribute vb_name="modglobal"

Option Explicit

Public clients As New Collection

Public clicount As Long

VERSION1.0 CLASS

  BEGIN

  Mulitiuse = -1

  End

  attribute vb_name="msgserver"

  attribute vb_globalnamespace=false

  attribute vb_creatable=true

  attribute vb_predeclaredid=false

  attribute vb_exposed=true

Option Explicit

Public Sub sendmsg(msg As VbMsgBoxResult)

Dim c As msgclient

 For Each c In clients

   c.setmsg msg

   DoEvents

 Next c

End Sub

Public Sub addmsgclient(c As msgclient)

 clicount = clicount + 1

 c.ID = clicount

 clients.Add c, c.key

End Sub

Public Sub delmsgclient(c As msgclient)

 clients.Remove c.key

If clients.Count = 0 Then licount = 0

End Sub

 comst msginfoid = 101

Private WithEvents mclient As msgclient

Private Sub form_load()

Set mclient = New msgclient

  mclient.minmsg = msginfoid

  mclient.maxmsg = msginfoid

    addmsgclient mclient

 End Sub

Private Sub Form_Unload(Cancel As Integer)

 delmsgclient mclient

End Sub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等天晴i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值