c# - 如何在 C# 中使用 SendMessageTimeout 获取窗口标题

标签 c# winapi

我需要枚举所有打开的窗口并获取它们的标题,但问题是某些窗口属于同一进程但属于不同的线程,该线程被阻塞(等待互斥锁)。因此,我不能对属于我自己的进程的窗口使用 GetWindowText,因为这将导致 SendMessage 调用,这将阻止我的代码的执行(因为它将等待被阻止的线程的 relpy)。

顺便说一句,这里有一篇关于 GetWindowText 内部工作原理的有趣文章:http://blogs.msdn.com/b/oldnewthing/archive/2003/08/21/54675.aspx

作为解决方案,决定对窗口使用 SendMessageTimeout 以检索其标题,但我无法使其工作。我正在做的是:

[DllImport("User32.dll")]
public static extern int SendMessageTimeout(
  IntPtr hWnd, 
  int uMsg, 
  int wParam, 
  int lParam, 
  int fuFlags, 
  int uTimeout, 
  out StringBuilder lpdwResult);

...

StringBuilder sb = new StringBuilder(256);
int result = Win32API.SendMessageTimeout(
  hWnd, 
  0x0D /*WM_GETTEXT*/, 
  256, 
  0, 
  10 /*SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG*/, 
  500, 
  out sb);

但我总是得到 0,表示函数失败,并且 sb 始终为 null。 有任何想法吗? 非常感谢。

最佳答案

@Alex 已经给了你正确的答案。但由于我已经输入了代码,这里是您可以使用的 P/Invoke 声明。

[DllImport("User32.dll", SetLastError=true)] 
public static extern int SendMessageTimeout( 
  IntPtr hWnd,  
  uint uMsg,  
  uint wParam,
  StringBuilder lParam,  
  uint fuFlags,  
  uint uTimeout,  
  IntPtr lpdwResult);

为 lParam 传递你的 StringBuilder,因为 WM_GETTEXT填充由 lParam 指定的缓冲区,您只需将 IntPtr.Zero 传递给 lpdwResult。

关于c# - 如何在 C# 中使用 SendMessageTimeout 获取窗口标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3658998/

相关文章:

c++ - CAppModule vs CAtlExeModuleT ,获取应用程序消息循环

c# - == 对象被装箱时运算符重载

c# - 您在 .NET 中使用代码生成做什么?

c# - 创建骨架 WiX 扩展时失败

c++ - 手动调出工具提示? (WinAPI)

c - 调整窗口大小时是否可以完全消除闪烁?

c++ - 为来自不同进程的窗口设置父级是否正确?

c# - ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

c# - jqgrid动态格式化列

c++ - 我是否需要使用 COM(组件对象模块)