我正试图将WM_CLOSE
从我的应用程序发送到目标应用程序,以告诉它关闭。我在。NET 6.0上运行VS调试器。
我找到目标应用程序的句柄并向其句柄发送WM_CLOSE
消息,但spy++说消息从未到达目标窗口,因此目标窗口当然不会关闭。
我知道我有正确的目标句柄,因为我可以在spy++中看到它(我用spy++的十字准星手动标记目标窗口标题栏),它们匹配。同样,当我从句柄中获得窗口标题时,它会在目标应用程序的标题栏中显示相同的窗口标题。PostMessage
调用的返回代码为零,因此PostMessage
说它发送了消息。
但是PostMessage
和SendMessage
发送的消息在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项目中调用GetLastError
WinAPI函数不是微不足道的;有关如何正确地这样做的深入讨论,请参阅这里:WinApi - GetLastError与Marshal.GetLastWin32Error。