4

I have an ActiveX control generated by the FireBreath framework (http://firebreath.org). I need to get a reference to the <object> tag in the page that hosts the plugin from C++.

If I were using NPAPI, I would use the NPNVPluginElementNPObject constant with NPN_GetValue.

so to make sure I am being clear, say I have the following in the page:

<object id="testPlugin" type="application/x-someplugin" width="100%" height="100%"></object>

I want to get a reference to the plugin like I would if I used document.getElementById("testPlugin"), except from within the C++ code of the activex control that is inserted for that mimetype.

Please note that passing the id in as a <param> is not a good option for me, but if there is a way to get the ID from inside the activex control that may work.

edit: I am considering using getElementsByTagName and trying to find it through the DOM, but it would be difficult to tell the difference between two instances of the same plugin.


Thanks to FireBreath contributor jtojanen from Finland, we finally have a solution.

The first thing is that the COM object must be registered as "Apartment", not "Single" (in the registry). Otherwise, this will not work; seems to be a bug in COM.

Then anywhere after SetClientSite is called, you can do the following:

CComQIPtr<IOleControlSite> site(m_spClientSite);
CComPtr<IDispatch> dispatch;
site->GetExtendedControl(&dispatch);
CComQIPtr<IHTMLElement2> htmlElement = dispatch;

Hope this saves someone some time; it's taken me almost 2 years to find someone who could answer this for me.

The object in htmlElement will be the <object> tag that wraps your plugin; so if you queryInterface for any of your interfaces, it should succeed, but it may not actually literally be your object, it will likely be a wrapper to your object.

4

2 回答 2

2

感谢来自芬兰的 FireBreath 贡献者 jtojanen,我们终于有了一个解决方案。

首先,COM 对象必须注册为“Apartment”,而不是“Single”(在注册表中)。否则,这将不起作用;似乎是COM中的一个错误。

然后在调用 SetClientSite 之后的任何地方,您都可以执行以下操作:

CComQIPtr<IOleControlSite> site(m_spClientSite);
CComPtr<IDispatch> dispatch;
site->GetExtendedControl(&dispatch);
CComQIPtr<IHTMLElement2> htmlElement = dispatch;

希望这可以节省一些时间;我花了将近 2 年的时间才找到可以为我回答这个问题的人。

htmlElement 中的对象将是包装插件的 <object> 标记;因此,如果您为任何接口查询接口,它应该会成功,但它实际上可能不是您的对象,它可能是您对象的包装器。

于 2011-01-11T20:52:00.717 回答
0

In C#:

    public int SetSite(object site)
    {
        if (site != null)
        {
            var oleControl = (IOleControlSite)site;
            object oHtmlElement;
            oleControl.GetExtendedControl(out oHtmlElement);
            var htmlElement = (IHTMLElement2)oHtmlElement;
            ...
        }
    }
于 2014-10-02T12:36:00.060 回答