EnumChildWindows找不到所有子窗口 [英] EnumChildWindows doesn't find all child windows
问题描述
我正在使用Interop Services,尝试在我的应用程序中运行的进程中查找所有子窗口。正在运行的应用程序是IE。它找到前两个( BrowserFrameGripperClass
和客户端标题
),然后退出。
相关代码:
public static class WinAPI
{
public delegate bool WindowEnumProc( IntPtr hwnd, IntPtr lparam);
[DllImport( user32.dll)]
[ return :MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows( IntPtr hwnd,WindowEnumProc回调, IntPtr lParam);
}
class public MyClass
{
public IntPtr HWnd { get ; set ; }
public List< IntPtr>儿童{获取; set ; }
public MyClass( IntPtr hwnd)
{
}
public void RefreshChildren()
{
if ( this .Children == null )
{
this .Children = new 列表< WindowHandle> ();
}
else
{
this .Children 。明确();
}
if ( this .HWnd!= IntPtr .Zero)
{
List< IntPtr> childHandles = new List< IntPtr>();
GCHandle gch = GCHandle.Alloc(childHandles);
尝试
{
WinAPI.WindowEnumProc childProc = 新 WinAPI。 WindowEnumProc(EnumerateChildWindow);
WinAPI.EnumChildWindows( this .HWnd,childProc,GCHandle.ToIntPtr(gch));
List< IntPtr> list = gch.Target as List< IntPtr> ;;
foreach ( IntPtr 子 list)
{
Children.Add( new WindowHandle(child));
}
}
最后
{
if (gch.IsAllocated)
{
gch.Free();
}
}
}
}
public bool EnumerateChildWindow( IntPtr hwnd, IntPtr lParam)
{
bool result = true ;
GCHandle gch = GCHandle.FromIntPtr(lParam);
List< IntPtr> list = gch.Target as List< IntPtr> ;;
result =(list.Count == 0 );
if (list!= null )
{
list。加入(HWND);
}
返回结果;
}
}
嗨约翰,
只是一个快速的消息 - 没有解决方案我担心...只是想告诉你我发现了什么(或不是)...
EnumerateChildWindow的文档说明:
通过将句柄依次传递给每个子窗口来枚举属于指定父窗口的子窗口应用程序定义的回调函数。 EnumChildWindows继续,直到最后一个子窗口被枚举或回调函数返回FALSE
我怀疑一个(!)错误是在条件中。
result =(list.Count == 0 )
如果我尝试没有这个条件的代码来枚举VisualStudio的子窗口我得到~10但你的条件只有2 ...在iexplore上它在我的系统上根本不起作用 - 回调似乎永远不会被称为...... ???对不起,我没有时间找出我系统上可能出现的问题。 (我还测试了)中的原始代码[ ^ ] - 结果相同 - 找不到iexplore的任何子窗口...
无论如何,我无法发现你的代码中的任何错误(除了上述情况,我认为只是一个额外的错误)。
亲切的问候
Johannes
我改变了逻辑在
public bool EnumerateChildWindow(< span class =code-sdkkeyword> IntPtr hwnd, IntPtr lParam)
{
bool result = false ;
GCHandle gch = GCHandle.FromIntPtr(lParam);
List< IntPtr> list = gch.Target as List< IntPtr> ;;
if (list!= null )
{
list。加入(HWND);
result = true ; // 只要找到孩子就返回
}
返回结果;
}
结果是孩子的列表,一些有名字,有些没有。
1 -
2 - 导航栏
3 -
4 -
5 -
6 -
7 -
8 -
9 - 地址组合控制
10 - 页面控制
11 -
12 -
13 - SeConnect
14 -
15 - 搜索组合控制
16 - 搜索控制
17 -
18 -
19 -
20 - 命令栏
21 -
22 -
23 -
24 - 收藏夹命令栏
25 - LinksBand
26 - 收藏夹栏
27 - 加入收藏夹栏
28 -
29 - ITBarHost
30 - 菜单栏
31 -
32 -
33 - Bing - Windows Internet Explorer提供者...
34 -
35 -
36 - 缩放等级
37 -
38 -
39 -
我从控制台应用程序运行代码并通过GetWindow
获取IE8窗口的句柄。
不确定这是否有任何意义。
I'm using Interop Services, trying to find all child windows in a process that I run from within my app. The app being run is IE. It finds the first two (BrowserFrameGripperClass
and Client Caption
) and then simply quits.
Relevant code:
public static class WinAPI
{
public delegate bool WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc callback, IntPtr lParam);
}
class public MyClass
{
public IntPtr HWnd { get; set; }
public List<IntPtr> Children { get; set; }
public MyClass(IntPtr hwnd)
{
}
public void RefreshChildren()
{
if (this.Children == null)
{
this.Children = new List<WindowHandle>();
}
else
{
this.Children.Clear();
}
if (this.HWnd != IntPtr.Zero)
{
List<IntPtr> childHandles = new List<IntPtr>();
GCHandle gch = GCHandle.Alloc(childHandles);
try
{
WinAPI.WindowEnumProc childProc = new WinAPI.WindowEnumProc(EnumerateChildWindow);
WinAPI.EnumChildWindows(this.HWnd, childProc, GCHandle.ToIntPtr(gch));
List<IntPtr> list = gch.Target as List<IntPtr>;
foreach (IntPtr child in list)
{
Children.Add(new WindowHandle(child));
}
}
finally
{
if (gch.IsAllocated)
{
gch.Free();
}
}
}
}
public bool EnumerateChildWindow(IntPtr hwnd, IntPtr lParam)
{
bool result = true;
GCHandle gch = GCHandle.FromIntPtr(lParam);
List<IntPtr> list = gch.Target as List<IntPtr>;
result = (list.Count == 0);
if (list != null)
{
list.Add(hwnd);
}
return result;
}
}
Hi John,
Just a quick message - no solution I fear... Just want to tell you what I found out (or not)...
The documentation for EnumerateChildWindow states:
Enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE
I suspect one (!) error is in the condition.
result = (list.Count == 0)
If I try your code without this condition to enumerate VisualStudio's child windows I get ~10 but with your condition only 2... On iexplore it doesn't work at all on my system - the callback seems to be never called... ??? Sorry I didn't find the time to find out what may be the problem on my system. (I also tested with the original code found at )[^] - same results - not any childwindow for iexplore is found...
Anyway I can't spot any mistake in your code (except the above condition which is I think just an "additional" error).
Kind regards
Johannes
I changed the logic in
public bool EnumerateChildWindow(IntPtr hwnd, IntPtr lParam) { bool result = false ; GCHandle gch = GCHandle.FromIntPtr(lParam); List<IntPtr> list = gch.Target as List<IntPtr>; if (list != null) { list.Add(hwnd); result = true; // return true as long as children are found } return result; }
The result is list of children, some with names and some without.
1 - 2 - Navigation Bar 3 - 4 - 5 - 6 - 7 - 8 - 9 - Address Combo Control 10 - Page Control 11 - 12 - 13 - SeConnect 14 - 15 - Search Combo Control 16 - Search Control 17 - 18 - 19 - 20 - Command Bar 21 - 22 - 23 - 24 - Favorites Command Bar 25 - LinksBand 26 - Favorites Bar 27 - Add to Favorites Bar 28 - 29 - ITBarHost 30 - Menu Bar 31 - 32 - 33 - Bing - Windows Internet Explorer provided by ... 34 - 35 - 36 - Zoom Level 37 - 38 - 39 -
I run the code from a console application and get the handle to the IE8 window viaGetWindow
.
Not sure if that has any significance.
这篇关于EnumChildWindows找不到所有子窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!