我们来自五湖四海,不为别的,只因有共同的爱好,为中国互联网发展出一分力!
领航时时彩重庆版

时时彩稳赚dd:VB程序中如何处理随机事件

2014年05月09日22:26 阅读: 29938 次

领航时时彩重庆版 www.9nwl5.cn 标签: VB程序中如何处理随机事件

在程序设计过程中,如何轻松地处理众多的随机 事件,往往是制作大型系统首先要考虑的问题之一。用C语言开发Windows程序时,可以方便 地使用消息机制(Message),但是,设计VB程序时,就没有这样的方便条件了。例如,多个窗 口同时打开同一个表(Table),当在一个窗口中对数据进行了修改,而其他的窗口也能够随 之进行数据更新,这时就需要有一条说明数据改变了的消息在所有的窗口间进行广播。如 果使用的语言是C,只需要定义一条用户消息(UserMessage),就可以实现这一点??墒侨?果是用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增添了许多强有力的特性,有几点特性,正好 可以帮助我们解决难题。先让我介绍一下这几个特性: 
用户自定义事件:在类??橹?,可以使用Event关键字来定义用户自定义事件,使用RaiseEvent 语句来产生该事件,这一机制给处理随机事件带来极大的方便。上面说的消息广播引擎, 就可以不再使用Timer控件做支持,而是当收到需要广播的消息时,产生一个预定义的事 件,而需要处理消息的客体对象,只需截获该事件,就完成了消息的传递。 
ActiveXEXE部件:利用VB,可以方便地将共享代码封装在ActiveX部件之中。将消息 广播引擎实现于一个ActiveX部件之中,不仅方便了在程序中使用,而且更为重要的一点 是,可以实现跨进程间的消息传递。因为ActiveX部件有内部(DLL)外部(EXE)两种,对于 外部部件,可以对??槟诘娜质菔迪止蚕恚ü赜贏ctiveX两种代码部件的区别,请阅 读VB的联机帮助文件)。 
远程自动化连接:ActiveX部件,是一种标准的客户机/服务器结构,利用Windows平台 的COM模型,VB已能方便地将这种结构扩展到整个网络的范围。所以,我们的消息广播设 计,在实现了进程间的消息传递之后,进而实现网络上的消息传递,也成为可能。 
通过上面的几点介绍,这一方式的设计思想也就比较 清楚了,在具体设计时,我通过四个??橹涞南嗷バ?,完成了消息的发送、广播及接收,并 将这四个??榉庾霸谝桓鯝ctiveXEXE部件之中。下面就是这三个类??榈募虻ソ樯芗霸创?码: 
类??橹唬篗sg.cls 
在该??橹?,定义了消息数据结构VbMsg类,它是消息 传递中的载体。这里只是一个简单的例子,如果想实现更多的功能,如建立两点间的数据通道, 而不是单纯的广播消息,则可能需要对该结构进行一些扩充。 

VERSION 1.0 CLASS 
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 

类??橹篗sgCli.cls 
本??槭嵌钥突Ы邮斩薓sgClient类的定义,这相当 于一个消息接收器。在这个类中定义的一个RecMsg事件,当接收器收到消息时(过程SetMsg被 调用),就产生这一事件。接收器的建立者就截获这一事件,并处理消息。为了避免接收不必要 的消息,声明了minMsg、maxMsg两个变量,以便对VbMsg中的iType属性进行过滤。 

VERSION 1.0 CLASS 
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) 
End If 
End Sub 
' 根 据ID, 返 回 对 象 的 关 键 字, 
只 应 由 消 息 服 务 器(MsgServer) 调 用 
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 过 程) 依 次 发 送 给 列 表 中 的 所 有 接 收 器。 注 意, 这 个 类 被 声 明 为 公 共 全 局 类, 这 主 要 是 为 了 方 便 使 用( 不 必 在 每 个 程 序 中 再 建 立 该 类, 过 程 名 全 局 有 效)。 

VERSION 1.0 CLASS 
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 程 序 时, 往 往 会 感 觉 到 程 序 的 实 际 运 行 过 程 与 你 想 象 的 相 差 甚 远, 调 试 时 就 非 常 希 望 看 到 程 序 运 行 时 后 台 的 一 些 情 况。 利 用 V B 的 单 步 执 行 或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 过 程 也 不 一 定 要 全 部 删 掉, 只 要 将 实 时 查 看 变 为 写 入 日 志 文 件, 这 些 运 行 时 的 信 息 也 是 日 后 软 件 维 护 的 第 一 手 资 料。
分享到: 更多
©2018 安全焦点 版权所有.

  • 奚国华委员:新兴际华将党建六大优势转化为发展优势 2018-12-06
  • 创业女青年哈丽娟:世界是自己的 与他人没关系 2018-12-06
  • 移植2胚怀5胎 一针减3化风险 十堰市人民医院再创生命奇迹 2018-11-06
  • 首届妈祖信俗“立德”论坛成功举办 2018-10-25
  • 郧西男孩两条腿“长”在一起 十堰市人民医院手术整形帮他迈开双腿 2018-10-25
  • 重磅 江西省委副书记李炳军同志任省委党校校长 2018-10-19
  • 商务部新闻发言人对美白宫6月18日声明发表谈话 2018-10-12
  • 从献血条件,看看你的身体是否达标 2018-09-26
  • 全国“非遗”保护工作先进名单公布 2018-09-26
  • 储大同 中国医学科学院肿瘤医院首席科学家 2018-08-15
  • 【理上网来·喜迎十九大】扶贫也创新!十八大以来年均减贫人数超1300万 获历史突破 2018-08-15
  • 开创美丽中国建设新局面 2018-08-13
  • 毛泽东三游故宫看了些什么 2018-08-13
  • 独家视频:新时代来啦! 2018-08-12
  • 旅游市场再创佳绩端午假期河北接待游客2026.77万 揽金147.79亿 2018-08-12
  • 76| 592| 440| 165| 63| 916| 803| 25| 180| 642|