接上一篇文章内容,本篇文章将講解如何使用Webbrowser 操作HTML頁面
二、對HTML頁面元素的操作
(1) Input 值設定
xny::Integer SetInputText(LPCTSTR lpInputName, LPCTSTR lpText, LPCTSTR lpParentName, LPCTSTR lpPopFrameName)
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
CComPtr<IHTMLElement> pElement = NULL;
if (lpPopFrameName)
{
CComPtr<IHTMLIFrameElement> pIFrame = (IHTMLIFrameElement*)m_pWebBrowserEx->GetElementByName(lpPopFrameName, lpParentName, IID_IHTMLIFrameElement);
if (pIFrame == NULL ) break;
pElement = (IHTMLElement *)m_pWebBrowserEx->GetElementByName(lpInputName,pIFrame, IID_IHTMLElement);
}
else
{
pElement = (IHTMLElement *)m_pWebBrowserEx->GetElementByName(lpInputName, lpParentName, IID_IHTMLElement);
}
if (pElement == 0) break;
//轉換成CComBSTR
CComBSTR bStr = lpText;
//輸入内容
pElement->put_innerText(bStr);
nRet = nsny::eProbeErr::NYERR_SUCCESS;
} while (0);
return nRet;
}
(2) Select選擇
xny::Integer SelectOption(LPCTSTR lpOptionName, bool bIsSelect, LPCTSTR lpParentName )
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
CComPtr<IHTMLElement> pElement = NULL;
pElement = (IHTMLElement*)m_pWebBrowserEx->GetElementByTag(lpOptionName, _T("input"), _T("id"), lpParentName, IID_IHTMLElement);
if (pElement == NULL ) break;
VARIANT va;
va.vt = VT_BOOL;
va.boolVal = bIsSelect;
nRet = pElement->setAttribute(L"checked", va);
//此處需要主動響應點選事件否則隻會有顯示效果
VARIANT params[10];
VARIANT ret;
HRESULT hRet = CWebBrowserEx::InvokeMethod(pElement, _T("onclick"), &ret, params, 0);
if (FAILED(hRet)) break;
VariantClear(&va);
} while (0);
return nRet;
}
(3) Combo選擇
xny::Integer SelectCombo(LPCTSTR lpCmboName, int nIndex, LPCTSTR lpParentName )
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
CComPtr<IHTMLSelectElement> pElement = NULL;
pElement = (IHTMLSelectElement*)m_pWebBrowserEx->GetElementByName(lpCmboName, lpParentName, IID_IHTMLSelectElement);
if (pElement == NULL) break;
long lLen = 0;
HRESULT hRet = pElement->get_length(&lLen);
if (FAILED(hRet)) break;
for (int i = 0; i < lLen; i++)
{
if (i != nIndex)continue;
CComPtr<IHTMLOptionElement> pItem;
CComDispatchDriver spInputElement; //取得第 i 項
hRet = pElement->item(CComVariant(i), CComVariant(i), &spInputElement);
if (FAILED(hRet)) continue;
hRet = spInputElement->QueryInterface(IID_IHTMLOptionElement, (void**)&pItem);
if (FAILED(hRet)) continue;
pItem->put_selected(TRUE);
}
//此處需要主動響應onchange 消息,否則不會自動觸發
VARIANT params[10];
VARIANT ret;
hRet = CWebBrowserEx::InvokeMethod(pElement, _T("onchange"), &ret, params, 0);
if (FAILED(hRet)) break;
nRet = nsny::eProbeErr::NYERR_SUCCESS;
} while (0);
return nRet;
}
(4) Table 插入資料到tBody
xny::Integer InstertTableElement(LPCTSTR lpTabName, TABLE_INFO& info, LPCTSTR lpParentName)
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
CComPtr<IHTMLTable> pElement = NULL;
pElement = (IHTMLTable*)m_pWebBrowserEx->GetElementByName(lpTabName, lpParentName, IID_IHTMLTable);
if (pElement == NULL ) break;
//清理
CComPtr<IHTMLElementCollection> pBody;
HRESULT hr = pElement->get_tBodies(&pBody);
if (FAILED(hr)) break;
long lNum = 0;
pBody->get_length(&lNum);
CComPtr<IHTMLDOMNode> node_tdnum = NULL;
for (int i = 0; i < lNum; i++)
{
CComDispatchDriver spInputElement; //取得第 i 項
HRESULT hr = pBody->item(CComVariant(i), CComVariant(i), &spInputElement);
if (FAILED(hr))continue;
CComPtr<IHTMLElement> pItem;
hr = spInputElement->QueryInterface(IID_IHTMLElement, (void**)&pItem);
if (FAILED(hr)) continue;
BSTR strName;
pItem->get_outerHTML(&strName);
OutputDebugString(strName);
hr = pItem->QueryInterface(IID_IHTMLDOMNode, (void**)&node_tdnum);
}
if (node_tdnum == NULL ) break;
CComPtr<IHTMLDocument2> pHtmlDoc2 = NULL;
CComPtr<IDispatch> dispatch;
hr = m_pWebBrowserEx->GetWebBrowser2()->get_Document(&dispatch);
if (!FAILED(hr) && dispatch)
{
hr = dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc2);
}
if (FAILED(hr)) break;
nRet = CreateTabElement(pHtmlDoc2, node_tdnum, info, lNum);
} while (0);
return nRet;
}
(5) 建立HTML節點元素
xny::String CreateTabElement(CComPtr<IHTMLDocument2> pHtmlDoc2, IHTMLDOMNode* pParent, TABLE_INFO& info, int nCurIndex)
{
HRESULT hRet = S_FALSE;
std::map<xny::String, xny::String> mpAttr;
xny::String strRetXml;
do
{
if (pHtmlDoc2 == NULL ) break;
if (pParent == NULL ) break;
std::map<xny::String, xny::String> mpData;
xny::String strRetHtml;
CComPtr<IHTMLDOMNode> pNode_Main = CreateHtmlNode(pHtmlDoc2, _T("tr"), mpData, NULL, strRetHtml);
CComPtr<IHTMLDOMNode> pRefNode;
mpData[_T("width")] = _T("10%");
mpData[_T("class")] = _T("td_num");
xny::String strXML = _T("<td width=\"10%\" class=\"td_num\">")
_T("<input name=\"element_name1\" id=\"tn_")+ std::to_wstring(nCurIndex)+_T("\"")
_T("style=\"border: 0px currentColor; width: 60px; text-align: center;\" type=\"text\"")
_T("readOnly=\"true\" value=\"") + std::to_wstring(nCurIndex) + _T("\">")
_T("<input name=\"element_name2\" style=\"display: none;\" type=\"checkbox\"")
_T("CHECKED=\"checked\" value=\"") + info.strTableID + _T("\">")
_T("<input name=\"element_name3\"")
_T("style=\"display: none;\" type=\"checkbox\" CHECKED=\"checked\" value=\"") + info.strTableName + _T("\">")
_T("<input name=\"element_name4\" style=\"display: none;\" type=\"checkbox\" CHECKED=\"checked\" value=\"") + info.strType + _T("\">")
_T("</td>");
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml, strXML.c_str());
strRetXml += strRetHtml;
mpData.clear();
mpData[_T("width")] = _T("10%");
mpData[_T("class")] = _T("borderT3");
mpData[_T("data")] = info.strType;
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml);
strRetXml += strRetHtml;
mpData.clear();
mpData[_T("width")] = _T("15%");
mpData[_T("class")] = _T("borderT3");
mpData[_T("data")] = info.strTableNum;
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml);
strRetXml += strRetHtml;
mpData.clear();
mpData[_T("width")] = _T("15%");
mpData[_T("class")] = _T("borderT3");
mpData[_T("data")] = info.strTableNum;
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml);
strRetXml += strRetHtml;
mpData.clear();
mpData[_T("width")] = _T("20%");
mpData[_T("class")] = _T("borderT3");
mpData[_T("data")] = info.strTableName;
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml);
mpData.clear();
mpData[_T("width")] = _T("10%");
mpData[_T("class")] = _T("borderT3");
strXML = _T("<td width=\"10%\" class=\"borderT3\"><input onclick=\"attremove(this)\" type=\"button\" value=\"删除\"></td>");
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml, strXML.c_str());
strRetXml += strXML;
mpData.clear();
mpData[_T("width")] = _T("20%");
mpData[_T("class")] = _T("borderT3");
strXML = _T("<td width = \"20%\" class=\"borderT3\"><input name=\"btn1\"")
_T("onclick = \"prevMoveTrCommand(this,'tableTest','tb_num');\" type=\"button\" value=\"上移\"><input ")
_T("name = \"btn2\" onclick=\"nextMoveTrCommand(this,'tableTest','tb_num');\" type=\"button\"")
_T("value = \"下移\"></td>");
CreateHtmlNode(pHtmlDoc2, _T("td"), mpData, pNode_Main, strRetHtml, strXML.c_str());
strRetXml += strXML;
hRet = pParent->appendChild(pNode_Main, &pRefNode);
} while (0);
return hRet;
}
CComPtr<IHTMLDOMNode> CreateHtmlNode(CComPtr<IHTMLDocument2> pHtmlDoc2, xny::String strTag, std::map<xny::String, xny::String>& mpAttr, IHTMLDOMNode* pParent, LPCTSTR lpXML )
{
CComPtr<IHTMLElement> ele = NULL;
BSTR strText = ::SysAllocString(strTag.c_str());
pHtmlDoc2->createElement(strText, (IHTMLElement**)&ele);
CComPtr<IHTMLDOMNode> node = NULL;
ele->QueryInterface(IID_IHTMLDOMNode, (void **)&node);//you need include <mshtml.h>
SysFreeString(strText);
VARIANT attrVal;
if (lpXML)
{
strText = SysAllocString(lpXML);
ele->put_innerHTML(strText);
SysFreeString(strText);
}
for (auto it_attr = mpAttr.begin(); it_attr != mpAttr.end(); it_attr++)
{
if (it_attr->first == _T("data"))
{
BSTR text = ::SysAllocString(it_attr->second.c_str());
ele->put_innerText(text);
SysFreeString(text);
continue;
}
attrVal.vt = VT_BSTR;
attrVal.bstrVal = ::SysAllocString(it_attr->second.c_str());
BSTR strName = ::SysAllocString(it_attr->first.c_str());
ele->setAttribute(strName, attrVal);
SysFreeString(strName);
SysFreeString(attrVal.bstrVal);
VariantClear(&attrVal);
}
if (pParent)
{
CComPtr<IHTMLDOMNode> pRetNode;
pParent->appendChild(node, &pRetNode);
}
return node;
}
(6) 調用Js函數
xny::Integer CallJsFun(LPCTSTR lpFunName, LPCTSTR lpParam )
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
VARIANT params[10];
int nParamNum = 0;
if (lpParam != NULL)
{
xny::StringArray arr = util::CStrMisc::split_vct(lpParam, _T(","));
int nIndex = 0;
for (auto it_param = arr.begin(); it_param != arr.end(); it_param++, nIndex++)
{
params[nIndex].vt = VT_BSTR;
params[nIndex].bstrVal = ::SysAllocString(lpParam);
}
nParamNum = arr.size();
}
CComBSTR bStr = lpFunName;
VARIANT ret;
CWebBrowserEx::InvokeMethod(m_pWebBrowserEx->GetHtmlWindow(), bStr, &ret, params, nParamNum);
if (nParamNum)
{
for (int i = 0; i < nParamNum; i++)
{
SysFreeString(params[i].bstrVal);
VariantClear(¶ms[i]);
}
}
nRet = nsny::eProbeErr::NYERR_SUCCESS;
} while (0);
return nRet;
}
(7) 網頁按鈕模拟點選
xny::Integer ClickButton(LPCTSTR lpBtnName, LPCTSTR lpClassName, LPCTSTR lpBtnTag, LPCTSTR lpParentName, LPCTSTR lpPopFrameName)
{
xny::Integer nRet = nsny::eProbeErr::NYERR_FAIL;
do
{
if (m_pWebBrowserEx == NULL ) break;
CComPtr<IHTMLElement> pElement = NULL;
if (lpPopFrameName)
{
CComPtr<IHTMLIFrameElement> pIFrame = (IHTMLIFrameElement*)m_pWebBrowserEx->GetElementByName(lpPopFrameName,lpParentName, IID_IHTMLIFrameElement);
if (pIFrame == NULL) break;
if (lpClassName)
pElement = (IHTMLElement*)m_pWebBrowserEx->GetElementByTag(lpClassName, lpBtnTag, lpBtnName, pIFrame, IID_IHTMLElement);
else
pElement = (IHTMLElement*)m_pWebBrowserEx->GetElementByName(lpBtnName, pIFrame, IID_IHTMLElement);
}
else
{
if (lpClassName)
pElement = (IHTMLElement*)m_pWebBrowserEx->GetElementByTag(lpClassName, lpBtnTag, lpBtnName, lpParentName, IID_IHTMLElement);
else
pElement = (IHTMLElement*)m_pWebBrowserEx->GetElementByName(lpBtnName, lpParentName, IID_IHTMLElement);
}
if (pElement == NULL ) break;
VARIANT params[10];
VARIANT ret;
CWebBrowserEx::InvokeMethod(pElement, _T("click"), &ret, params, 0);
nRet = nsny::eProbeErr::NYERR_SUCCESS;
} while (0);
return nRet;
(8) 模拟上傳檔案(由于篇幅問題,需要的可以移步到下一篇文章中檢視)