天天看點

VC Webbrowser操作全解(二)

 接上一篇文章内容,本篇文章将講解如何使用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(&params[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)  模拟上傳檔案(由于篇幅問題,需要的可以移步到下一篇文章中檢視)

繼續閱讀