`

Java实现与IE的交互

阅读更多
需求
遍历当前打开的IE实例,分别获取IE浏览器中打开文档的一个节点值,调用IE内容中的一个javascript函数。

分析
Java直接控制IE浏览器,有点麻烦。只有通过VC来实现,生成一个dll文件,Java通过JNI调用。

实现

1、准备工作:该工程采用的原理是通过和IE对象的接口的交互来实现对IE的访问,实际上是采用COM的技术。所以需要在vc工程中加入对COM的支持:

#import <shdocvw.dll>
#import <mshtml.tlb> // Internet Explorer 5
#include <atlbase.h>
CComModule _Module;// 由于要使用 CComDispatchDriver ATL的智能指针,
		// 所以声明它是必须的

#include <mshtml.h>		// 所有 IHTMLxxxx 的接口声明
#include <atlcom.h>

2、用VC实现对当前IE实例的进行遍历的方法,通过ShellWindows集合来代表属于shell的当前打开的窗口的集合,而IE就是属于shell的一个应用程序。

CoInitialize(NULL);//初始化COM
CComPtr< IShellWindows > spShellWin;
HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
if ( FAILED ( hr ) )
{
       return;
}

long nCount = 0;		
spShellWin->get_Count( &nCount );// 取得浏览器实例个Explorer 
//和 IExplorer)
if( 0 == nCount )
{
	return;
}

for(int i=0; i<nCount; i++)
{
	CComPtr< IDispatch > spDispIE;
	hr=spShellWin->Item(CComVariant( (long)i ), &spDispIE );
	if ( FAILED ( hr ) )	continue;

	CComQIPtr< IWebBrowser2 > spBrowser = spDispIE;
	if ( !spBrowser )		continue;

	CComPtr < IDispatch > spDispDoc;
	hr = spBrowser->get_Document( &spDispDoc );//判断实例
                                                     //对象是不是属于IE浏览器对象

	if ( FAILED ( hr ) )	continue;
         ComQIPtr< IHTMLDocument2 > spDocument2 = spDispDoc;
	if ( !spDocument2 )		continue;
	// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
	}
CoUninitialize();//release COM


3、获取IE浏览器中打开文档的一个节点值

HRESULT hr;
CComBSTR bstrTitle;
CComPtr<IHTMLElementCollection> pElementCol;
VARIANT id, index;
CComPtr<IHTMLElement> pElement;
pIHTMLDocument2->get_title( &bstrTitle );	//取得文档标题
if (SUCCEEDED(pIHTMLDocument2->get_all(&pElementCol)))
{
	long p=0;
	if(SUCCEEDED(pElementCol->get_length(&p)))
	if(p!=0)
	{   
		// AfxMessageBox("1");
		for(long i=0;i<=(p-1);i++)
		{
			
			V_VT(&id) = VT_I4;
			V_I4(&id) = i;
			V_VT(&index) = VT_I4;
			V_I4(&index) = 0;
				
			if(SUCCEEDED(pElementCol->item(id,index, &spDispatch)))
			{
					
			     if(SUCCEEDED(spDispatch->QueryInterface(IID_IHTMLElement,(void**)&pElement)))
			     {
					CComBSTR value;
					CComBSTR type;  
					pElement->get_outerText(&value);
					pElement->get_tagName(&type);
					CString   str(value); 
					CString   str2(type); 
					if(str == "百度一下,你就知道")
							AfxMessageBox(str);
					if(str2 == "BROWERID")
							AfxMessageBox(str2);
				}
			}
		}
	}
}

4、调用IE内容中的一个javascript函数

HRESULT   ExecJavascript(CString   strJsFunctionName_In,   const   CArray <VARIANT,   VARIANT&>   &pArrVARIANT_Params) 
{ 
//前提是你已经取得了IHTMLDocument2 
CComPtr <IDispatch>   pScript; 

hResult   =   m_IHTMLDocument2-> get_Script(&pScript); 
if(FAILED(hResult)) 
{ 
return   FALSE; 
} CComBSTR   pCComBSTR(strJsFunctionName_In); 
DISPID   pDISPID; 
hResult   =   pScript-> GetIDsOfNames(IID_NULL,   &pCComBSTR,   1,   LOCALE_SYSTEM_DEFAULT,   &pDISPID); 
if(FAILED(hResult)) 
{ 
return   FALSE; 
}

//(3)Add   Parameters 
DISPPARAMS   pDISPPARAMS; 
memset(&pDISPPARAMS,   0,   sizeof(pDISPPARAMS)); 

int   intArgsCount_In   =   pArrVARIANT_Params.GetSize(); 
VARIANT*   vParams   =   new   VARIANT[intArgsCount_In]; 

for(   int   i   =   0;   i   <   intArgsCount_In;   i++) 
{ 
vParams[i]   =   pArrVARIANT_Params.GetAt(i);   
} 

//Params   Count 
pDISPPARAMS.cArgs   =   intArgsCount_In; 
//Params   Array 
        pDISPPARAMS.rgvarg   =   vParams; 
//Name   Args   Count 
    pDISPPARAMS.cNamedArgs   =   0; 
//(4)Invoke   Javascript   Method 
EXCEPINFO   pEXCEPINFO; 
memset(&pEXCEPINFO,   0,   sizeof(pEXCEPINFO)); 

CComVariant   pCComVariant; 

//Initialize   to   invalid   arg 
UINT   nintArgErr   =   (UINT)-1;     

hResult   =   pScript-> Invoke 
(pDISPID,   IID_NULL,   0,   DISPATCH_METHOD,   &pDISPPARAMS,   &pCComVariant,   &pEXCEPINFO,   &nintArgErr); 

delete[]   pDISPPARAMS.rgvarg; 
pScript.Release(); 

if(FAILED(hResult)) 
{ 
return   FALSE; 
} 

return   TRUE; 
} 


5、编译生成dll文件,供Java通过JNI调用

注意事项
1、可能Java通过JNI调用的时候,会报异常,可能是因为没有释放一些资源包括IDispatch、IHTMLElementCollection、IHTMLElement等。c++不会像java那样垃圾自动回收,需要手动释放。
2、首先需要调用CoInitialize(NULL),因为在调用任何COM函数之前,需要一个线程去调用CoInitialize(NULL)来加载COM组件,这样就可以自由地调用COM的,不过不要忘记CoUninitialize()哦!
分享到:
评论

相关推荐

    java与html交互

    本文通过一个小例子演示了如何通过js与JavaApplet的交互来获取IE端的IP地址,体现了交互和调用。

    IE11停用后EDGE兼容模式切换指南.pdf

    Internet Explorer 11 将于 2022 年 6 月 15 日停用 Microsoft Edge 是唯一一款对旧版网站和应用具有内置兼容性的浏览器。 EDGE怎样兼容IE的网站访问,以下是切换方法 ...扩展(不支持与 IE 页面内容直接交互的扩展)

    flash和jsp,flash和java交互的web project

    flash和jsp交互 flash和java交互的webproject,导入myeclipse中即可运行,

    基于Java Applet的图片浏览小程序设计与实现(源码)

    含有Applet的网页的HTML文件代码中部带有...在Java Applet中,可以实现图形绘制,字体和颜色控制,动画和声音的插入,人机交互及网络交流等功能。 Applet还提供了名为抽象窗口工具箱(Abstract Window Toolkit)

    Java实现WEB链接的标签

    Java实现具有Web 链接功能的标签。窗体中就是一个Web 链接标签,单击此标签,可以打开IE(或其他浏览  器,但必须是系统默认的网页浏览器)并链接至指定的网址。主要是使用java.lang 包中的Runtime 类可以实现标签...

    计算机毕业设计 - JAVA+access综合测评系统毕业设计(源代码+论文+开题报告+任务书),保证可靠运行,提供论文可参考

    Java Applet是用Java语言编写的一些小应用程序,这些程序直接嵌入到网页中,由支持Java的浏览器(IE或Nescape)解释执行能够产生特殊效果。它可以大大提高Web页面的交互能力和动态执行能力。Java Applet与ASP等制作...

    Android编程使用WebView实现与Javascript交互的方法【相互调用参数、传值】

    本文实例讲述了Android编程使用WebView实现与Javascript交互的方法。分享给大家供大家参考,具体如下: Android中可以使用WebView加载网页,同时Android端的Java代码可以与网页上的JavaScript代码之间相互调用。 ...

    DWR:java ajax application

    dwr, java ajax 应用框架,可以将Java对象直接export到ie客户端,成为javascript对象,非常方便js和服务器端的交互,如果你还没有用,就是一下。太方便了呀。

    Java学习Ajax的小例子

    在IE,Servlet的环境下实验Ajax的一个小例子,初学者可看。工具为Eclipse,Tomcat

    这是一个针对ECharts3.x(2.x)版本的Java类库,.rar

    ECharts,一个纯Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的 Canvas 类库 ZRender,提供直观,生动,可交互,可...

    使用Ext Pushlet 实现的点对点聊天功能

    实现通过pushlet,进行点对点聊天功能。 包括: 在线用户上线的通知 离线的通知 来新消息时的通知 前台使用Ext ,后台使用pushlet ...聊天时需要使用,两台电脑,或者 分别使用 IE 与FF 浏览器测试,来模拟多个用户

    使用Ext Pushlet 实现的点对点聊天功能最新

    实现通过pushlet,进行点对点聊天功能。 包括: 在线用户上线的通知 离线的通知 来新消息时的通知 前台使用Ext ,后台使用pushlet ...聊天时需要使用,两台电脑,或者 分别使用 IE 与FF 浏览器测试,来模拟多个用户

    解析Android中webview和js之间的交互

    Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true,,然后通过loadUrl就可以直接进行调用,如下所示:mWebView.getSettings().setJavaScriptEnabled...

    javascript 使用手册

    Java采用静态联编,即Java的对象引用必须在编译时的进行,以使编译器能够实现强类型检查,如不经编译则就无法实现对象引用的检查。JavaScript采用动态联编,即JavaScript的对象引用在运行时进行检查。

    贵阳人文科技学院简历制作ppt

    根据业主要求,网站兼容到chrome,FF,IE9+并使用响应式布局,由于网站主要是展示效果,实现结构、功能、样式三者分离,使用源生js,css2.0(一级页面中使用少量css3.0代码)完成。在项目开发过程中,使用正则表达式实现...

    Java Servlet及Cookie的使用

    本文介绍了Java Servlet编程所需的软件及环境配置。...其作用类似于CGI程序,可以实现网页中很多交互式效果,但比CGI程序效率更高。Cookies是用户访问Web服务器时由Web服务器写入用户计算机特定目录的一小段信息

    说说Java生态圈的那些事儿

    1. 哪个项目能离开网络,数据库,操作系统来运行?所以生态圈的应用技术主要在这些知识点处。  2. Java组件,组件其实是一个应用程序块 但是它们不是完整的...举个例子,IE发送了一个请求给容器,容器通过调用其中

    Android中在WebView里实现Javascript调用Java类的方法

    为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制。只要调用addJavascriptInterface方法即可映射一个Java对象到JavaScript对象上。 1、映射Java对象到...

Global site tag (gtag.js) - Google Analytics