Welcome

首页 / 软件开发 / VC.NET / COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)

COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)2010-05-29 博客园 Phinecos(洞庭散人)声明:本文代码基于CodeProject的文章《A Complete ActiveX Web Control Tutorial》修改而来,因此同样遵循Code Project Open License (CPOL)。

最近遇到两个需求:1)在ActiveX控件中使用工作线程来完成底层的硬件设备扫描任务,并在工作线程中根据操作结果回调外部web页面的JavaScript函数;2)能根据控件任务的不同自动调整控件大小。但在查阅了大量资料后,发现网上讨论ActiveX中多线程开发的文章基本没有,最后在csdn论坛里遇到一个高手帮忙后,摸索了几天才解决这两个问题,本文的目的就在于记录下我解决这两个问题的过程,也希望能帮助到以后有同样需求的朋友。

简单抽象下第一个任务的模型:在AcitveX控件中开启一个工作线程去执行特点任务后,然后根据工作线程的执行结果中去通知外部的web页面的JavaScript。在进入到多线程之前,先来介绍下ActiveX中调用外部web页面的JavaScript函数的两种方式。

ActiveX中调用JavaScript

第一种方式是使用事件,这是最简单方法。在“类视图”中,右键CMyActiveXCtrl ,选择“添加事件”,这种方式就不赘述了。

第二种方式是利用IWebBrowser2和IHTMLDocument2这两个COM组件来访问包含ActiveX控件的外部Web页面上的所有元素。具体实现步骤如下:

1, 在CMyActiveXCtrl类中加入两个变量:

public:
IWebBrowser2* pWebBrowser; //IE浏览器
IHTMLDocument2* pHTMLDocument; //包含此控件的web页面

2,重载OnSetClientSite函数。

void CMyActiveXCtrl::OnSetClientSite()
{
HRESULT hr = S_OK;
IServiceProvider *isp,*isp2 = NULL;
if (!m_pClientSite)
{
COMRELEASE(pWebBrowser);
}
else
{
hr = m_pClientSite->QueryInterface(IID_IServiceProvider,reinterpret_cast<void **>(&isp));
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
hr = isp->QueryService(SID_STopLevelBrowser,IID_IServiceProvider,reinterpret_cast<void **>(&isp2));
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
hr = isp2->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2,reinterpret_cast<void **>(&pWebBrowser)); //查询IE浏览器接口
if (FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
hr = pWebBrowser->get_Document((IDispatch**)&pHTMLDocument); //查询Web页面接口
if(FAILED(hr))
{
hr = S_OK;
goto cleanup;
}
cleanup:
// Free resources.
COMRELEASE(isp);
COMRELEASE(isp2);
}
}