web-dev-qa-db-de.com

Rückgabe des Fenster-Handle durch Namen/Titel

Ich kann dieses Problem nicht lösen. Ich erhalte eine Fehlermeldung:

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

Das hört sich sehr einfach an und ist wahrscheinlich ... es tut mir leid, so offensichtliche Fragen zu stellen.

Hier ist mein Code:

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

Ich habe es auf viele verschiedene Arten versucht und jeder scheitert. Vielen Dank im Voraus.

10
VixinG

Vergessen Sie nicht, dass Sie innerhalb der Schleife hWnd deklariert haben. Dies bedeutet, dass sie nur innerhalb der Schleife sichtbar ist. Was passiert, wenn der Fenstertitel nicht existiert? Wenn Sie es mit einer for tun wollen, sollten Sie es außerhalb Ihrer Schleife deklarieren, innerhalb der Schleife setzen und dann zurückgeben ...

  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

Da Sie innerhalb des if-Blocks hWnd deklarieren, kann auf die return-Anweisung nicht zugegriffen werden, die sich außerhalb davon befindet. Siehe http://www.blackwasp.co.uk/CSharpVariableScopes.aspx zur Verdeutlichung.

Der von Ihnen angegebene Code kann durch Verschieben der Deklaration der Variablen hWnd festgelegt werden:

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 wird in der foreach-Schleife deklariert. Sein Kontext ist in foeach Schleife . Um seinen Wert zu erhalten, deklarieren Sie ihn außerhalb der foreach-Schleife.

Verwenden Sie es so,

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

Als Option zur Lösung dieses Problems:

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

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

Dies kommt einige Jahre später, aber wie bereits erwähnt, liegt der Geltungsbereich von hWnd nur in der foreach-Schleife.

Allerdings ist es erwähnenswert, dass Sie, sofern Sie nichts anderes mit der Funktion tun, zwei Probleme mit den Antworten haben, die andere gegeben haben:

  1. Die Variable hWnd ist eigentlich nicht erforderlich, da sie nur für eine Sache bestimmt ist (als Variable für die return).
  2. Die foreach-Schleife ist ineffizient, da Sie auch nach dem Finden einer Übereinstimmung die restlichen Prozesse durchsuchen. Tatsächlich gibt es den letzten gefundenen Prozess zurück, der gefunden wird.

Angenommen, Sie möchten den letzten Prozess nicht abgleichen (Punkt 2), dann ist dies eine sauberere und effizientere Funktion:

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