WM_CLOSE未到达目标窗口;spy++也看不到WM_CLOSE



我正试图将WM_CLOSE从我的应用程序发送到目标应用程序,以告诉它关闭。我在。NET 6.0上运行VS调试器。

我找到目标应用程序的句柄并向其句柄发送WM_CLOSE消息,但spy++说消息从未到达目标窗口,因此目标窗口当然不会关闭。

我知道我有正确的目标句柄,因为我可以在spy++中看到它(我用spy++的十字准星手动标记目标窗口标题栏),它们匹配。同样,当我从句柄中获得窗口标题时,它会在目标应用程序的标题栏中显示相同的窗口标题。PostMessage调用的返回代码为零,因此PostMessage说它发送了消息。

但是PostMessageSendMessage发送的消息在spy++滚动显示中实时记录的目标窗口的消息中都是可见的。

为什么我的WM_CLOSE消息不是:(1)在spy++中可见,(2)没有到达目标应用程序?

public static void
SendCloseToHandle(IntPtr handle) {
var result = PostMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
if (result != 0) {
FormAppendTextContent($"WM_CLOSE failed to send. {result:X}");
return;
}
//SendMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
var title = GetWindowTitle(handle);
FormAppendTextContent($"Posted WM_CLOSE message to {title} '{handle:X}'");
}

并且PostMessage调用的返回码为零,因此PostMessage表示它发送了消息

这是不对的。PostMessage函数失败时返回0。因此,假设您的代码(如所示)没有显示错误消息,那么PostMessage调用失败,并且WM_CLOSE没有被发送到目标。

您需要将错误处理更改为使用if (result == 0) { ...,然后在该块中调用GetLastError函数来检索错误代码。如果那是5(正如我怀疑的那样),那么调用由于不正确的UIPI访问而失败,您将需要解决该问题,如本Q/A中所述:跨进程PostMessage, UIPI限制和uipaccess = " true "。


注意:从c#和/或。net项目中调用GetLastErrorWinAPI函数不是微不足道的;有关如何正确地这样做的深入讨论,请参阅这里:WinApi - GetLastError与Marshal.GetLastWin32Error。

最新更新