获取应用程序的窗口句柄

18

我正在开发一个应用程序,该应用程序接受另一个应用程序的主窗口句柄,并收集有关该窗口状态的信息。我可以轻松地收集有关子窗口的信息,但我无法访问应用程序的其他打开窗口甚至菜单。是否有办法获取应用程序的所有窗口句柄?


请查看这个可行的解决方案:https://dev59.com/vnM_5IYBdhLWcg3wdzDz#28055461 - Caffé
3个回答

17
你可以像 Process.MainWindowHandle 所做的一样:使用 P/Invoke 调用 EnumWindows 函数,该函数调用系统中每个顶级窗口的回调方法。
在你的回调中,调用 GetWindowThreadProcessId,并将窗口的进程 id 与 Process.Id 进行比较;如果进程 id 匹配,则将该窗口句柄添加到列表中。

11

首先,您需要获取应用程序主窗口的窗口句柄。

 [DllImport("user32.dll", SetLastError = true)]
 static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 IntPtr hWnd = (IntPtr)FindWindow(windowName, null);

然后,您可以使用此句柄获取所有子窗口:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

private List<IntPtr> GetChildWindows(IntPtr parent)  
{  
    List<IntPtr> result = new List<IntPtr>();  
    GCHandle listHandle = GCHandle.Alloc(result);  
    try  
    {  
         EnumWindowProc childProc = new EnumWindowProc(EnumWindow);  
         EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));  
    }  
    finally  
    {  
         if (listHandle.IsAllocated)  
               listHandle.Free();  
    }  
    return result;  
}   

1
Mez,问题不在于获取子窗口,我可以轻松做到这一点,但我无法访问除主窗口及其子窗口之外的其他窗口... - user361526
1
这适用于任何窗口,包括不属于自己应用程序的窗口。如果我误解了您的问题,请原谅。 - Mez
1
EnumWindowProc 是从哪里来的? - Matthieu Charbonnier
1
在其中添加声明:private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - luka
2
EnumWindowProc childProc = new EnumWindowProc(EnumWindow); 这会导致一个错误。 - luka

2
    public void GetWindowHandles()
    {
        List<IntPtr> windowHandles = new List<IntPtr>();

        foreach (Process window in Process.GetProcesses())
        {
            window.Refresh();

            if (window.MainWindowHandle != IntPtr.Zero) 
            {
                windowHandles.Add(window.MainWindowHandle);
            }
        }
    }

阅读这篇文章,了解为什么要调用refresh方法并检查指针是否为零。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接