VB程序中处理随机事件

2016-02-19 21:46 11 1 收藏

今天图老师小编要跟大家分享VB程序中处理随机事件,精心挑选的过程简单易学,喜欢的朋友一起来学习吧!

【 tulaoshi.com - 编程语言 】

  在程序设计过程中,如何轻松地处理众多的随机事件,往往是制作大型系统首先要考虑的问题之一。用C语言开发Windows程序时,可以方便地使用消息机制(Message),但是,设计VB程序时,就没有这样的方便条件了。例如,多个窗口同时打开同一个表(Table),当在一个窗口中对数据进行了修改,而其他的窗口也能够随之进行数据更新,这时就需要有一条说明数据改变了的消息在所有的窗口间进行广播。如果使用的语言是C,只需要定义一条用户消息(UserMessage),就可以实现这一点。可是如果是用VB编程,做起来就不是那么简单了。VB5.0企业版中增添了许多强有力的特性,有几点特性,正好可以帮助我们解决难题。先介绍一下这几个特性:

  1.用户自定义事件:在类模块中,可以使用Event关键字来定义用户自定义事件,使用RaiseEvent语句来产生该事件,这一机制给处理随机事件带来极大的方便。当收到需要广播的消息时,产生一个预定义的事件,而需要处理消息的客体对象,只需截获该事件,就完成了消息的传递。

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

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

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

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

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属性进行过滤。

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)

End If End Sub ' '

根 据ID, 返 回 对 象 的 关 键 字, 只 应 由 消 息 服 务 器(MsgServer)调 用

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

Public Property Get Key() As String Key="ID:" & ID End Property

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

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

Option Explicit

/ 说 明:

/ 消 息 服 务 器 全 局 变 量

/消 息 接 收 客 户 列 表

Public Clients As New Collection

/ 消 息 接 收 客 户ID 计 数 器

Public CliCount As Long

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

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) & msg.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过程也不一定要全部删掉,只要将实时查看变为写入日志文件,这 些运行时的信息也是日后软件维护的第一手资料。

来源:https://www.tulaoshi.com/n/20160219/1627110.html

延伸阅读
作者: juky_huang 事件的简单解释: 事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某些其他的程序逻辑触发的。引发(触发)事件的对象叫做事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。 在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)...
VC6:          在窗体上点击右键,“ClassWizard”然后在“MESSAGES”中选择“PreTranslateMessage”,添加函数即可。 VC.NET:          将窗口切换到窗体(.cpp)代码编辑状态,在属性中选择重载列表,然后选择“PreTranslateMessage”即可。 BOOL CDaily...
《魔法世界》全随机事件解析攻略 《魔法世界》游戏中随机事件是在世界当中会出现的偶然天文现象或人为和非人为的因素所导致的事情。 这些事件会对战局、生产作业等都会带来一定影响,有好也有坏。 随机事件列表(共51) 探索远古(Ancient Discovery) 作用:一个新的世界结构会出现在地图当中。 婴儿潮(Baby Boom) 作用:一个单一的城市人口...
要想控制拨号网络,就要使用RemoteAccessService(RAS)API,这个API最早是在WindowsforWorkgroup3.11中出现的,现在它已经成为Win32API的一个组成部分。挂断拨号网络的函数叫RasHangUp,这个函数的功能和用法都很简单,它只有一个参数,就是要挂断的拨号网络连接的句柄。我们可以利用RasEnumConnections获得当前系统所有RAS连接(通常我们的系统...
UDP协议是一种无连接协议,两台计算机之间的数据传输类似于传递邮件:消息从一台计算机发送到另一台计算机,但是两者之间没有明确的连接。 由于UDP协议不需要显式的连接,就需要在两个Winsock控件中间发送数据,关键需要完成以下的三步: 1.将RemoteHost属性设置为另一台计算机的名称。 2.将RemotePort属性设置为第二个控件的Loca...

经验教程

120

收藏

10
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部