after 1 month online hunting I not found solution for my problem. now i feel like its time to post this post for any assistance.
My project: it find the external running softwares in taskbar and get the location, name, processid and title of the window and save it in datagrid. I am using c# in winform with windows 7
Problem: my code can find the running softwares process(processID) and can get the size of and other detail. but issue is my code not able to find a sub/child window's size or any other detail.
Sample info: i attached sample images and code which is working find without any error. but not capturing the other programs running child windows.
In the images you can see Webex software can find the child window and attached a popup box over it (its just for an example that its possible to find child window)
in my second image you can see my code only find the main window of skype(lync)
any suggestion or direction will be a great help, thank you
Import dll
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);
public struct Rect
{
public int Left { get; set; }
public int Top { get; set; }
public int Right { get; set; }
public int Bottom { get; set; }
}
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
Run code to find window and size on press of button and do some calculation for w and h.
Process[] processes = Process.GetProcesses();
foreach (Process p in processes)
{
if ((int)p.MainWindowHandle != 0)
{
if (!String.IsNullOrEmpty(p.MainWindowTitle))
{
myCurrentProcessName = p.ProcessName;
//listBox1.Items.Add(p.MainWindowTitle); // add all process to listbox
//find windows size and location
IntPtr ptr = p.MainWindowHandle;
Rect appRect = new Rect();
GetWindowRect(ptr, ref appRect);
x = appRect.Left;
y = appRect.Top;
r = appRect.Right;
b = appRect.Bottom;
//
//calculate size of the app
w = r - x;
h = b - y;
dataGridView1.Rows.Add(p.Id, p.MainWindowHandle, p.ProcessName, p.MainWindowTitle, IsIconic(wHnd), appState, x, y, w, h);
}
}
}
update: as per Abye's advised. I tried to google EnumChildWindows. i found a code from this link How can I get the child windows of a window given its HWND? I tried to implement it in my code but dnt know how to consume it and get the child window location and size.
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 Form1(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;
}
private void button5_Click(object sender, EventArgs e)
{
Process[] anotherApps = Process.GetProcessesByName(textBox1.Text);
if (anotherApps.Length == 0) return;
if (anotherApps[0] != null)
{
var allChildWindows = new Form1(anotherApps[0].MainWindowHandle).GetAllChildHandles();
}
}
This is the returning value from GetAllChildHandles() code, but how to consume it to get child window location and size?