Una volta ottenuto il processo, è possibile enumerare tutte le finestre del processo e verificare se qualsiasi di loro corrispondono alla finestra che stai cercando.
avrete bisogno dei seguenti P/Invoke dichiarazioni
[DllImport("user32", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
Il followng è un esempio di un paio di funzioni che possono essere utilizzati per trovare le finestre di uno specifico procedimento, ho capito dalla tua domanda che si avere il processo, il problema è enumerare le finestre.
public static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
foreach (ProcessThread t in process.Threads)
{
windowHandle = FindWindowInThread(t.Id, compareTitle);
if (windowHandle != IntPtr.Zero)
{
break;
}
}
return windowHandle;
}
private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
Quindi è possibile chiamare la funzione FindWindowInProcess di trovare una finestra che è il titolo termina con "ABC" come esempio.
IntPtr hWnd = FindWindowInProcess(p, s => s.EndsWith("ABC"));
if (hWnd != IntPtr.Zero)
{
// The window was found....
}
Naturalmente è possibile sostituire s => s.EndsWith ("ABC") con qualsiasi espressione in grado di soddisfare i criteri di ricerca per la finestra, potrebbe essere un espressione regolare ecc
qui è anche una versione di FindThreadWindow che controlla anche il primo livello di finestre figlio. Potresti fare questo e renderlo una funzione ricorsiva se la tua finestra è più in basso nella gerarchia.
private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
else
{
windowHandle = FindChildWindow(hWnd, compareTitle);
if (windowHandle != IntPtr.Zero)
{
return false;
}
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
private static IntPtr FindChildWindow(IntPtr hWnd, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumChildWindows(hWnd, (hChildWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hChildWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hChildWnd;
return false;
}
return true;
}, IntPtr.Zero);
return windowHandle;
}
risposta molto elaborata, funziona come un fascino. – Axarydax
In FindChildWindow ... non dovrebbe essere hChildWnd invece di hWnd dopo aver controllato il risultato di compareTitle? – seveves