it-roy-ru.com

Возвращает дескриптор окна по имени/названию

Я не могу решить эту проблему .. Я получаю сообщение об ошибке:

The name 'hWnd' does not exist in the current context

Звучит очень легко и, вероятно, ... извините за столь очевидные вопросы.

Вот мой код:

    public static IntPtr WinGetHandle(string wName)
    {
        foreach (Process pList in Process.GetProcesses())
        {
            if (pList.MainWindowTitle.Contains(wName))
            {
                IntPtr hWnd = pList.MainWindowHandle;
            }
        }
        return hWnd;
    }

Я пытался разными способами, и каждый не удается ... Заранее спасибо.

10
VixinG

Не забывайте, что вы объявляете себя hWnd внутри цикла - это означает, что он виден только внутри цикла. Что происходит, если заголовок окна не существует? Если вы хотите сделать это с for, вы должны объявить это вне вашего цикла, установить его внутри цикла и вернуть ...

  IntPtr hWnd = IntPtr.Zero;
  foreach (Process pList in Process.GetProcesses())
  {
      if (pList.MainWindowTitle.Contains(wName))
      {
          hWnd = pList.MainWindowHandle;
      }
  }
  return hWnd; //Should contain the handle but may be zero if the title doesn't match
13
Basic

Поскольку вы объявляете hWnd внутри блока if, он недоступен для оператора return, который находится вне его. См. http://www.blackwasp.co.uk/CSharpVariableScopes.aspx для уточнения.

Код, который вы указали, можно исправить, переместив объявление переменной hWnd:

public static IntPtr WinGetHandle(string wName)
{
    IntPtr hwnd = IntPtr.Zero;
    foreach (Process pList in Process.GetProcesses())
    {
        if (pList.MainWindowTitle.Contains(wName))
        {
            hWnd = pList.MainWindowHandle;
        }
    }
    return hWnd;
}
3
Mitch

hWnd объявляется в цикле foreach. Его контекст находится внутри цикла foeach. Чтобы получить его значение, объявите его вне цикла foreach.

Используйте это так,

public static IntPtr WinGetHandle(string wName){
    IntPtr hWnd = NULL;

    foreach (Process pList in Process.GetProcesses())
        if (pList.MainWindowTitle.Contains(wName))
            hWnd = pList.MainWindowHandle;

    return hWnd;
}
1
Shiplu Mokaddim

Как вариант, чтобы решить эту проблему:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

public IntPtr GetHandleWindow(string title)
{
    return FindWindow(null, title);
} 
1
Wizard

Пришло несколько лет назад, но, как уже упоминалось, область действия hWnd находится только в цикле foreach.

Однако стоит отметить, что, если вы ничего не делаете с этой функцией, то есть две проблемы с ответами, которые предоставили другие:

  1. Переменная hWnd на самом деле не нужна, поскольку она существует только для одной цели (как переменная для return)
  2. Цикл foreach неэффективен, так как даже после того, как вы нашли совпадение, вы продолжаете искать остальные процессы. На самом деле, он вернет последний найденный процесс, который соответствует.

Предполагая, что вы не хотите соответствовать последнему процессу (пункт № 2), тогда это более чистая и эффективная функция:

public static IntPtr WinGetHandle(string wName)
{
    foreach (Process pList in Process.GetProcesses())
        if (pList.MainWindowTitle.Contains(wName))
            return pList.MainWindowHandle;

    return IntPtr.Zero;
}
0
Richard