Как получить заголовок окна, используя SendMessageTimeout в C # - PullRequest
3 голосов
/ 07 сентября 2010

Мне нужно перечислить все открытые окна и получить их заголовок, но проблема в том, что некоторые окна принадлежат одному и тому же процессу, но другому потоку, который заблокирован (ожидание мьютекса).Поэтому я не могу использовать 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 всегда равен нулю.Есть идеи?Большое спасибо.

Ответы [ 2 ]

6 голосов
/ 07 сентября 2010

@ Алекс дал тебе правильный ответ.Но так как я уже набрал код, вот объявление 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);

Передайте свой StringBuilder для lParam, так как WM_GETTEXT заполняет буфер, указанный вlParam, и вы можете просто передать IntPtr.Zero для lpdwResult.

1 голос
/ 07 сентября 2010

Вам нужно передать строку bufer в lParam, а не в lpdwResult. lpdwResult может быть NULL или Int32, он содержит результат обработки сообщения. Обратите внимание, что SendMessageTimeout не помогает получить заголовок неотвечающего окна, но предотвращает блокировку вызывающего абонента.

Edit: Интересно отметить, что объявление PInvoke для SendMessageTimeout зависит от сообщения, которое вы хотите отправить. В случае необходимости отправки разных сообщений в одной и той же программе, я думаю, можно сделать несколько объявлений PInvoke, вызывающих один и тот же API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...