SendMessage - 奇怪的返回值

时间:2015-03-31 15:27:27

标签: winapi visual-c++

我有一个应用程序,它使用三个辅助线程从数据库中读取(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使实用程序工作得更好。

1 个答案:

答案 0 :(得分:2)

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()相同线程所有,并且消息处理程序发生来调用{ {1}}(直接或间接通过失败的API调用)设置非零错误代码,发生返回0作为SetLastError()的结果值返回到发件人,那么我能想到的唯一方法是让发件人区分SendMessage()返回的错误代码是由GetLastError()本身在失败时设置的,还是由消息处理程序设置的,是使用线程-locale消息钩子通过SendMessage()来检测消息处理程序是否实际被调用(我能想到的唯一条件是,如果目标SetWindowsHookEx()无效,那么HWND就不能找到它的窗口程序。)

您可以使用SendMessage()GetWindowThreadProcessId()来检查目标GetCurrentThreadId()是否归调用线程所有。