转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
在VB程序中处理随机事件         ★★★★

在VB程序中处理随机事件

作者:闵涛 文章来源:闵涛的学习笔记 点击数:901 更新时间:2009/4/23 14:57:45
    在Visual Basic(以下简称VB)程序设计过程中,如何轻松地处理众多的随机事件,往往是制作大型系统首先要考虑的问题之一。例如,多个窗口同时打开同一个表(Table),一个窗口中对数据进行了修改,而其它窗口也能够随之进行数据更新,这时就需要有一条说明数据改变了的消息在所有窗口间进行广播。在C中,只需要定义一条用户消息即可实现这一点;而用VB编程就不那么简单。

早期实现方法及局限性

  对于以上问题,笔者早期的实现方法是,自定义一个消息结构(VbMsg),并在程序的主窗体内建立一个消息广播引擎,主要由一个消息队列和一个定时消息广播器所组成。消息广播器每隔一固定时间检查一次消息队列,如果有消息存在,就将其发送给所有打开的窗口,并将该消息从队列中删除。如此再定义一个全局的消息发送过程(SendMsg),将要发送的消息(VbMsg)送入消息队列。这样当需要广播消息时,只需填充好消息结构,调用SendMsg过程即可。 

  这里较为复杂的是消息广播器如何将消息发送到各窗口。这需要作个硬性规定,即每一个窗体都必须定义一个形式完全相同的消息接收函数(RecMsg),在这个函数中对接收到的消息进行处理,当然也可以什么都不做。有了这样的规定之后,消息广播器在进行广播时,就可以利用VB系统定义的全局变量Forms,遍历所有的窗体,并调用一遍每个窗体的消息接收函数。其主要代码如下:

Public Sub SendMsgToForms(msg as VbMsg)
Dim frm as Form
For Each frm In Forms
frm.RecMsg msg
Next frm
End Sub  

  通过上面的这些过程,就可以实现在独立的程序中,对随机事件进行异步处理。这一方法的效果基本令人满意。但是它有几个较大的局限性:

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

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

? 消息的接收者只能是窗体,而作为真正的基础单元“类”却无法直接接收消息。 

VB5.0的新特性及实现方法

  VB 5.0 企业版增添了 嗲坑辛Φ奶匦裕梢越饩鲆陨夏烟狻!?

1、 用户自定义事件

  在类模块中,可以使用Event关键字来定义用户自定义事件,使用 RaiseEvent 语句来产生该事件,这一机制给处理随机事件带来了很大方便。本文中的消息广播引擎,就可以不再使用Timer控件做支持,而是当收到需要广播的消息时,产生一个预定义的事件;而需要处理消息的客体对象,只需截获该事件。

2、 ActiveX EXE组件

  利用VB,可以方便地将共享代码封装在ActiveX组件之中,从而可以实现跨进程间的消息传递。因为ActiveX组件有内部(DLL)、外部(EXE)两种,外部组件可以对模块内的全局数据实现共享。

3、 远程自动化连接

  ActiveX组件是一种标准的客户机/服务器结构,利用Windows平台的COM模型,VB能够方便地将这种结构扩展到整个网络的范围。所以,消息广播设计既可实现进程间的消息传递,也可实现网络上的消息传递。

  根据以上思想,笔者通过四个模块之间的相互协作,完成了消息的发送、广播及接收,并将这四个模块封装在一个ActiveX EXE组件之中。下面就是这四个类模块的简单介绍及源代码。

类模块之一:Msg.cls

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

BEGIN
MultiUse = -1 True
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 消息源说明
Public iDescription 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

类模块之二:MsgCli.cls

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

BEGIN
MultiUse = -1 True
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(ByVal msg As VbMsg)
通过设置消息的接收范围,过滤掉不需要的消息
Public minMsg As Long
Public maxMsg As Long
 
该对象的标志编号,使用时不应修改该值
Public ID As Long
事件产生过程,只应由消息服务器(MsgServer)调用
Public Sub SetMsg(msg As VbMsg)
If msg.iType >= minMsg And msg.iType <= maxMsg Then
RaiseEvent RecMsg(msg)
nd If
nd Sub
根据ID返回对象的关键字,只应由消息服务器调用
Public Property Get Key() As String
Key = “ID:& ID
End Property

类模块之三:Global.bas

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

Attribute VB_Name = “modGlobal
Option Explicit
消息服务器全局变量,消息接收客户列表
Public Clients As New Collection
消息接收客户ID计数器
Public CliCount As Long

类模块之四:MsgSrv.cls

  本模块定义了消息服务器类MsgServer,该类是消息广播引擎的主体,它主要管理维护消息接收器列表(Clients),将发送来的消息(调用SendMsg过程)依次发送给列表中的所有接收器。请注意:为了方便使用,该类被声明为公共全局类。

BEGIN
MultiUse = -1 True
END
Attribute VB_Name = “MsgServer
Attribute VB_GlobalNameSpace = True
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit
 
消息服务器类,发送消息
Public Sub SendMsg(msg As VbMsg)
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 CliCount = 0
End Sub

应用举例

  至此,一个小巧灵活的消息广播引擎就完成了,它的使用范围很广,用起来也很方便,只需在工程中引入编译过的ActiveX组件,就可以直接调用SendMsg发送消息。但可能在安装消息接收器(MsgClient)时会稍许有点麻烦,下面举例说明其应用。

  在设计Windows程序时,往往希望调试时能看到程序运行时后台的一些情况。利用VB的单步执行或Debug命令,会受到一些限制。利用消息广播引擎,制作一个通用的实时消息事件查看程序,就可以很好地解决这一问题。查看程序的主要工作是捕捉一组事先定义好的消息事件,并将消息的内容显示在列表框内。本应用可以只用一个窗体完成,主要代码如下。

Const 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
Private Sub mClient _RecMsg(ByVal msg As VbMsgSrv.VbMsg)
List1.AddItem msg.iTimeStr & Chr(9) & msg.iName & Chr(9) &
sg.iDescription
End Sub

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

Const MsgInfoID=101
Public Sub MsgInfo(iName As String,iDes As String)
Dim msg As New MsgClient
With msg
.iName = iName
. iDescription = iDes
End With
SendMsg msg
End Sub

 

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

155


[VB.NET程序]GSM短信模块库函数,可以用VB,VC,调用简单实用  [办公软件]PowerPoint做交互课件之弃用VBA
[办公软件]VBA获取U盘、主板、CPU序列号和网卡MAC地址  [办公软件]VBA设置文件属性及加密源代码示例
[办公软件]VBA中初始化ADO连接的几种方法  [网络安全]“VB破坏者变种N”病毒摘要
[Web开发]ASP.NET上传文件到数据库VB版  [办公软件]在Excel中利用VBA实现多表单元格数据的读取与赋值…
[办公软件]使用Vba读取已关闭的Excel工作薄数据到当前工作表…  [办公软件]Excel编程基础之VBA文件操作详解
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台