我们的目标是让程序在聊天室中自动发言。自动包括:自动进入聊天室,自动选择发言用户,自动提交发言,
自动在不同的聊天室循环等。
下面我们已tom.com作为例子。
首先我们找到聊天室的入口页面,tom.com聊天室的入口页面为chat.tom.com。我们看一下这个页面的源代码:
<td><div align="center"><a href="http://chat.tom.com/index_more.php?group=同龄话题" target="_blank">
<img src="images/index/chim0_12.gif" width="57" height="15" border="0"></a></div></td>
<td><div align="center"><img src="images/index/chatim_12.gif" width="2" height="13"></div></td>
<td><div align="center"><a href="http://chat.tom.com/index_more.php?group=城市相逢" target="_blank">
<img src="images/index/chim0_16.gif" width="57" height="15" border="0"></a></div></td>
<td><div align="center"><img src="images/index/chatim_12.gif" width="2" height="13"></div></td>
<td><div align="center"><a href="http://chat.tom.com/index_more.php?group=休闲文化" target="_blank">
<img src="images/index/chim0_18.gif" width="58" height="15" border="0"></a></div></td>
<td><div align="center"><img src="images/index/chatim_12.gif" width="2" height="13"></div></td>
<td><div align="center"><a href="http://chat.tom.com/index_more.php?group=情感世界" target="_blank">
<img src="images/index/chim0_20.gif" width="58" height="15" border="0"></a></div></td>
<td><div align="center"><img src="images/index/chatim_12.gif" width="2" height="13"></div></td>
我们可以看到有四个大的入口。因此我们的第一任务就是打开chat.tom.com,提取这四个超链接。
响应CHtmlView类的OnDocumentComplete事件,加入如下代码:
if(strcmp(lpszURL, m_strBaseUrl) == 0)
{
// 得到入口页面列表
if(GetEntryUrlList() == TRUE)
{
// 转到第一个入口页面
PostMessage(WM_NEXT_ENTRY);
}
return;
}
其中lpszURL为OnDocumentComplete事件传入的参数,m_strBaseUrl这里为chat.tom.com。
GetEntryUrlList()为自定义函数,目的是得到入口页面。
我在继承的view类中添加了CStringList m_strEntryList;成员变量,用来保存入口页面的URL地址。
GetEntryUrlList()函数实现如下:
// 得到入口页面列表
BOOL CTomView::GetEntryUrlList()
{
BOOL bRet = FALSE;
HRESULT hResult;
IDispatch *pDocDisp = NULL;
IDispatch *pLinkDisp = NULL;
IHTMLDocument2 *pDoc = NULL;
IHTMLAnchorElement *pLink = NULL;
IHTMLElementCollection *pLinkColl = NULL;
// 清空聊天室入口URL列表
m_strEntryList.RemoveAll();
pDocDisp = GetHtmlDocument();
if(pDocDisp != NULL)
{
hResult = pDocDisp->QueryInterface(IID_IHTMLDocument2, (void **) &pDoc);
if( SUCCEEDED(hResult) && pDoc!=NULL )
{
// 得到所有的超链接
hResult = pDoc->get_links(&pLinkColl);
if( SUCCEEDED(hResult) && pLinkColl!=NULL )
{
long lLinkLen;
VARIANT varIndex;
VariantInit(&varIndex);
varIndex.vt = VT_I4;
pLinkColl->get_length(&lLinkLen);
for(long i=0; i<lLinkLen; i++)
{
varIndex.lVal = i;
hResult = pLinkColl->item(varIndex, varIndex, &pLinkDisp);
if( SUCCEEDED(hResult) && pLinkDisp!=NULL )
{
hResult = pLinkDisp->QueryInterface(
IID_IHTMLAnchorElement,
(void **) &pLink );
if( SUCCEEDED(hResult) && pLink!=NULL)
{
BSTR bstrHref;
CString strHref;
bRet = TRUE;
pLink->get_href(&bstrHref);
strHref = bstrHref;
SysFreeString(bstrHref);
// 得到想要的超链接
if(strHref.Find("http://chat.tom.com/index_more.php?group=") >= 0)
{
// 保存到列表中
m_strEntryList.AddTail(strHref);
}
}
SAFERELEASE(pLink);
}
}
}
}
}
SAFERELEASE(pLinkColl);
SAFERELEASE(pLink);
SAFERELEASE(pDoc);
SAFERELEASE(pLinkDisp);
SAFERELEASE(pDocDisp);
return bRet;
}
这样我们就得到了chat.tom.com的聊天室入口地址。然后进入第一个入口页面。也就是
http://chat.tom.com/index_more.php?group=同龄话题
在OnDocumentComplete函数里
// 转到第一个入口页面
PostMessage(WM_NEXT_ENTRY);
用来进入该页面。
接下来将讲述怎样得到聊天室房间地址,以及怎样自动进入聊天室。
或者因为网页保密的考虑;或者因为软件分发的考虑,有的时候就需要让 IE 或 IE 浏览器控件显示内存或资源中的 HTML 网页。在 MFC 中,CHtmlView::LoadFromResource() 可以显示程序资源中的 HTML 内容。我们都知道MFC的 CHtmlView 其实是对 IWebBrowser2 的一个包装,但是在 IWebBrowser2 中却没有类似的方法。那么它是如何实现的那?步骤如下:
1、首先通过 IWebBrowser2::Navigate2() 显示一个网页,其目的是产生有效的对象,从而得到 IHTMLDocument2 接口;
2、IWebBrowser2::get_Document() 得到 IHTMLDocument2 接口指针;
3、IHTMLDocument2::QueryInterface() 得到 IPersistStreamInit 接口指针;
4、IPersistStreamInit::InitNew() 初始化接口对象;
5、IPersistStreamInit::Load() 装载内存中的 HTML 数据流(IStream *);
内存指针转换为流的方法是:
I、 GlobalAlloc() 申请内存;
II、 复制 HTML 字符串内容到上述的内存中;
III、 CreateStreamFromHGlobal() 转换内存为 IStream 指针;
|