我在一个非常古老的VB6应用程序上工作,这仍然是我们公司的主要项目。在开始这个项目之前,我从未在Visual Basic中工作过,而不是VB6。我遇到了很多有地方的地方,以保持表格的响应性,我越是深入了解doevents
,在尝试调试使用它们的代码时,我越不得不挠头。
我正在研究一种方法,当我们点击那行代码时,可能会告诉doevent是否真的要做任何事情。我希望有一个对窗口泵和消息队列有更多了解的人可以告诉我,我的方法是否能有效告诉我这种方法是否有效。 我试图在我点击doevents行之前使用PeekMessage来查看它们是否是队列中的任何消息。
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将要做什么的经验?
答案 0 :(得分:1)
要记住的是,DoEvents是一个神奇的词。那些模糊或不知道它做什么的人会随意尝试它以防它起作用。
VB6清除它自己的消息队列,然后调用Sleep(0),这意味着所有其他应用程序都可以清除它们的队列。
当然,VBRuntime中断你的代码并执行VB6事件有同样的问题,多线程有,全局/静态变量可以被访问,部分更新等等。我从未见过围绕DoEvents语句的同步或任何想法已经给它。
Spy ++窗口消息spyer包含在VB6和SDK中。
在Windows中,某些消息是按需生成的。 Timers,Paint和其他一些实际上并不在队列中。如果队列为空并且程序查询,那么Windows将查看是否设置了paint或其他标志。如果是,则生成消息并清除该标志。所以Paint等是FLAGS而不是队列中的消息。