TWebBrowser QueryInterface IID_IHTMLElement2 总是返回 E_NOINTERFACE

Posted

技术标签:

【中文标题】TWebBrowser QueryInterface IID_IHTMLElement2 总是返回 E_NOINTERFACE【英文标题】:TWebBrowser QueryInterface IID_IHTMLElement2 always returns E_NOINTERFACE 【发布时间】:2021-08-17 03:13:02 【问题描述】:

我正在做一个简单的QueryInterface() 来获取IhtmlElement2 接口,但它总是以E_NOINTERFACE 失败。

更新:我需要获取body 元素的IHTMLElement2 接口,因为它有一个focus() 方法,因此我可以将焦点设置到正文。用IHTMLElement接口是做不到的。

任何想法为什么会出现此错误(或如何联系body->focus())?

WebBrowser1->Navigate(L"c:\\test.htm");
while (WebBrowser1->Busy) Application->ProcessMessages();

DelphiInterface<IHTMLDocument2> diDoc = WebBrowser1->Document;
if (diDoc) 
    DelphiInterface<IHTMLElement2> diBodyElement;

    // all good until this point
    if (SUCCEEDED(diDoc->QueryInterface(IID_IHTMLElement2, reinterpret_cast<void**>(&diBodyElement))) && diBodyElement) 
        // Never reaches this part - always E_NOINTERFACE when querying for IID_IHTMLElement2
        diBodyElement->focus();
        
    

【问题讨论】:

您正在尝试在Document 本身中查询IHTMLElement2,但文档不是元素,它是元素的容器。您要准确访问哪个元素?通常,Document 应该首先查询IHTMLDocument2(你正在做的)或更高,然后从那里开始,例如搜索IHTMLDocument2.all,或使用IHTMLDocument3.getElementById() 等。或者,如果你想要&lt;html&gt; 元素本身,那么你真的在寻找 IHTMLDocument3.documentElement 而不是 @RemyLebeau 感谢您的回复 - 它有帮助。我现在已经在答案中找到了自己的解决方案。 【参考方案1】:

我已经找到了自己的解决方案,如何联系body-&gt;focus() 如下:

DelphiInterface <IHTMLDocument2> diDoc2 = WebBrowser1->Document;

if (diDoc2) 
    DelphiInterface<IHTMLElement>     pBody1;
    DelphiInterface<IHTMLElement2>    pBody2;
    DelphiInterface<IHTMLBodyElement> pBodyElem;

    if (SUCCEEDED(diDoc2->get_body(&pBody1)) && pBody1) 
        if (SUCCEEDED(pBody1->QueryInterface(IID_IHTMLBodyElement, reinterpret_cast<void**>(&pBodyElem))) && pBodyElem) 
        if (SUCCEEDED(pBodyElem->QueryInterface(IID_IHTMLElement2, reinterpret_cast<void**>(&pBody2))) && pBody2) 
            pBody2->focus();
            
        
    

编辑(由 Reby Lebeau 建议) - 简化版:

DelphiInterface <IHTMLDocument2> diDoc2 = WebBrowser1->Document;

if (diDoc2) 
    DelphiInterface<IHTMLElement>  pBody1;
    DelphiInterface<IHTMLElement2> pBody2;

    if (SUCCEEDED(diDoc2->get_body(&pBody1)) && pBody1) 
        if (SUCCEEDED(pBody1->QueryInterface(IID_IHTMLElement2, reinterpret_cast<void**>(&pBody2))) && pBody2) 
            // focus to <body> element
            pBody2->focus();
            
        
    

【讨论】:

如果你已经有IHTMLElement,你可能不需要查询IHTMLBodyElement,直接去IHTMLElement2 @RemyLebeau 谢谢,我已经添加了简化版。

以上是关于TWebBrowser QueryInterface IID_IHTMLElement2 总是返回 E_NOINTERFACE的主要内容,如果未能解决你的问题,请参考以下文章

TWebBrowser 中的方向键切换控件

如何在 TWebBrowser 中居中和拉伸/收缩 SVG 显示?

如何从 TWebBrowser 获取图像到 TImage

在默认浏览器中打开 TWebBrowser 链接

检测可编辑 TWebBrowser 中的更改

TWebBrowser句柄关闭请求