在程序中添加 IE浏览器控件.并添加消息映射函数:
// 重载OnBeforeNavigate2()函数后,可以实现连接重定向
void CIE::OnBeforeNavigate2Explorer1( //该函数在HTML的连接前调用
LPDISPATCH pDisp,
VARIANT FAR* URL, //准备浏览的URL,修改它可以实现转向
VARIANT FAR* Flags,
VARIANT FAR* TargetFrameName,
VARIANT FAR* PostData,
VARIANT FAR* Headers,
BOOL FAR* Cancel) //TRUE:停止 FALSE:继续
{
CString sURL(URL->bstrVal);
int id=sURL.ReverseFind('//'); //反向查找"/和/"
if(id==-1) sURL.ReverseFind('/');
try
{
if(sURL.Mid(id+1).CompareNoCase("ToDialog"))
throw(0); //不是预定义的URL
if(((PostData->vt) & (VT_VARIANT | VT_BYREF))==0)
throw(0);
VARIANT * v=PostData->pvarVal;
if(((v->vt) & (VT_UI1 | VT_ARRAY))==0)
throw(0);
SAFEARRAY *pArr=v->parray;
CString sData=(LPCSTR)pArr->pvData; //至此,得到传送的数据流
////////////// 数据流的结构 //////////////
// 变量1=值1&变量2=值2&......变量n=值n //
//////////////////////////////////////////
CStringArray arrPart;
while(TRUE) //按照 '&' 进行拆分
{
id=sData.Find('&');
if(id==-1){ arrPart.Add(sData); break; }
arrPart.Add(sData.Left(id));
sData=sData.Mid(id+1);
}
CString sResult;
for(int nPart=0;nPart<arrPart.GetSize();nPart++)
{ //循环处理每个“变量=值”的部分
CString sPart=arrPart.GetAt(nPart); //取出
id=sPart.Find('=');
ASSERT(id!=-1);
CString sName = sPart.Left(id); //变量名
CString sValue= sPart.Mid(id+1); //值
sName = WebStr2Str(sName); //转换Web字符串到标准字符串
sValue= WebStr2Str(sValue);
sResult += sName+" = "+sValue+"<br>";
}
//////////// 以下是演示使用DHTML //////////////
IHTMLDocument2 *pDoc=(IHTMLDocument2 *)m_ie.GetDocument();
VARIANT *param;
SAFEARRAY *sfArray;
BSTR bstr = sResult.AllocSysString();
sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if(sfArray && pDoc)
{
if(S_OK == SafeArrayAccessData(sfArray,(LPVOID*) & param))
{
param->vt = VT_BSTR;
param->bstrVal = bstr;
SafeArrayUnaccessData(sfArray);
pDoc->write(sfArray);
}
SysFreeString(bstr);
if (sfArray) SafeArrayDestroy(sfArray);
}
pDoc->Release();
*Cancel=TRUE;
}
catch(...)
{
*Cancel=FALSE;
}
}
CString CIE::WebStr2Str(LPCSTR lpBuf)
{
int nLen;
if(!lpBuf) nLen=0;
else nLen=::lstrlen(lpBuf);
CString s; int i=0;
while(i<nLen)
{
if(lpBuf[i]=='%')
{
BYTE c1=lpBuf[i+1];
BYTE c2=lpBuf[i+2];
i+=2;
if(c1>='0' && c1<='9') c1=(c1-'0')*16;
else if(c1>='A' && c1<='Z') c1=(c1-'A'+10)*16;
else if(c1>='a' && c1<='a') c1=(c1-'a'+10)*16;
if(c2>='0' && c2<='9') c2=c2-'0';
else if(c2>='A' && c2<='Z') c2=c2-'A'+10;
else if(c2>='a' && c2<='z') c2=c2-'a'+10;
char szStr[2]; szStr[0]=c1+c2; szStr[1]=0;
s+=szStr;
}
else if(lpBuf[i]=='+') s+=" ";
else s+=CString(&lpBuf[i],1);
i++;
}
return s;
}
在PreTranslateMessage(MSG* pMsg) 消息中增加:
if ((pMsg->message == WM_LBUTTONDOWN) ) {
CPoint point(pMsg->pt);
ScreenToClient(&point); //
IHTMLDocument2* pdoc2=NULL;
IHTMLElement* pElement=NULL;
IDispatch* pDisp=NULL;
pDisp = m_ie.GetDocument();
if (pDisp == NULL) return TRUE;
pDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pdoc2);
pDisp->Release();
if (pdoc2 == NULL) return TRUE;
// 在我的机器上Y坐标就得减30才取得的URL才正确的地址链接,此处可自行调用以获得准确URL
pdoc2->elementFromPoint (point.x,point.y-30 ,&pElement);
pdoc2->Release();
if(pElement != NULL)
{
IHTMLAnchorElement *pAnchor = NULL;
pElement->QueryInterface(&pAnchor);
if(pAnchor != NULL)
{
BSTR bstrSrc;
pAnchor->get_href(&bstrSrc);
CString sHref(bstrSrc); //转换获得的URL地址
// AfxMessageBox("选择的链接为 : " + sHref);
m_ie.Navigate (sHref, NULL, NULL, NULL, NULL); // 打开获得的链接地址
return TRUE; // 在此处返回,以表示消息已经处理,否则打开的链接还会在新窗口中打开。
}
else
AfxMessageBox ("取到的链接地址为空");
}
return COleControl::PreTranslateMessage(pMsg);