1个月的网上狩猎后,我没有找到解决问题的方法。现在,我觉得该发布这个帖子了。
我的项目:它在任务栏中找到外部正在运行的软件,并获取窗口的位置,名称,进程ID和标题并将其保存在datagrid中。我在Windows 7的Winform中使用C#
问题:我的代码可以找到正在运行的软件的process(processID)并可以获取的大小和其他详细信息。但是问题是我的代码无法找到子/子窗口的大小或其他任何细节。
示例信息:我附上了有效的示例图像和代码,没有任何错误。但不捕获运行子窗口的其他程序。
在图像中,您可以看到Webex软件可以找到子窗口并在其上附加一个弹出框(仅作为示例,它可能找到子窗口)
在第二张图片中,您可以看到我的代码只能找到skype(lync)的主窗口
任何建议或方向都会有很大帮助,谢谢
导入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);
运行代码,按一下按钮即可找到窗口和尺寸,并对w和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);
}
}
}
更新:按照Abye的建议。我试图用谷歌EnumChildWindows。我从此链接How can I get the child windows of a window given its HWND?中找到了一个代码,我试图在我的代码中实现它,但是dnt知道如何使用它并获取子窗口的位置和大小。
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();
}
}
这是GetAllChildHandles()代码的返回值,但是如何使用它来获取子窗口的位置和大小?