Obtener mango de una ventana que no tiene título .. (C #)
Pregunta
¿Cómo podemos obtener el identificador de una ventana que no tiene un título? ¿Hay una manera de enumerar todas las ventanas en el escritorio y filtrar la ventana que no tienen un título (en mi caso, sólo hay una) y conseguir el mango de la misma .. o especificando otros atributos como una ventana que tiene un botón específico o cuadro de lista, etc ...
Solución
Esto debe hacerlo:
...
using System.Runtime.InteropServices;
using System.Diagnostics;
...
public class foo()
{
...
[DllImport ("user32")]
internal static extern int GetWindowText (int hWnd, String text, int nMaxCount);
[DllImport ("user32.dll")]
public static extern int GetWindowTextLength (int hWnd);
[DllImport ("user32.dll")]
public static extern int FindWindow (String text, String class_name);
[DllImport ("user32.dll")]
public static extern int FindWindowEx (int parent, int start, String class_name);
[DllImport ("user32.dll")]
public static extern int GetWindow (int parent, uint cmd);
public List<int> FindTitlelessWindows()
{
List<int> titleless = new List<int> ();
Process [] procs = Process.GetProcesses ();
IntPtr hWnd;
foreach (Process proc in procs)
{
hWnd = proc.MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
TraverseHierarchy (hWnd.ToInt32 (), 0, titleless);
}
}
foreach (int i in titleless)
{
System.Console.WriteLine (i);
}
return titleless;
}
public void TraverseHierarchy (int parent, int child, List<int> titleless)
{
String text = "";
GetWindowText (parent, text, GetWindowTextLength (parent));
if (String.IsNullOrEmpty (text))
{
titleless.Add (parent);
}
TraverseChildern (parent, titleless);
TraversePeers (parent, child, titleless);
}
public void TraverseChildern(int handle, List<int> titleless)
{
// First traverse child windows
const uint GW_CHILD = 0x05;
int child = GetWindow (handle, GW_CHILD);
if (0 != child)
{
TraverseHierarchy (child, 0, titleless);
}
}
public void TraversePeers(int parent, int start, List<int> titleless)
{
// Next traverse peers
int peer = FindWindowEx(parent, start, "");
if (0 != peer)
{
TraverseHierarchy (parent, peer, titleless);
}
}
}
Otros consejos
Tome un vistazo a la función EnumChildWindows.
Creo que si se pasa en el puntero de la ventana principal (es decir, de escritorio) para esta función, usted será capaz de obtener una lista de todas las ventanas y sus ventanas hijas.
En combinación con FindWindow debería ser posible para obtener el identificador de la ventana que desea una vez que encuentre un control secundario esperado.
Algo como esto debería funcionar, no ensayado
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);
....
Process[] procs = Process.GetProcesses();
IntPtr hWnd;
foreach(Process proc in procs)
{
hWnd = proc.MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
int length = GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, length);
if (String.IsNullOrEmpty(sb.ToString())
{
// we have a window with no title!
}
}
}
http://msdn.microsoft.com/ en-us / library / ms633558 (VS.85) .aspx
WindowFromPoint devuelve un identificador, o null si no hay ninguna ventana debajo del cursor. Podría esto ser utilizado, o está tratando de automatizar el proceso?
Aquí se puede encontrar una biblioteca para hacer frente a las cosas de API de Windows en código administrado.
Descargar el archivo DLL y hacer referencia a él en su proyecto y de ahí en adelante es muy fácil
obtener cualquier información sobre cualquier ventana que desea;
void ForAllSystemWindows()
{
foreach (SystemWindow window in SystemWindow.AllToplevelWindows)
{
if (window.Title == string.Empty)
{
//Found window without title
//Get window handle
IntPtr windowhandle = window.HWnd;
//Do other stuff ..
}
}
}