C++ EnumChildWindows从不调用其回调
我试图操纵一个特定的InternetExplorer11窗口。使用WinSpy++我发现C++ EnumChildWindows从不调用其回调,c++,winapi,C++,Winapi,我试图操纵一个特定的InternetExplorer11窗口。使用WinSpy++我发现 顶层窗口的类是一个IEFrame,文档标题为文本(由GetWindowText返回) 实际的web视图类称为“Internet Explorer_Server”,是前者的子类 我编写了一个简单的测试用例,用三种不同的方式查找在“”上打开的IE11的web视图: HWND FindIE_A() { // Use FindWindow, works! HWND hWndTop = ::FindW
HWND FindIE_A()
{
// Use FindWindow, works!
HWND hWndTop = ::FindWindowA( NULL, "Google - Internet Explorer" );
// Find the web view window, the callback (FindIEServer) is NEVER called!
HWND hWnd = NULL;
::EnumChildWindows( hWndTop, &FindIEServer, (LPARAM)&hWnd );
return hWnd;
}
HWND FindIE_B()
{
// Use EnumChildWindows with NULL as parent, works!
HWND hWndTop = NULL;
::EnumChildWindows( NULL, &FindIEMain, (LPARAM)&hWndTop );
// Find the web view window, the callback (FindIEServer) is NEVER called!
HWND hWnd = NULL;
::EnumChildWindows( hWndTop, &FindIEServer, (LPARAM)&hWnd );
return hWnd;
}
HWND FindIE_C()
{
// Simple EnumWindows, works!
HWND hWndTop = NULL;
::EnumWindows( &FindIEMain, (LPARAM)&hWndTop );
// Find the web view window, the callback (FindIEServer) is NEVER called!
HWND hWnd = NULL;
::EnumChildWindows( hWndTop, &FindIEServer, (LPARAM)&hWnd );
return hWnd;
}
回调非常简单;从窗口获取属性并与硬编码值进行比较:
BOOL CALLBACK FindIEServer( HWND hWnd, LPARAM lParam )
{
char className[64];
::GetClassNameA( hWnd, className, sizeof(className) );
if ( !strcmp( className, "Internet Explorer_Server" ) )
{
*(HWND*)lParam = hWnd;
return FALSE;
}
return TRUE;
}
BOOL CALLBACK FindIEMain( HWND hWnd, LPARAM lParam )
{
char text[128];
::GetWindowTextA( hWnd, text, sizeof(text) );
if ( !strcmp( text, "Google - Internet Explorer" ) )
{
*(HWND*)lParam = hWnd;
return FALSE;
}
return TRUE;
}
每次提供父窗口时,EnumChildWindows都失败(根本不调用回调!)。为什么?问题是,当我查找窗口标题时,我假设只有一个窗口具有该标题。然而,Internet Explorer做了一些恶作剧,创建了多个具有相同标题的窗口,但其中只有一个具有类IEFrame 碰巧找到的第一个窗口是错误的,它没有任何子窗口(因此EnumChildWindows没有任何可迭代的对象)。只是增加了一个额外的检查标题+类作品
然而,正如@wakjah所建议的,最好将IE(或任何其他浏览器)直接集成到您的代码中。通过谷歌,我找到了很多关于如何使用IE和Chrome实现这一点的文档。我不知道你的最终目标是什么,但你最好通过COM使用IE自动化。请看一个例子,也许Internet Explorer不希望您欺骗它的孩子。您是否试图在网页中获取控件,例如web表单中的控件?如果是这样,你应该知道。@wakjah我正试图在directx9游戏中嵌入浏览器。我能够捕捉窗口像素并将其流到纹理中并绘制它。我现在希望能够在游戏中控制它。谢谢你的链接,看起来很有趣,我会看看的!
internetexplorer\u服务器
窗口不是IEFrame
的直接子窗口,它嵌套了好几层。即使您让EnumChildWindows()
工作,它也不会找到internetexplorer\u服务器
,除非您多次调用它。在这种情况下,应该使用FindWindowEx()
而不是EnumChildWindows()
。