【问题标题】:SendMessage - strange return valuesSendMessage - 奇怪的返回值
【发布时间】:2015-04-01 07:34:57
【问题描述】:

我有一个应用程序,它使用三个辅助线程从数据库中读取数据(3 个不同的表,总共约 160,000 行),从这些行创建对象,然后将对象添加到两个列表之一,具体取决于什么类型对象的创建。帮助线程通过 SendMessage 调用将对象添加到列表中,以便主线程是唯一在列表中添加/删除的对象。

奇怪的是 SendMessage 并不总是成功,我会经常收到这两个错误 ERROR_ALREADY_EXISTS (183) 和 ERROR_TRUSTED_DOMAIN_FAILURE (1788)。 SendMessage 调用的函数只是将一个对象添加到列表中,并且此函数始终返回成功(0)。没有创建文件(正如 ERROR_ALREADY_EXISTS 似乎暗示的那样),也没有网络调用,所以我不确定为什么会收到 ERROR_TRUSTED_DOMAIN_FAILURE 错误。

关于可能导致这些错误的原因或调试这些错误的任何方法的任何想法?

请注意,在使用 SendMessage 之前,我使用的是 PostMessage,会收到很多 ERROR_NOT_ENOUGH_QUOTA 错误; SendMessage 使该实用程序工作得更好。

【问题讨论】:

  • 如果我使用 PostMessage,我还能使用 GetLastError() 吗?我喜欢线程安全的数组方法,谢谢。
  • @HansPassant 你这是什么意思?它说我仍在处理“非排队传入消息”的部分(是其他SendMessage()s 吗?)?
  • 这仅适用于工作线程创建自己的窗口并具有消息队列的情况。不太可能在这里申请。
  • @HansPassant 那么我在文档中缺少什么说非系统消息不是线程安全的?还是我们区分线程安全和阻止调用线程运行?
  • 发送到另一个进程的非系统消息不能包含指针,因为它们不会自动编组到目标进程的地址空间。但是,在发送者自己的进程中发送的非系统消息可以包含指针,并且应该是线程安全的,因为发送代码在接收窗口过程完成处理消息之前被阻塞。

标签: winapi visual-c++


【解决方案1】:

SendMessage() 返回已发送消息的结果。由消息处理程序决定SendMessage() 实际返回给发送代码的值。 GetLastError() 仅在 SendMessage() 本身失败时才有意义,并且您必须使用 SetLastError() 来检测它,例如:

SetLastError(0);
LRESULT res = SendMessage(...);
if ((res == 0) && (GetLastError() != 0))
{
    // send failed, for example GetLastError()=ERROR_ACCESS_DENIED if UIPI blocked the message ...
}
else
{
    // send succeeded, res is whatever value the message handler returned ...
}

只有当目标 HWND不同的线程 拥有而不是调用 SendMessage() 的线程时,这才可靠地工作。 GetLastError() 不能跨线程边界影响。在消息处理程序中对SetLastError() 的任何调用都会影响HWND 所属线程的错误代码,而不是发送线程的错误代码。

但是,如果目标HWND 由调用SendMessage()同一线程 拥有,并且消息处理程序发生 调用SetLastError()(直接,或间接通过失败的 API 调用)设置非零错误代码,发生返回 0 作为 SendMessage() 的结果值返回给发件人,那么我能做到的唯一方法考虑让发送者区分GetLastError()返回的错误码是SendMessage()自己在失败时设置的,还是由消息处理程序设置的,是通过SetWindowsHookEx()使用线程语言环境消息钩子来检测是否消息处理程序是否实际被调用(我能想到的唯一条件是目标HWND 无效,因此SendMessage() 找不到它的窗口过程)。

您可以使用GetWindowThreadProcessId()GetCurrentThreadId() 来检查目标HWND 是否由调用线程拥有。

【讨论】:

  • 但这可靠吗?没有什么能阻止我的信息做同样的事情。还是我误解了你想要表达的意思?
猜你喜欢
  • 2020-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 2013-04-26
  • 2013-02-07
  • 2012-06-21
  • 2013-10-08
相关资源
最近更新 更多