Ottenere maniglia di una finestra che non ha alcun titolo .. (C #)
Domanda
Come possiamo ottenere l'handle di una finestra che non dispone di un titolo? C'è un modo per enumerare tutte le finestre sul desktop e filtrare la finestra che non hanno un titolo (nel mio caso, v'è una sola) e ottenere il manico di esso .. oppure specificando altri attributi come una finestra che ha un pulsante specifico o casella di riepilogo ecc ...
Soluzione
Questo dovrebbe farlo:
...
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);
}
}
}
Altri suggerimenti
Date un'occhiata alla funzione EnumChildWindows.
Credo che se si passa il puntatore della finestra principale (cioè desktop) a questa funzione, si sarà in grado di ottenere un elenco di tutte le finestre e le loro finestre figlio.
In combinazione con FindWindow dovrebbe essere possibile per ottenere l'handle della finestra che si desidera Una volta individuato un controllo figlio atteso.
Qualcosa del genere dovrebbe funzionare, non testato
[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/ it-it / library / ms633558 (VS.85) aspx
WindowFromPoint restituisce un handle, o null se nessuna finestra si trova sotto il cursore. Questo potrebbe essere utilizzato, o stai cercando di automatizzare il processo?
Qui è possibile trovare una libreria a che fare con roba finestre API nel codice gestito.
Scarica il dll e farvi riferimento nel progetto e da lì è molto facile
ottenere tutte le informazioni su ogni finestra che si desidera;
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 ..
}
}
}