EnumChildWindows从不调用它的回调

时间:2014-09-19 23:53:12

标签: c++ winapi

我正在尝试操作特定的Internet Explorer 11窗口。使用WinSpy ++我发现

  1. 顶级窗口的类是一个IEFrame,文档标题为文本(由GetWindowText返回)
  2. 实际的Web视图类称为“Internet Explorer_Server”,是前者的子级。
  3. 我写了一个简单的测试用例,用于以三种不同的方式查找在“https://encrypted.google.com/”上打开的IE11的Web视图:

    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失败(通过不调用回调全部!)。为什么呢?

1 个答案:

答案 0 :(得分:0)

问题在于,当我查找窗口标题时,我假设只有一个窗口具有该标题。但Internet Explorer会执行一些恶作剧并创建多个具有相同标题的窗口,但只有其中一个具有IEFrame类。

恰好发现第一个窗口是错误的,它没有任何孩子(因此EnumChildWindows没有任何东西可以迭代)。只需添加标题+类的额外检查即可。

然而,正如@wakjah所说,最好将IE(或任何其他浏览器)直接集成到您的代码中。通过谷歌我发现了很多关于如何使用IE和Chrome进行此操作的文档。