ATL控件中如何取得Internet Explorer_Server对象? 我用ATL写了个ActiveX for IE,想在运行时得到Internet Explorer_Server对象,然后再在Internet Explorer_Server中动态创建其它控件,请问怎么才能在ATL Control中获取Internet Explorer_Server对象呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以从窗口句柄得到, 用CWnd::GetControlUnknown得到IUnknown对象. void CCPClient::DoAdvise(bool bAdvise){ HRESULT hr = S_FALSE; if(m_spSHWinds == 0) { // Create Instance ShellWindows if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) return; } IDispatchPtr spDisp; long nCount = m_spSHWinds->GetCount(); // Enum all Shell Windows and list them for (long i = 0; i < nCount; i++) { _variant_t va(i, VT_I4); spDisp = m_spSHWinds->Item(va); SHDocVw::IWebBrowser2Ptr spBrowser(spDisp); if (spBrowser != NULL) { // Get document's IDispatch LPDISPATCH lpDisp = NULL; spBrowser->get_Document(&lpDisp); if (lpDisp) { IOleContainer* pOleContainer; // get container HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer, (void**)&pOleContainer); lpDisp->Release(); if (FAILED(hr)) continue;// hr= m_spClientSite->GetContainer (&pOleContainer); // get the page browser object if (SUCCEEDED(hr)) { IEnumUnknown* pEnumUnknown = NULL; hr = pOleContainer->EnumObjects (OLECONTF_EMBEDDINGS|OLECONTF_OTHERS, &pEnumUnknown); pOleContainer->Release(); if (SUCCEEDED (hr)) { IUnknown* pUnk; HRESULT hr = E_FAIL; // retrieve all ActiveX objects on the page while (pEnumUnknown->Next (1, &pUnk, NULL) == S_OK) { IOleObject* pOleObject = NULL; hr = pUnk->QueryInterface (IID_IOleObject, (void**)&pOleObject); if (SUCCEEDED (hr)) { IOleClientSite* pClientSite = NULL; pOleObject->GetClientSite (&pClientSite); if (pClientSite) { // suppose there's more than one CPClient object IDispatch* pAmbientDispatch = NULL; pClientSite->QueryInterface (IID_IDispatch, (void**)&pAmbientDispatch); // get name of the found ActiveX object _bstr_t bstr; if (pAmbientDispatch) { bstr = GetExtendedName(pAmbientDispatch); pAmbientDispatch->Release(); } _bstr_t bstName ("CPServer"); if (bstName == bstr) { // get the IConnectionPointContainer interface pointer IConnectionPointContainer* pConnPtContainer = NULL; hr = pUnk->QueryInterface (IID_IConnectionPointContainer, (void**)&pConnPtContainer); _ASSERT (SUCCEEDED (hr) && pConnPtContainer != NULL); // get the IConnectionPoint interface pointer IConnectionPoint* pConnPt = NULL; hr = pConnPtContainer->FindConnectionPoint (DIID__ICPServerEvents, &pConnPt); _ASSERT (SUCCEEDED (hr) && pConnPt != NULL); // set/reset the CPClient's Unknown interface as the outgoing interface DWORD dwCookie = 0; if (bAdvise) { // get a Cookie hr = pConnPt->Advise (this->GetUnknown(), &dwCookie); // save a Cookie into Cookie collection m_vectorCookie.push_back(dwCookie); } else { // Unadvise all connection-point through Cookie collection for (vector<DWORD>::iterator iter = m_vectorCookie.begin(); iter != m_vectorCookie.end(); iter++) { dwCookie = (DWORD)*iter; hr = pConnPt->Unadvise (dwCookie); if (hr == CONNECT_E_NOCONNECTION) continue; else break; } } pConnPt->Release(); pConnPtContainer->Release(); } } pOleObject->Release(); } pUnk= NULL; } } } } } } m_spSHWinds.Release(); m_spSHWinds = 0; if (!bAdvise) { m_vectorCookie.erase(m_vectorCookie.begin(), m_vectorCookie.end()); }} 上面这段代码可以做参考。里面有去遍历获得当前打开的所有ie标签页的Internet Explorer_Server对象。 只要能得到ActiveX的IOleClientSite接口就行了,可以试试用下面的方法从unkonwn得到(没测试,不知道是否可行)。IOleObject *lpObject;lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&lpObject);IOleClientSite* pClientSite = NULL;pOleObject->GetClientSite (&pClientSite);得到这个接口后就简单了:IWebBrowser2 *browser = NULL;IServiceProvider *isp = NULL, *isp2 = NULL;pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));pClientSite->Release();isp->Release();isp2->Release(); 问题解决了,可能不算完美,但至少是个途径。假如说只获取Internet Explorer_Server的话,直接在ATL控件里面使用::GetParent(m_hWnd)即可得到,为了保险起见,可以做个循环来取parent,直到匹配到classname为Internet Explorer_Server的HWND即可。 Windows API 回调函数在com里怎么用 看看有没有BUG 关于ethereal 帮帮新手吧!改写VC的ActiveX控件! 消息处理函数里怎么不能操纵对话框? 请问字符串拷贝 不用系统函数用自定义函数 怎么实现? 在win2000中,如何停止使用一个设备,如移动磁盘。如何检测当前是否可以停止使用该设备,急。。。 关于NetMessageBufferSend 如何在一个小窗口里面实现很多功能? 请问如何做输入法,或者哪里可以找到相关的资料? 关于pDC->GetSafeHdc()释放的问题 学MFC一个月了
{
HRESULT hr = S_FALSE;
if(m_spSHWinds == 0) {
// Create Instance ShellWindows
if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK)
return;
}
IDispatchPtr spDisp;
long nCount = m_spSHWinds->GetCount();
// Enum all Shell Windows and list them
for (long i = 0; i < nCount; i++) {
_variant_t va(i, VT_I4);
spDisp = m_spSHWinds->Item(va);
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
if (spBrowser != NULL) {
// Get document's IDispatch
LPDISPATCH lpDisp = NULL;
spBrowser->get_Document(&lpDisp);
if (lpDisp) {
IOleContainer* pOleContainer;
// get container
HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer, (void**)&pOleContainer);
lpDisp->Release();
if (FAILED(hr))
continue;
// hr= m_spClientSite->GetContainer (&pOleContainer); // get the page browser object
if (SUCCEEDED(hr)) {
IEnumUnknown* pEnumUnknown = NULL;
hr = pOleContainer->EnumObjects (OLECONTF_EMBEDDINGS|OLECONTF_OTHERS, &pEnumUnknown);
pOleContainer->Release();
if (SUCCEEDED (hr)) {
IUnknown* pUnk;
HRESULT hr = E_FAIL;
// retrieve all ActiveX objects on the page
while (pEnumUnknown->Next (1, &pUnk, NULL) == S_OK) {
IOleObject* pOleObject = NULL;
hr = pUnk->QueryInterface (IID_IOleObject, (void**)&pOleObject); if (SUCCEEDED (hr)) {
IOleClientSite* pClientSite = NULL;
pOleObject->GetClientSite (&pClientSite);
if (pClientSite) { // suppose there's more than one CPClient object
IDispatch* pAmbientDispatch = NULL;
pClientSite->QueryInterface (IID_IDispatch, (void**)&pAmbientDispatch);
// get name of the found ActiveX object
_bstr_t bstr;
if (pAmbientDispatch) {
bstr = GetExtendedName(pAmbientDispatch);
pAmbientDispatch->Release();
}
_bstr_t bstName ("CPServer");
if (bstName == bstr) {
// get the IConnectionPointContainer interface pointer
IConnectionPointContainer* pConnPtContainer = NULL;
hr = pUnk->QueryInterface (IID_IConnectionPointContainer, (void**)&pConnPtContainer);
_ASSERT (SUCCEEDED (hr) && pConnPtContainer != NULL);
// get the IConnectionPoint interface pointer
IConnectionPoint* pConnPt = NULL;
hr = pConnPtContainer->FindConnectionPoint (DIID__ICPServerEvents, &pConnPt);
_ASSERT (SUCCEEDED (hr) && pConnPt != NULL);
// set/reset the CPClient's Unknown interface as the outgoing interface
DWORD dwCookie = 0;
if (bAdvise) {
// get a Cookie
hr = pConnPt->Advise (this->GetUnknown(), &dwCookie);
// save a Cookie into Cookie collection
m_vectorCookie.push_back(dwCookie);
} else {
// Unadvise all connection-point through Cookie collection
for (vector<DWORD>::iterator iter = m_vectorCookie.begin();
iter != m_vectorCookie.end(); iter++) {
dwCookie = (DWORD)*iter;
hr = pConnPt->Unadvise (dwCookie);
if (hr == CONNECT_E_NOCONNECTION) continue;
else break;
}
}
pConnPt->Release();
pConnPtContainer->Release();
}
}
pOleObject->Release();
}
pUnk= NULL;
}
}
}
}
}
}
m_spSHWinds.Release();
m_spSHWinds = 0;
if (!bAdvise) {
m_vectorCookie.erase(m_vectorCookie.begin(), m_vectorCookie.end());
}
}
只要能得到ActiveX的IOleClientSite接口就行了,可以试试用下面的方法从unkonwn得到(没测试,不知道是否可行)。IOleObject *lpObject;
lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&lpObject);
IOleClientSite* pClientSite = NULL;
pOleObject->GetClientSite (&pClientSite);
得到这个接口后就简单了:IWebBrowser2 *browser = NULL;
IServiceProvider *isp = NULL, *isp2 = NULL;pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));pClientSite->Release();
isp->Release();
isp2->Release();
假如说只获取Internet Explorer_Server的话,直接在ATL控件里面使用::GetParent(m_hWnd)即可得到,为了保险起见,可以做个循环来取parent,直到匹配到classname为Internet Explorer_Server的HWND即可。