• 使用IWebBrowser2操控浏览器页面测试(IE)


      测试一下在IE浏览器界面中插入代码测试,采用寻找窗口的方式获取Internet Explorer_Server句柄。
      写的时候参考了很多网上的资料,有些地方不大适用就稍微修改了一下。

    1. SendMessageTimeout函数一直无效(看网上有一回答说c#可以正常使用,没试过),无效情况是执行成功(非超时),但是lpRes为0,于是改用SendMessage;
    2. 使用spyxx查找IEFrame下的Internet Explorer_Server窗口,根据实际情况来寻找窗口,网上年代久远的部分代码只有三层;
    3. 似乎是因为main函数在退出时会释放程序执行过程中申请的所有资源的原因,在程序最后加上CoUninitialize()将导致win7下出现程序退出异常的情况,在win10下则不会;另一个解决办法是在CoUninitialize()后边使用ExitProcess()退出进程,但是可能有部分内存未释放;
    4. 测试代码时,在win7及以下平台系统中navigate2()方法无法使用,应使用navigate(),使用navigate()时BSTR类型的URL参数时使用SysAllocString初始化,虽然实际上是wchar*,但是使用常量初始化变量或者使用字符串拷贝函数wcscpy时会出错(迷);
    5. QueryService参数中的SID_SWebBrowserApp替换为IID_IWebBrowserApp

      这里将js代码写入页面需要运行的话,我是使用IHTMLDocument2write方法写回document,页面刷新执行js代码,但是页面部分样式可能丢失。除此之外,还有很多方法可以实现,比如利用事件响应等方法,而且也不一定插入js,插入iframe或者一条链接之类的无需刷新页面。

    #include "windows.h"
    #include "mshtml.h"
    #include "stdio.h"
    #include "ExDisp.h"
    #include "atlbase.h"
    #include "comutil.h"
    #include "oleacc.h"
    
    //#pragma comment(lib, "oleacc.lib")
    
    //int WINAPI WinMain(HINSTANCE hins, HINSTANCE hPrev, LPSTR lpCmdLine, INT nCmdShow) {
    INT main(int argc, char* argv[]){
    	//IWebBrowser2 
    	HWND hWnd_pre = NULL, hWnd_child = NULL, hWnd_IES = NULL;
    	hWnd_pre = FindWindow("IEFrame", NULL);	//IE Window Class
    	if (hWnd_pre == NULL) {
    		OutputDebugString(TEXT("IE didnot open."));
    	}
    
    	hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Shell DocObject View"), NULL);	// test
    	if (hWnd_child == NULL) {	// not only three Layers
    		hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Frame Tab"), NULL);
    		if (hWnd_child == NULL) {
    			OutputDebugString(TEXT("not Found IE Tab."));
    		}
    		hWnd_pre = hWnd_child;
    		hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("TabWindowClass"), NULL);
    		hWnd_pre = hWnd_child;
    		hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Shell DocObject View"), NULL);
    		hWnd_pre = hWnd_child;
    		hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Internet Explorer_Server"), NULL);
    	}
    	else {
    		hWnd_pre = hWnd_child;
    		hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Internet Explorer_Server"), NULL);
    	}
    	hWnd_IES = hWnd_child;		// Get Internet Explorer_Server Window's Handle
    	printf("handle value of Internet Explorer_Server => %#x
    ", (DWORD*)hWnd_child);
    
    	CoInitialize(0);   // for using of COM interfaces
    	UINT nMsg = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT"));   // register common msg of between two windows
    	if (nMsg)
    		printf("success registe Window message WM_HTML_GETOBJECT, msg ID => %#x
    ", nMsg);
    	
    	CComPtr<IHTMLDocument2> pHtmlDoc;
    	LRESULT result;
    	//if (!SendMessageTimeout(hWnd_IES, nMsg, 0, 0, SMTO_NORMAL, 30000, (LPDWORD)result)) {
    	if (!(result = SendMessage(hWnd_IES, nMsg, 0, 0)))		// send message for associated value of msg
    		printf("call sendMessageTimeout failed:( error code: %#x
    ", GetLastError());
    	else {
    		printf("returned result value: %#x
    ", result);
    		/*if (!result) {
    			printf("returned result id none...end");
    			ExitProcess(1);
    		}*/
    		HMODULE hLib = LoadLibrary("oleacc.dll");
    		LPFNOBJECTFROMLRESULT pFObjectFromLresult = (LPFNOBJECTFROMLRESULT)GetProcAddress(hLib, "ObjectFromLresult");
    		//HRESULT hRes = ObjectFromLresult(result, IID_IHTMLDocument2, 0, (void**)&pHtmlDoc);
    		HRESULT hRes = pFObjectFromLresult(result, IID_IHTMLDocument2, 0, (void**)&pHtmlDoc);
    		if (SUCCEEDED(hRes)) {
    			printf("get IHTMLDocument2 success :)
    ");
    			//OLECHAR urll[] = L"http://www.baidu.com/";
    			CComPtr<IHTMLWindow2> spWnd2;
    			CComPtr<IServiceProvider> spServiceProvider;
    			IWebBrowser2* pWebBrow = NULL;
    			hRes = pHtmlDoc->get_parentWindow((IHTMLWindow2**)&spWnd2);
    			if (SUCCEEDED(hRes)) {
    				hRes = spWnd2->QueryInterface(IID_IServiceProvider, (void**)&spServiceProvider);	// Query Interface
    				if (SUCCEEDED(hRes)) {
    					hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&pWebBrow);   // query service
    					if (SUCCEEDED(hRes)) {
    						printf("Get IWebBrowser handlw Success :)
    ");
    
    						////1-跳转测试
    						//VARIANT PARAM;
    						//VariantInit(&PARAM);
    						////V_VT(&PARAM) = VT_I4;
    						////V_I4(&PARAM) = navOpenInNewTab;	//open in new tab
    						////hRes = pWebBrow->Navigate2(&CComVariant("http://www.baidu.com/"), 0, 0, 0, 0);// win7 and former versions not support.
    						//BSTR URLL = SysAllocString(L"http://www.baidu.com/");
    						//hRes = pWebBrow->Navigate(URLL, &PARAM, &PARAM, &PARAM, &PARAM);		// navigate
    						//SysFreeString(URLL);
    						//if (SUCCEEDED(hRes)) printf("navigate success :)
    ");
    						//else printf("navigate failed :(
    ");
    						
    						///*//2-获取地址栏URL测试
    						//hRes = pWebBrow->get_LocationURL(&URLLL);
    						//if(SUCCEEDED(hRes))
    						//	printf("Get URL : %ws
    ", URLL);*/
    						
    						////3-write document
    						//SAFEARRAY* pSafeArr = SafeArrayCreateVector(VT_VARIANT, 0, 1);
    						//if (pSafeArr) {
    						//	BSTR pInsertCode = SysAllocString(L"<script>alert('just a test')</script>");
    						//	VARIANT *PARAM = NULL;
    						//	SafeArrayAccessData(pSafeArr, (void**)&PARAM);
    						//	V_VT(PARAM) = VT_BSTR;		// PARAM->vt = VT_BSTR
    						//	V_BSTR(PARAM) = pInsertCode;	// PARAM->bStrVal
    						//	SafeArrayUnaccessData(pSafeArr);
    						//	pHtmlDoc->write(pSafeArr);	// will refresh
    						//	pHtmlDoc->close();
    						//	SafeArrayDestroy(pSafeArr);
    						//	pSafeArr = NULL;
    						//}
    						
    
    						//get HTML codes
    						BSTR pText = SysAllocString(L"<script>alert('test')</script>");
    						BSTR wheer = SysAllocString(L"afterBegin");	//代码放置位置
    						CComPtr<IHTMLElement> pHtmlElem;
    						pHtmlDoc->get_body(&pHtmlElem);
    						
    						//pHtmlElem->get_innerHTML(&pText);
    						//pHtmlElem->put_innerHTML(pText);
    						hRes = pHtmlElem->insertAdjacentHTML(wheer, pText); // 插入
    						SysFreeString(pText);
    						SysFreeString(wheer);
    						pText = NULL;
    						wheer = NULL;
    
    						//重载页面
    						if (SUCCEEDED(hRes)) {
    							printf("insert html code SUCCESS:)
    ");
    
    							/*pHtmlElem->get_outerHTML(&pText);
    							SAFEARRAY* pSafeArr = SafeArrayCreateVector(VT_VARIANT, 0, 1);
    							VARIANT *PARAM = NULL;
    							SafeArrayAccessData(pSafeArr, (void**)&PARAM);
    							V_VT(PARAM) = VT_BSTR;
    							V_BSTR(PARAM) = pText;
    							SafeArrayUnaccessData(pSafeArr);
    							pHtmlDoc->write(pSafeArr);
    							pHtmlDoc->close();
    							SafeArrayDestroy(pSafeArr);
    							pSafeArr = NULL;*/
    						}
    						else
    							printf("insert html code Failed:(
    ");
    						//printf("HTML Text (length: %#x): %ws
    ", );
    						//INT dwSize = wcslen(pText);
    						//CHAR *pOutter = (CHAR*)malloc(dwSize);
    						//WideCharToMultiByte(CP_ACP, 0, pText, dwSize, pOutter, dwSize, 0, 0);
    						//FILE *fp = fopen("html.html", "w");
    						////fprintf(fp, "%ws", pText);
    						//fwrite(pOutter, wcslen(pText), 1, fp);
    						//free(pOutter);
    						//fclose(fp);
    
    					}
    					else printf("Get IWebBrowser handle Failed:(
    ");
    				}
    				//pHtmlDoc->get_body(&pHtmlElem); //get_body(&pHtmlElem);
    				//pHtmlElem->get_outerHTML(pText); //get_innerText(pText);
    				//printf("GOT > 
    %ws
    ", pText);
    				pWebBrow->Release();
    				pWebBrow = NULL;
    			}
    			else
    				printf("error returned Result Code: %#x
    ", hRes);
    		}
    		else printf("get IHTMLDocument2 failed:(
    ");
    	}
    	/*printf("%#x
    ", hwd);
    
    	PostMessage(hWnd_IES, WM_QUIT, 0, 0);
    	PostMessage(hWnd_IES, WM_CLOSE, 0, 0);
    	PostMessage(hWnd_IES, WM_DESTROY, 0, 0);*/
    	/*CoUninitialize(); //添加则出现异常,可能是在程序退出时还会调用一次析构函数,以释放所有声明的变量
    	ExitProcess(0);*/
    }
    
    

      愈发感觉windows的不简单。
    参考链接:

    1. MSDN
    2. 获取IWebBrowser2指针的方法
  • 相关阅读:
    angular4-http
    angular4-表单
    angular4-事件绑定
    angular4-常用指令
    angular4-自定义组件
    sea.js与require.js的区别
    OC面向对象下之协议
    OC基本程序和面向对象
    OC面对对象下之类别
    Foudation框架之字典
  • 原文地址:https://www.cnblogs.com/zUotTe0/p/11397508.html
Copyright © 2020-2023  润新知