计算机专业职业发展免费测评

CowNew开源团队

http://www.cownew.com 邮件请联系 about521 at 163.com

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  258 随笔 :: 1 文章 :: 578 评论 :: 0 Trackbacks

在SWT中提供了访问OLE的方式,不过相关的例子都是进程内OLE的例子,比如嵌入浏览器、引用ActiveX控件什么的。由于客户的需求,我们需要在程序中通过进程外Automation服务的方式访问IE浏览器。经过网上搜寻,找到一个朋友写的CComObject类可以访问Automation服务。不过经过使用发现一些错误,因此对其进行了修改,为了方便访问IE,我又封装了一个IEAutomation类,这样就暴露给使用者navigatequit这样的方法。(作者:www.cownew.com 杨中科)

这里例子完全可以用来操控其他的Automation对象,比如操控Work、Excel、AcrobatReader等。

全部代码如下:

CComObject.java

package test;


import org.eclipse.swt.SWT;

import org.eclipse.swt.internal.ole.win32.COM;

import org.eclipse.swt.internal.ole.win32.DISPPARAMS;

import org.eclipse.swt.internal.ole.win32.EXCEPINFO;

import org.eclipse.swt.internal.ole.win32.GUID;

import org.eclipse.swt.internal.ole.win32.IDispatch;

import org.eclipse.swt.internal.ole.win32.ITypeInfo;

import org.eclipse.swt.internal.ole.win32.IUnknown;

import org.eclipse.swt.internal.win32.OS;

import org.eclipse.swt.ole.win32.OLE;

import org.eclipse.swt.ole.win32.Variant;

/**

 * 
@author hcw

 
*/


public class CComObject

{

private GUID guid = new GUID();


private IDispatch Autoface = null;


private ITypeInfo TypeInfo = null;


private void CreateComObject()

{

dispose();


int[] ppv = new int[1];


int ret = COM.CoCreateInstance(guid, 0, COM.CLSCTX_INPROC_SERVER

| COM.CLSCTX_LOCAL_SERVER, COM.IIDIUnknown, ppv);

if (ret != COM.S_OK)

OLE.error(ret);

// throw new RuntimeException("对象创建失败!");


IUnknown objIUnknown 
= new IUnknown(ppv[0]);

ppv 
= new int[1];


ret 
= objIUnknown.QueryInterface(COM.IIDIDispatch, ppv);

objIUnknown.Release();

if (ret != COM.S_OK)

OLE.error(ret);

// throw new RuntimeException("对象不支持Dispatch!");


Autoface 
= new IDispatch(ppv[0]);


ppv 
= new int[1];

ret 
= Autoface.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppv);

if (ret == OLE.S_OK)

{

TypeInfo 
= new ITypeInfo(ppv[0]);

TypeInfo.AddRef();


}



}



private int getIDsOfNames(String name)

{

int[] rgdispid = new int[1];

String[] names 
= new String[] { name };

int ret = Autoface.GetIDsOfNames(guid, names, names.length,

COM.LOCALE_USER_DEFAULT, rgdispid);

if (ret != COM.S_OK)

return -1;


return rgdispid[0];

}



private void getVariantData(Variant aVar, int pData)

{

if (pData == 0)

OLE.error(OLE.ERROR_OUT_OF_MEMORY);


COM.VariantInit(pData);


if ((aVar.getType() & COM.VT_BYREF) == COM.VT_BYREF)

{

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new int[] { aVar.getByRef() }4);

return;

}



switch (aVar.getType())

{

case COM.VT_EMPTY:

break;

case COM.VT_BOOL:

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8,

new int[] { (aVar.getBoolean()) ? COM.VARIANT_TRUE

: COM.VARIANT_FALSE }
2);

break;

case COM.VT_R4:

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new float[] { aVar.getFloat() }4);

break;

case COM.VT_I4:

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new int[] { aVar.getInt() }4);

break;

case COM.VT_DISPATCH:

aVar.getDispatch().AddRef();

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new int[] { aVar.getDispatch()

.getAddress() }
4);

break;

case COM.VT_UNKNOWN:

aVar.getUnknown().AddRef();

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new int[] { aVar.getUnknown()

.getAddress() }
4);

break;

case COM.VT_I2:

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

COM.MoveMemory(pData 
+ 8new short[] { aVar.getShort() }2);

break;

case COM.VT_BSTR:

COM.MoveMemory(pData, 
new short[] { aVar.getType() }2);

char[] data = (aVar.getString() + "\0").toCharArray();

int ptr = COM.SysAllocString(data);

COM.MoveMemory(pData 
+ 8new int[] { ptr }4);

break;


default:

OLE.error(SWT.ERROR_NOT_IMPLEMENTED);

}


}



private Variant setVariantData(int pData)

{

if (pData == 0)

OLE.error(OLE.ERROR_INVALID_ARGUMENT);


Variant ret 
= null;

short[] dataType = new short[1];

COM.MoveMemory(dataType, pData, 
2);

int type = dataType[0];


if ((type & COM.VT_BYREF) == COM.VT_BYREF)

{

int[] newByRefPtr = new int[1];

OS.MoveMemory(newByRefPtr, pData 
+ 84);

return new Variant(newByRefPtr[0], COM.VT_BYREF);

}



switch (type)

{

case COM.VT_EMPTY:

break;

case COM.VT_BOOL:

short[] newBooleanData = new short[1];

COM.MoveMemory(newBooleanData, pData 
+ 82);

ret 
= new Variant(newBooleanData[0!= 0);

break;

case COM.VT_R4:

float[] newFloatData = new float[1];

COM.MoveMemory(newFloatData, pData 
+ 84);

ret 
= new Variant(newFloatData[0]);

break;

case COM.VT_I4:

int[] newIntData = new int[1];

OS.MoveMemory(newIntData, pData 
+ 84);

ret 
= new Variant(newIntData[0]);

break;

case COM.VT_DISPATCH:

{

int[] ppvObject = new int[1];

OS.MoveMemory(ppvObject, pData 
+ 84);

if (ppvObject[0== 0)

{

type 
= COM.VT_EMPTY;

break;

}


ret 
= new Variant(new IDispatch(ppvObject[0]));

break;

}


case COM.VT_UNKNOWN:

{

int[] ppvObject = new int[1];

OS.MoveMemory(ppvObject, pData 
+ 84);

if (ppvObject[0== 0)

{

type 
= COM.VT_EMPTY;

break;

}


ret 
= new Variant(new IUnknown(ppvObject[0]));

break;

}


case COM.VT_I2:

short[] newShortData = new short[1];

COM.MoveMemory(newShortData, pData 
+ 82);

ret 
= new Variant(newShortData[0]);

break;

case COM.VT_BSTR:

// get the address of the memory in which the string resides

int[] hMem = new int[1];

OS.MoveMemory(hMem, pData 
+ 84);

if (hMem[0== 0)

{

type 
= COM.VT_EMPTY;

break;

}


int size = COM.SysStringByteLen(hMem[0]);

if (size > 0)

{

char[] buffer = new char[(size + 1/ 2]; // add one to avoid

// rounding errors

COM.MoveMemory(buffer, hMem[
0], size);

ret 
= new Variant(new String(buffer));

}
 else

{

ret 
= new Variant(""); //$NON-NLS-1$

}


break;


default:

int newPData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,

Variant.sizeof);

if (COM.VariantChangeType(newPData, pData, (short0, COM.VT_R4) == COM.S_OK)