2

我在一个非常古老的 VB6 应用程序上工作,它仍然是我们公司的主要项目。在开始这个项目之前,我从未使用过 Visual Basic,更不用说 VB6。我遇到过很多地方都有事件来保持表单响应,并且我越深入研究什么doevents,在尝试用它们来调试代码时,我就越需要挠头。

我正在研究一种方法,可以判断当我们点击那行代码时 doevent 是否真的会做任何事情。我希望如果有人对窗口泵和消息队列有更多了解,可以告诉我我的方法是否能有效地告诉我这种方法是否有效。我正在尝试使用PeekMessage来查看它们是否是队列中的任何消息,然后再点击 doevents 行。

 Public Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As msg, ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long

 Public Type POINTAPI
     X As Long
     Y As Long
 End Type

 Public Type msg
     hWnd As Long
     Message As Long
     Wparam As Long
     lParam As Long
     time As Long
     pt As POINTAPI
 End Type

 Public Sub PeekAtMessages()
      Dim oPeekMessage As msg
      Dim bPeekMessage As Boolean
      Dim lCtr As Long
      bPeekMessage = True

      bPeekMessage = PeekMessage(oPeekMessage, frmMain.hWnd, 0, 0, 0)
      Debug.Assert bPeekMessage = True
      Debug.Print "DoEvents: Message= Hex(" & Hex(oPeekMessage.Message) & ") Dec(" & oPeekMessage.Message & ") hWnd=" & oPeekMessage.hWnd & " lParam=" & oPeekMessage.lParam & " time=" & oPeekMessage.time & " Wparam=" & oPeekMessage.Wparam   
 End Sub

 Public Sub MyDoEvents()
      PeekAtMessages
      DoEvents
 End Sub

所以我希望当我打电话时,MyDoEvents我只会点击Debug.Assert bPeekMessage = True队列中没有消息的情况。这将允许我在处理旧的未注释代码时判断 doevents 是否确实做了某事。

我对此进行了测试,看起来我只在Debug.Assert没有事件时才点击,但我仍然不知道我的发现是否准确/可靠。有没有其他人有过尝试查看 doevent 将要做什么的经验?

4

1 回答 1

1

要记住的是 DoEvents 是一个神奇的词。模糊或不知道它做什么的人随机尝试它以防万一。

VB6 清除它自己的消息队列,然后调用 Sleep(0),这意味着所有其他应用程序都可以清除它们的队列。

当然,VBRuntime 中断您的代码并执行 VB6 事件具有与多线程相同的问题,可以访问全局/静态变量、部分更新等。我从未见过围绕 DoEvents 语句进行同步,也从未考虑过它.

Spy++ window message spyer 包含在 VB6 和 SDK 中。

在 Windows 中,一些消息是按需生成的。计时器、Paint 和其他一些实际上不在队列中。如果队列为空且程序查询,则 Windows 会查看是否设置了绘制或其他标志。如果是,则生成一条消息并清除该标志。所以 Paint 等是 FLAGS 而不是队列中的消息。

于 2014-10-17T20:39:42.247 回答