Возвращает дескриптор окна по имени / названию
Я не могу решить эту проблему. Я получаю ошибку:
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;
}
Я пробовал разными способами, и каждый из них не удается. Заранее спасибо.
7 ответов
Не забывай, что объявляешь себя 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
Как вариант, чтобы решить эту проблему:
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public IntPtr GetHandleWindow(string title)
{
return FindWindow(null, title);
}
Опоздал на несколько лет, но, как уже упоминалось, охват hWnd
только в foreach
петля.
Однако стоит отметить, что, если вы ничего не делаете с этой функцией, то есть две проблемы с ответами, которые предоставили другие:
- Переменная
hWnd
на самом деле не нужно, так как это только для одной вещи (как переменная дляreturn
) 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;
}
Потому что вы декларируете 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;
}
Для метода, который позволяет вам выполнять поиск без учета регистра по части заголовка окна (который будет искать все окна, а не только первое окно для каждого процесса)
using System.Runtime.InteropServices;
using System.Text;
var hwnd = GetHandleByTitle("Chrome");
Console.WriteLine(hwnd);
[DllImport("USER32.DLL")]
static extern IntPtr GetShellWindow();
[DllImport("USER32.DLL")]
static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
static IntPtr GetHandleByTitle(string windowTitle)
{
const int nChars = 256;
IntPtr shellWindow = GetShellWindow();
IntPtr found = IntPtr.Zero;
EnumWindows(
delegate (IntPtr hWnd, int lParam)
{
//ignore shell window
if (hWnd == shellWindow) return true;
//get Window Title
StringBuilder Buff = new StringBuilder(nChars);
if (GetWindowText(hWnd, Buff, nChars) > 0)
{
//Case insensitive match
if (Buff.ToString().Contains(windowTitle, StringComparison.InvariantCultureIgnoreCase))
{
found = hWnd;
return true;
}
}
return true;
}, 0
);
return found;
}
delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
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;
}
#include <windows.h>
#using <System.dll>
using namespace System;
using namespace System::Diagnostics;
using namespace System::ComponentModel;
// get window handle from part of window title
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;
}
}
return hWnd;
}
// get window handle from exact window title
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public IntPtr GetHandleWindow(string title)
{
return FindWindow(null, title);
}