gpt4 book ai didi

c++ - 如何自动化弹出模态 HTML 对话框的 IE webapp?

转载 作者:可可西里 更新时间:2023-11-01 15:24:56 28 4
gpt4 key购买 nike

[再次修订为了清晰起见]

我有一个与网站交互的 C++ 程序。该站点是特定于 IE 的,我的程序也是。

我正在以普通方式连接到 IE 的运行实例(进程外 -- 请参阅代码)。一旦获得 IWebBrowser2,我就可以轻松获得 IHTMLDocument2 并与各个 IHTMLElement 对象进行交互,填写字段并单击按钮。

但是如果网页有调用window.showModalDialog的javascript ,我卡住了:我需要与弹出窗口中的 HTML 元素进行交互,就像其他页面一样;但我似乎无法获取它的 IWebBrowser2

弹出窗口始终标题为“网页对话框”,并且是一个类型为 Internet Explorer_TridentDlgFrame 的窗口,其中包含一个 Internet Explorer_Server。但是我无法从 Internet Explorer_Server 窗口获取 IWebBrowser2,就像它是普通 IE 实例时那样。

我可以获得 IHTMLDocument2Ptr,但是当我尝试获取 IWebBrowser2 时,我得到了 E_NOINTERFACEHRESULT >.

代码是非常标准的东西,如果它是“正常”的 IE 窗口则可以正常工作

IHTMLDocument2Ptr pDoc;
LRESULT lRes;

/* hWndChild is an instance of class "Internet Explorer_Server" */

UINT nMsg = ::RegisterWindowMessage( "WM_HTML_GETOBJECT" );
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000,
(DWORD*)&lRes );

LPFNOBJECTFROMLRESULT pfObjectFromLresult =
(LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, "ObjectFromLresult" );
if ( pfObjectFromLresult != NULL )
{
HRESULT hr;
hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&pDoc );
if ( SUCCEEDED(hr) ) {
IServiceProvider *pService;
hr = pDoc->QueryInterface(IID_IServiceProvider, (void **) &pService);
if ( SUCCEEDED(hr) )
{
hr = pService->QueryService(SID_SWebBrowserApp,
IID_IWebBrowser2, (void **) &pBrowser);

// This is where the problem occurs:
// hr == E_NOINTERFACE
}
}
}

以防万一,这是 VistaIE8。 (我强调这一点是因为这两个都在我的代码库中引入了重大更改,它在 XP/IE7 上运行良好。)

再一次,我的目标是获取每个 IHTMLElement 并与之交互。我无权访问我正在自动化的应用程序的源代码。

我正在考虑盲目地将击键发送到 Internet Explorer_Server 窗口,但我宁愿不这样做。

编辑添加:

有人建议获取子窗口并向它们发送消息,但我很确定这不适用于 Internet Explorer_Server;根据 Spy++,没有任何子窗口。 (这不是特定于 IE 的。Java 小程序似乎也没有子窗口。)

更新

在评论中,Simon Maurer 说上面的代码对他有用,为了确保没有拼写错误,他非常慷慨地在 pastebin 上发布了一个完整的独立应用程序。 .当我使用他的代码时,它在同一个地方以同样的方式失败了,我意识到他以为我想连接到底层页面,而不是弹出窗口。所以我编辑了上面的文本以消除歧义。

最佳答案

如果您只想要 IHTMLElement,我不知道为什么要获取 IServiceProviderIWebBrowser2。您可以通过调用 IHTMLDocumentget_all() 方法来获取它们。

此代码片段向您展示了它是如何工作的:

#include <Windows.h>
#include <mshtml.h>
#include <Exdisp.h>
#include <atlbase.h>
#include <SHLGUID.h>
#include <oleacc.h>
#include <comdef.h>
#include <tchar.h>

HRESULT EnumElements(HINSTANCE hOleAccInst, HWND child)
{
HRESULT hr;

UINT nMsg = ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
LRESULT lRes = 0;
::SendMessageTimeout(child, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (PDWORD)&lRes);

LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress(hOleAccInst, "ObjectFromLresult");
if (pfObjectFromLresult == NULL)
return S_FALSE;

CComPtr<IHTMLDocument2> spDoc;
hr = (*pfObjectFromLresult)(lRes, IID_IHTMLDocument2, 0, (void**)&spDoc);
if (FAILED(hr)) return hr;

CComPtr<IHTMLElementCollection> spElementCollection;
hr = spDoc->get_all(&spElementCollection);
if (FAILED(hr)) return hr;

CComBSTR url;
spDoc->get_URL(&url);
printf("URL: %ws\n", url);

long lElementCount;
hr = spElementCollection->get_length(&lElementCount);
if (FAILED(hr)) return hr;
printf("Number of elements: %d", lElementCount);

VARIANT vIndex; vIndex.vt = VT_I4;
VARIANT vSubIndex; vSubIndex.vt = VT_I4; vSubIndex.lVal = 0;
for (vIndex.lVal = 0; vIndex.lVal < lElementCount; vIndex.lVal++)
{
CComPtr<IDispatch> spDispatchElement;
if (FAILED(spElementCollection->item(vIndex, vSubIndex, &spDispatchElement)))
continue;
CComPtr<IHTMLElement> spElement;
if (FAILED(spDispatchElement->QueryInterface(IID_IHTMLElement, (void**)&spElement)))
continue;
CComBSTR tagName;
if (SUCCEEDED(spElement->get_tagName(&tagName)))
{
printf("%ws\n", tagName);
}
}
return S_OK;
}

int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
HINSTANCE hInst = ::LoadLibrary(_T("OLEACC.DLL"));
if (hInst != NULL)
{
HRESULT hr = EnumElements(hInst, (HWND)0x000F05E4); // Handle to Internet Explorer_Server determined with Spy++ :)
::FreeLibrary(hInst);
}
::CoUninitialize();
return 0;
}

以上代码适用于两种情况:普通窗口或模态窗口,只需将正确的 HWND 传递给 SendMessageTimeout 函数即可。

警告 我在这个例子中使用了一个硬编码的HWND值,如果你想测试它你应该启动一个IE实例并获取HWND 使用 Spy++ 的 Internet Explorer_Server 窗口。

我还建议您使用 CComPtr以避免内存泄漏。

关于c++ - 如何自动化弹出模态 HTML 对话框的 IE webapp?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16056416/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com