2009-09-01 13 views

Respuesta

6

que he encontrado la mejor solución sea Managed WindowsAPI. Tenía un control CrossHair que se podía usar para seleccionar una ventana (no parte de la pregunta), y un método AllChildWindows para obtener todas las ventanas secundarias que probablemente envolvían la función EnumChildWindows. Mejor no reinventar la rueda.

9

Uso:.

internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam); 

[DllImport("user32.dll")] 
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam); 

obtendrá devoluciones de llamada de la función se pasa en

3

Aquí hay una alternativa administrada a EnumWindows, pero igual necesitará usar EnumChildWindows para encontrar el manejador de la ventana secundaria.

foreach (Process process in Process.GetProcesses()) 
{ 
    if (process.MainWindowTitle == "Title to find") 
    { 
     IntPtr handle = process.MainWindowHandle; 

     // Use EnumChildWindows on handle ... 
    } 
} 
+0

Estoy tratando de hacer esto, pero no hay una ventana principal para el proceso. – Epu

+1

Epu, si no hay una ventana principal, entonces el proceso no tendrá un identificador de ventana para obtener (es decir, Process.MainWindowHandle == IntPtr.Zero). –

15

Here que tienen una solución de trabajo:

public class WindowHandleInfo 
{ 
    private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam); 

    [DllImport("user32")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam); 

    private IntPtr _MainHandle; 

    public WindowHandleInfo(IntPtr handle) 
    { 
     this._MainHandle = handle; 
    } 

    public List<IntPtr> GetAllChildHandles() 
    { 
     List<IntPtr> childHandles = new List<IntPtr>(); 

     GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles); 
     IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList); 

     try 
     { 
      EnumWindowProc childProc = new EnumWindowProc(EnumWindow); 
      EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList); 
     } 
     finally 
     { 
      gcChildhandlesList.Free(); 
     } 

     return childHandles; 
    } 

    private bool EnumWindow(IntPtr hWnd, IntPtr lParam) 
    { 
     GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam); 

     if (gcChildhandlesList == null || gcChildhandlesList.Target == null) 
     { 
      return false; 
     } 

     List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>; 
     childHandles.Add(hWnd); 

     return true; 
    } 
} 

Como consumir:

class Program 
{ 
    [DllImport("user32.dll", EntryPoint = "FindWindowEx")] 
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

    static void Main(string[] args) 
    { 
     Process[] anotherApps = Process.GetProcessesByName("AnotherApp"); 
     if (anotherApps.Length == 0) return; 
     if (anotherApps[0] != null) 
     { 
      var allChildWindows = new WindowHandleInfo(anotherApps[0].MainWindowHandle).GetAllChildHandles(); 
     } 
    } 
} 
+0

¿cómo puedo obtener user32.dll? – jai

+0

@jai Es una biblioteca de Windows, ya está presente y registrada en su máquina. Ese código debería funcionar sin la necesidad de referencias adicionales. –

+0

gracias @caffe .... Pero en realidad si uso user32.dll, la aplicación pide algún tipo de permiso ... donde no puedo ejecutar la aplicación ... ¿cómo puedo resolver eso ... – jai

Cuestiones relacionadas