前言
很多網友問到,在Html的頁面中放置一個COM對象,這個對象該如何調用頁面中的腳本函數的問題,本人近日也因為工作需要實現這樣的功能,在網上搜索後,獲得了很多幫助,但並沒有發現完整的實現。本文描述了實現過程中的幾個要點,同時提供一個示例工程的下載。
1——
給接口添加一個方法:
方法名:SetClIEntSite
參數:IOleClientSite* pClIEntSite
2——
給上面的方法加以實現(在相應的類中實現,已經自動生成了框架):
STDMETHODIMP CIrDav::SetClientSite(IOleClientSite * pClIEntSite)
{
// TODO: 在此添加實現代碼
HRESULT hr = S_OK;
IServiceProvider *isp, *isp2 = NULL;
if (!pClIEntSite)
{
COMRELEASE(m_spBrowser);
}
else
{
try
{
hr = pClIEntSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **> (&isp));
if (FAILED(hr))
throw("");
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
if (FAILED(hr))
throw("");
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&m_spBrowser));
if (FAILED(hr))
throw("");
hr=this->m_spBrowser->get_Document((IDispatch**)&m_spDoc);
if(FAILED(hr))
throw("");
}
catch(LPCTSTR lpszErr)
{
if(CString(lpszErr)!="")
MessageBox(lpszErr);
hr=S_OK;
}
catch(...)
{
MessageBox("未知錯誤");
hr=S_OK;
}
COMRELEASE(isp);
COMRELEASE(isp2);
}
return hr;
}
通過這步的操作,我們就獲得了控件所在Web頁面的BROWSER對象指針和相應的DOCUMENT對象指針。
通過這些BROWSER和DOCUMENT對象指針,我們可以設置窗口的很多屬性,比如菜單、全屏、工具欄等的顯示和DOCUMENT的背景顏色等等。
這個方法參見MSDN:http://support.microsoft.com/support/kb/articles/Q257/7/17.ASP
3——
獲得腳本,通過m_spDoc(DOCUMENT對象)的方法get_Script可以獲得頁面中的腳本對象:
CComPtr<IDispatch> pScript;
hr=this->m_spDoc->get_Script(&pScript);
4——
檢索函數,使用上面腳本對象的GetIDsOfNames可以獲取頁面之中指定名的腳本函數的指針:
CComBSTR bstrMember("calert");
DISPID dispid;
hr=pScript->GetIDsOfNames (IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);
5——
調用腳本對象的Invoke方法執行腳本函數:
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = 2;
dispparams.rgvarg = new VARIANT[dispparams.cArgs];
for( int i = 0; i < 2; i++)
{
CComBSTR bstr = "111"; // back reading
bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
dispparams.rgvarg[i].vt = VT_BSTR;
}
dispparams.cNamedArgs = 0;
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);
CComVariant vaResult;
UINT nArgErr = (UINT)-1; // initialize to invalid arg
hr = pScript->Invoke (dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
這裡的執行中我隨意的寫了幾個參數,可以根據自己需要修改。
本示例的觸發:打開相應的HTM頁面,點擊發送按鈕,按鈕調用腳本函數btn,btn調用了COM中的函數KeyPress函數,在KeyPress函數中獲取calert函數並調用。
注:一個問題:
獲得BROWSER對象是在SetClientSite函數中實現,這個函數我了解不多,我想應該是系統自動運行的函數之一,但當我使用這個函數後,原先我在COM中定義的事件(比如CLICK事件)不能響應。有高手介紹說放置在別的地方,我想應該是可以的,比如找一個COM就緒的函數進行處理,但不知IOleClientSite*pClIEntSite又該如何獲得。
本工程是用.Net2003弄的,可能你們系統不支持,不過沒有關系,重要建立自己的COM工程後,把IrDav的相關文件包含添加到工程就可以了。
對不起,由於本人沒有非常穩定空間,不能提供下載,如果有需要,請給本人QQ(68558710)或MSN([email protected])或EMail([email protected])聯系。如果您有空間,請告知,以便上傳後提供連接。