关于在WebBrowser2中自动点击链接的问题。

Ah 2007-01-15 03:08:34
void*
CTester::OpenLink(
long nIndex
)
{
IHTMLDocument2* pDoc = NULL;
IHTMLElement* pItem = NULL;
IHTMLElement* pBody = NULL;
IHTMLElementCollection* pEC = NULL;
IDispatch* pDisp = NULL;

pDoc = GetDocument();

if ( pDoc == NULL )
return NULL;

pDoc->get_body( &pBody );
pDoc->Release();

if ( pBody == NULL )
return NULL;

pBody->get_all( &pDisp );
pBody->Release();

if ( pDisp == NULL )
return NULL;

pDisp->QueryInterface( __uuidof( IHTMLElementCollection ), ( void** )&pEC );
pDisp->Release();

if ( pEC == NULL )
return NULL;

pEC->item( _variant_t( nIndex ), _variant_t( nIndex ), &pDisp );
pEC->Release();

if ( pDisp == NULL )
return NULL;

pDisp->QueryInterface( __uuidof( IHTMLElement ), ( void** ) &pItem );
pDisp->Release();

if ( pItem == NULL )
return NULL;

pItem->click(); /////////这句时发生异常
pItem->Release();

return NULL;
}
...全文
810 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ah 2007-01-19
  • 打赏
  • 举报
回复
To wwwllg(野蛮人):
你是怎么实现的?能说一下吗?
Ah 2007-01-18
  • 打赏
  • 举报
回复
怎么跨线程的?
UDX协议 2007-01-17
  • 打赏
  • 举报
回复
就是要实现跨线程调用
Ah 2007-01-17
  • 打赏
  • 举报
回复
楼上的能说说怎么解决的吗?
Ah 2007-01-16
  • 打赏
  • 举报
回复
To :jiangsheng(蒋晟.Net[MVP])

大侠,顺便再问一下,为什么在基于 CHtmlView 的,MDI 程序中,在 CMainFrame 中的 GetActiveView的返回值一直是 NULL ?
我现在没办法用的是 MDIGetActive()->GetActiveView();
Ah 2007-01-16
  • 打赏
  • 举报
回复
是的啊,不能从线程里调用吗?
蒋晟 2007-01-16
  • 打赏
  • 举报
回复
are you calling it from another thread?
Ah 2007-01-16
  • 打赏
  • 举报
回复
同样的代码,我在CDHtmlDialog里面试了一下,是正常的,但是(MDI)放到CHtmlView里就不正常了
Ah 2007-01-16
  • 打赏
  • 举报
回复
TO jiangsheng(蒋晟.Net[MVP]):

pDoc->get_body( &pBody );
pDoc->Release();
don't release the document until you finished the DOM operation.
use IID_IHTMLElemenet instead of uuid
==========================================================
我把所有的Release都注释掉了还是不行。


还是会在CHtmlView的 AsertValid 中断言失败,接着后面还有一系列的错误。

#ifdef _DEBUG
void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid

// check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd));

// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL); /////////////////在这里断言失败!///////////

CObject* p;
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
ASSERT((CWnd*)p == this); // must be us

}
}
UDX协议 2007-01-16
  • 打赏
  • 举报
回复
把你挣的钱分点我,赫赫。
UDX协议 2007-01-16
  • 打赏
  • 举报
回复
USES_CONVERSION ;
IHTMLElementCollection *pAnchors = NULL;
long ilHrefCount = 0;
if(SUCCEEDED(pElemColl->get_length(&ilHrefCount)))
{
long ilHrefIndex = 0;
for(ilHrefIndex = 0; ilHrefIndex < ilHrefCount; ilHrefIndex++)
{
_variant_t vIndex;
vIndex.vt = VT_I4;
vIndex.lVal = ilHrefIndex;

IDispatch *pItem = NULL;
pElemColl->item(vIndex, vIndex, &pItem);
if(pItem != NULL)
{
IHTMLAnchorElement *pAnchor = NULL;
if(SUCCEEDED(pItem->QueryInterface(IID_IHTMLAnchorElement,
(LPVOID*)&pAnchor)))
{

BSTR bURL;
if( SUCCEEDED(pAnchor->get_href(&bURL)))
{
string s = W2A(bURL);
if(s.find(url) != -1)
{
IHTMLElement * pElement = 0;
if(SUCCEEDED(pItem->QueryInterface(IID_IHTMLElement,
(LPVOID*)&pElement)))
{
pElement->click();
pElement->Release();
}
}
}


pAnchor->Release();
}
pItem->Release();
}
}
}
蒋晟 2007-01-16
  • 打赏
  • 举报
回复
pDoc->get_body( &pBody );
pDoc->Release();
don't release the document until you finished the DOM operation.
use IID_IHTMLElemenet instead of uuid
UDX协议 2007-01-16
  • 打赏
  • 举报
回复
我和你做一样的事情,不过我已经解决了。
跨线程调用是有这个问题。
Ah 2007-01-16
  • 打赏
  • 举报
回复
CoInitialize( NULL );
CoGetInterfaceAndReleaseStream(
pParam->pStream,
__uuidof( IWebBrowser2 ),
( void** ) &pWB2
);

pWB2->get_Document( &pDisp ); //在这句死掉了,程序没没反应了
Ah 2007-01-16
  • 打赏
  • 举报
回复
在线程内部加上了CoInitialize和CoUninitialize,但是现在死掉了,什么也不动
Ah 2007-01-16
  • 打赏
  • 举报
回复
我在线程启动前
CoMarshalInterThreadInterfaceInStream(
__uuidof( IWebBrowser2 ),
pWB2,
&pStream
);
线程内部
CoGetInterfaceAndReleaseStream(
pParam->pStream,
__uuidof( IWebBrowser2 ),
( void** ) &pWB2
);

在线程内部 pWB2 始终为 0
Ah 2007-01-16
  • 打赏
  • 举报
回复
COM之所以能够实现前面所说的那些规则(STA、MTA、NA),是因为跨套间调用时,被调用的对象指针是指向一个代理对象,不是组件对象本身。而那个代理对象实现前述的那三个实现算法(转成消息发送,线程切换等),而一般所说的代理/占位对象(Proxy/Stub)等其实都只是指进行汇集工作的代码(后述)。而按照上面直接通过线程参数传入的指针是直接指向对象的,所以将不能实现STA规则,为此COM提供了如下两个函数(还有其他方式,如通过全局接口表GIT)来方便产生代理:CoMarshalInterface和CoUnmarshalInterface(如果在同一进程内的线程间传递接口指针,则可以通过这两个函数来进一步简化代码的编写:CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream)。
现在重写上面代码,线程1得到IABCD*后,调用CoMarshalInterface得到一个IStream*,然后将IStream*传入线程2,在线程2中,调用CoUnmarshalInterface得到IABCD*,现在这个IABCD*就是指向代理对象的,而不是组件对象了。


jiangsheng(蒋晟.Net[MVP]),能不能举个例子?就拿我这个来说好了,谢谢。

Ah 2007-01-15
  • 打赏
  • 举报
回复
没用,最普通的链接都试过了
goodboyws 2007-01-15
  • 打赏
  • 举报
回复
改成
<A class=a01 href="javascript:turnpage('2')">下一页</A>试试
Ah 2007-01-15
  • 打赏
  • 举报
回复
IHTMLDocument2*
CTester::GetDocument(
void
)
{
LPDISPATCH pDisp = NULL;
IHTMLDocument2* pDoc = NULL;

if ( m_pHV == NULL )
return NULL;

if ( !IsWindow( m_pHV->GetSafeHwnd() )) //m_pHV的类型是CHtmlView
return NULL;

pDisp = m_pHV->GetHtmlDocument();
pDisp->QueryInterface(
__uuidof( IHTMLDocument2 ),
(void**) &pDoc
);
pDisp->Release();

return pDoc;
}
加载更多回复(2)

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧