【问题标题】:TWebBrowser QueryInterface IID_IHTMLElement2 always returns E_NOINTERFACETWebBrowser QueryInterface IID_IHTMLElement2 总是返回 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 感谢您的回复 - 它有帮助。我现在已经在答案中找到了自己的解决方案。

标签: interface c++builder twebbrowser mshtml


【解决方案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 谢谢,我已经添加了简化版。
猜你喜欢
  • 2021-08-22
  • 2012-01-04
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 2021-03-15
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多