I create a WinForms application that consist of two forms (MainForm and SecondForm). When the application is executed, there will be three forms on screen.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
var firstChildForm = new SecondForm();
firstChildForm.Text = "First child";
firstChildForm.Show();
firstChildForm.StartPosition = FormStartPosition.Manual;
var secondChildForm = new SecondForm();
secondChildForm.Text = "Second child";
secondChildForm.StartPosition = FormStartPosition.CenterScreen;
secondChildForm.Show();
}
}
How can I use a separate application that lists the titles of children forms for the main form ("ThreeForms")? I can only get the title and handle of the parent.
private void button1_Click(object sender, EventArgs e)
{
Process[] processes = System.Diagnostics.Process.GetProcessesByName("ThreeForms");
foreach (Process p in processes)
{
IntPtr parentHandle = p.MainWindowHandle; // this is found
listBox1.Items.Add("Parent Handle: " + parentHandle.ToString());
List<IntPtr> childrenHandles = GetChildWindows(parentHandle); // empty list
foreach(var ptr in childrenHandles)
{
listBox1.Items.Add(ptr.ToString());
}
}
}
public List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
Win32Callback childProc = new Win32Callback(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
// You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}