用MFC 新建一个对话框工程,在界面上加入webbrowsr控件。
关键是要利用这个头文件 Mshtml.h
声明这几个函数:
IHTMLElement* GetHTMLElement(const CString& strID); //获取网页元素,通过ID 主要用来获得 button 和 text 控件
IHTMLSelectElement* GetHTMLSelectElement(const CString& strID); //获取select 控件 元素
IDispatch* GetHTMLElemCollDispatch(const CString& strID); //获取收集所有网页元素的Dispatch这个函数具体实现
IDispatch* CHtmlClickDlg::GetHTMLElemCollDispatch(const CString& strID)
{
HRESULT hr = S_OK;
IDispatch* pDispath = NULL;
IHTMLElement* pElem = NULL;
pDispath = m_web.get_Document(); //m_web是CExplorer 也就是webbrowser控件
if (pDispath == NULL)
{
TRACE(L"pDispath = m_web.get_Document() = NULL");
}
IHTMLDocument2* pDoc = NULL;
hr = pDispath->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
pDispath->Release();
pDispath = NULL;
if(pDoc == NULL || hr != S_OK)
{
TRACE(L"IHTMLDocument2 pDoc NULL or hr != S_OK");
return NULL;
}
IHTMLElementCollection* pColl = NULL;
hr = pDoc->get_all(&pColl);
pDoc->Release();
pDoc = NULL;
ASSERT(pColl!=NULL);
if( pColl==NULL || hr != S_OK)
{
TRACE(L"IHTMLElementCollection pColl = NULL or hr != S_OK");
return NULL;
}
IDispatch* pDispath2 = NULL;
VARIANT index = {0};
V_VT(&index) = VT_I4;
V_I4(&index) = 0;
VARIANT varID = {0};
VariantInit(&varID);
varID.vt = VT_BSTR;
varID.bstrVal = strID.AllocSysString();
hr = pColl->item(varID,index,&pDispath2);
pColl->Release();
pColl = NULL;
if(hr != S_OK)
{
TRACE(L"");
pDispath2 = NULL;
}
return pDispath2;
}
这就可以通过GetHTMLElemCollDispatch函数来获得指定元素的Dispatch,用它来给定元素的接口
查询到IID_IHTMLElement的接口,把这个接口返回,后续用于执行click ,或者设置文字,这个可用于button,text控件,其他的可以查看那个头文件。
IHTMLElement* CHtmlClickDlg::GetHTMLElement(const CString& strID)
{
HRESULT hr = S_OK;
IDispatch* pDispath = NULL;
IHTMLElement* pElem = NULL;
pDispath = GetHTMLElemCollDispatch(strID);
if(pDispath != NULL)
{
hr = pDispath->QueryInterface(IID_IHTMLElement,(void**)&pElem); // 查询到IID_IHTMLElement的接口,把这个接口返回,后续用于执行click ,或者设置文字
if( hr != S_OK )
{
pElem = NULL;
}
pDispath->Release();
}
return pElem;
}
//这个可以用来获得select 下拉菜单控件的接口,当然都得使用到GetHTMLElemCollDispatch,有了接口就可以执行它内含的事件了。
IHTMLSelectElement* CHtmlClickDlg::GetHTMLSelectElement(const CString& strID)
{
HRESULT hr = S_OK;
IDispatch* pDispath = NULL;
IHTMLSelectElement* pSelectElem = NULL;
pDispath = GetHTMLElemCollDispatch(strID);
if(pDispath != NULL)
{
hr = pDispath->QueryInterface(IID_IHTMLSelectElement,(void**)&pSelectElem);
if( hr != S_OK )
{
pSelectElem = NULL;
}
pDispath->Release();
}
return pSelectElem;
}这几个函数具体实例操作。
button 按钮点击 , 传入参数可以是控件的 id 或者 name,就用查询到的接口,调用它里面的click事件就可以实现自动点击了
void CHtmlClickDlg::OnWebClick(const CString& strID)
{
HRESULT hr = S_OK;
IHTMLElement* pElem = NULL;
pElem = GetHTMLElement(strID);
if (pElem != NULL)
{
hr = pElem->click();
pElem->Release();
}
pElem = NULL;
}设置text 控件中的文字, 用的是put_innerText这个事件。需要text控件的 id 或name,已经要填入的文本。
void CHtmlClickDlg::SetWebEditText(const CString& strID,const CString& strText)
{
HRESULT hr = S_OK;
IHTMLElement* pElem = NULL;
pElem = GetHTMLElement(strID);
if (pElem != NULL)
{
hr = pElem->put_innerText(strText.AllocSysString());
pElem->Release();
}
pElem = NULL;
}
void CHtmlClickDlg::OnWebSelect(const CString& strID, long lIndex)
{
HRESULT hr = S_OK;
IHTMLSelectElement* pSelectElem = NULL;
pSelectElem = GetHTMLSelectElement(strID);
if (pSelectElem != NULL)
{
hr = pSelectElem->put_selectedIndex(lIndex);
pSelectElem->Release();
}
pSelectElem = NULL;
}这里只是一个简单的介绍和应用,局限性很大。
补充一些内容:
m_strWebAddr = m_web.get_LocationURL(); //获取当前网页地址
这个可以放在webbrowser控件的事件 DocumentCompleteExplorer(LPDISPATCH pDisp, VARIANT* URL) 中来完成,这个事件是网页加载完毕后会调用,但是如果网页是动态一部分一部分加载的该函数就会被调用很多次。
在控件上点击一个连接,不去打开新的网页窗口的办法可以尝试用这个。
在webbrowser控件中添加事件,NewWindow3Explorer
void CHtmlClickDlg::NewWindow3Explorer(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl)
{
m_web.Navigate(bstrUrl,NULL,NULL,NULL,NULL);
*Cancel = TRUE;
}
这里让控件去打开连接网站,并且避免打开新的窗口,就是给Cancel赋值为TRUE,即可实现,本地测试的是IE9
本文介绍如何在MFC应用中利用WebBrowser控件进行网页自动登录和交互。关键在于引入Mshtml.h头文件,通过GetHTMLElemCollDispatch获取元素Dispatch,执行click事件进行按钮点击,使用put_innerText设置输入框文字。同时,文章还提及了在网页加载完成后获取当前地址的方法,以及如何阻止新窗口的打开,实现链接点击后在当前窗口内导航。

2万+

被折叠的 条评论
为什么被折叠?



