- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们的应用程序充当 COM 服务器,其中所有自动化都发生在单个 STA 单元内(在应用程序的主线程中),并且一些进行长时间(> 10 分钟)调用的 VBS 脚本失败并显示错误“系统调用失败(80010100)” .一些研究( one , two , three )表明这可能是由于消息队列填满造成的,因此当 COM 尝试调用下一个方法时,它无法调用。
万一它很重要,应用程序是用 Embarcadero RAD Studio 2010 开发的(主要是 C++ ,对于某些 COM 类,只有 Delphi 。)
我想我会在冗长的 COM 方法调用结束时(即,在它返回之前)检查线程的消息队列,以查看它包含的内容,使用 GetQueueStatus
和 PeekMessage
。虽然队列似乎已满,但我看到了一些奇怪的行为,而且我无法弄清楚为什么 PeekMessage
的行为方式如此,以及队列为何已满 - 即它充满了什么。
前面稍微冗长的解释:
测试线程的消息队列已满
像这样的代码:
int iMessages = 0;
DWORD dwThreadId = GetCurrentThreadId();
while (::PostThreadMessage(dwThreadId, WM_USER, 0, 0)) {
iMessages++;
}
if (GetLastError() == ERROR_NOT_ENOUGH_QUOTA) {
String strError = L"Not enough quota, posted " + IntToStr(iMessages) + L" messages";
// Do something with strError
}
Application->ProcessMessages()
(调用应用程序的消息循环直到它为空,对于那些不是 Delphi/C++Builder 用户的人 - 这是一个相当正常的“get/translate/dispatch until no more messages”方法)解决了这个问题并且 COM 脚本可以成功调用下一个方法。虽然在这种特定情况下可能没问题,但在有效的随机位置调用
ProcessMessages()
是需要避免的 - 它可能导致重入。如果可能,我想找出导致队列已满的原因。
GetQueueStatus
来确定队列中的消息类型显示有计时器(
QS_TIMER
)、发布的消息(
QS_POSTMESSAGE
)、“所有发布的消息”(即其他发布的消息,
QS_ALLPOSTMESSAGE
)和 10445 条消息(
QS_PAINT
)。
PeekMessage
和
PM_REMOVE
删除选择的消息或消息类型,以部分清空队列并计算每种类型消息的数量。
while (::PeekMessage(&oMsg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD | (QS_TIMER << 16)) != 0) {...
WM_APP+something
消息;这个可能真的是经常发送。
while (::PeekMessage(&oMsg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE | PM_NOYIELD) != 0) {...
while (::PeekMessage(&oMsg, NULL, WM_APP+202, WM_APP+202, PM_REMOVE | PM_NOYIELD) != 0) {...
最佳答案
GetQueueStatus
() 接受 QS_xxx
参数但 PeekMessage
() 只接受 PM_QS_xxx
常数。
这解释了WM_TIMER
数量之间的差异。由 QueueStatus
指示的消息随后被 PeekMessage
删除()。您的 PeekMessage(PM_REMOVE)
调用未删除 WM_TIMER
消息,但完全是别的东西。
我认为您误解了 PeekMessage
的文档()。 PM_QS_POSTMESSAGE
被记录为与以下等价:
((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16)
PM_QS_xxx
常量被记录为等于相应的
QS_xxx
常数
<< 16
,但没有任何地方说情况始终如此,可以推断为所有
QS_xxxx
常数。
QS_TIMER << 16
正在产生一些过滤器,它不仅仅是过滤
WM_TIMER
消息(很明显,我不能肯定地说它产生了什么过滤器)。
WM_TIMER
是唯一与计时器相关的消息,因此不需要为更大的 super 计时器消息集设置更宽的过滤器 - 没有这样的 super 集。如果您想过滤计时器消息,只需过滤
WM_TIMER
.
关于delphi - 什么解释了这种奇怪的 PeekMessage 行为(尝试处理完整的消息队列,过滤特定消息)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8229710/
我是一名优秀的程序员,十分优秀!