java调用ocx控件(ActiveX控件),SWT调用ocx(ActiveX)
注 : OLE、OCX、ActiveX不进行过多阐述,简单理解就是插件,组件类
调用成功,即可展示ocx对应的窗口
java调用ocx窗口
文档结尾附我使用的jvm ,swt.jar包及下载swt.jar包地址
直接上代码,复制粘贴修改对应的ClassID,方法名,参数,DispatchID即可使用
-
创建 ActiveXUtil 类,简单说就是一个Ole的工具类,将初始化方法,调用ocx方法放在一个util中
import org.eclipse.swt.SWT; import org.eclipse.swt.ole.win32.OleAutomation; import org.eclipse.swt.ole.win32.OleControlSite; import org.eclipse.swt.ole.win32.OleFrame; import org.eclipse.swt.ole.win32.OleListener; import org.eclipse.swt.ole.win32.Variant; import org.eclipse.swt.widgets.Shell; public class ActiveXUtil { private Shell _shell;//弹窗 private OleFrame _frame; //一个放置ole控件的面板 private OleControlSite _site;//ActiveX控件(即插件 注 : OleClientSite为OLE控件) private OleAutomation _auto;//Ole自动服务器,编写能被其他程序调用的代码 public Shell getShell() { return _shell; } public OleFrame getFrame() { return _frame; } public OleControlSite getSite() { return _site; } public OleAutomation getAuto() { return _auto; } //请求 OLE 对象执行其中一个可用的动作 OLE 对象—激活其内容所需的操作 public int doVerb(int verb) { return _site.doVerb(verb); } //构造方法,进行窗口初始化 ActiveXUtil(String activexId, OleControlSite site, Shell shell) { if (site == null) { _shell = (shell == null ? new Shell() : shell); _frame = new OleFrame(_shell, SWT.NONE); _site = new OleControlSite(_frame, SWT.NONE, activexId); _auto = new OleAutomation(_site); } else { _site = site; _auto = new OleAutomation(site); } } //根据控件中的方法名获取对应的disId public int getID(String name) { try { int[] ids = _auto.getIDsOfNames(new String[] { name }); if (ids.length >= 0) return ids[0]; } catch (RuntimeException e) { e.printStackTrace(); } return -1; } public Variant[] createVariants(String[] paras) { Variant[] vr = new Variant[paras.length]; for (int i = 0; i < paras.length; i++) { vr[i] = new Variant(paras[i]); } return vr; } public Variant getProperty(String prop) { int propId = getID(prop); Variant v = null; try { v = _auto.getProperty(propId); } catch (Exception e) { e.printStackTrace(); } return v; } public void setProperty(String name, String... params) { int propId = getID(name); if (propId < 0) return; if (params.length == 1) _auto.setProperty(propId, new Variant(params[0])); else { Variant[] vs = new Variant[params.length]; int i = 0; for (String param : params) { vs[i] = new Variant(param); i++; } _auto.setProperty(propId, vs); } } public void setProperty(String name, Variant... params) { int propId = getID(name); if (propId < 0) return; _auto.setProperty(propId, params); } public Variant execute(String methodName, Variant... params) { int mid = getID(methodName); if (mid < 0) return null; Variant rtnv; if (params == null) rtnv = _auto.invoke(mid); else rtnv = _auto.invoke(mid, params); return rtnv; } public Variant execute(String methodName) { int mid = getID(methodName); if (mid < 0) return null; Variant rtnv = _auto.invoke(mid); return rtnv; } public void addEventListener(int eventID, OleListener listener) { _site.addEventListener(eventID, listener); } public void removeEventListener(int eventID, OleListener listener) { _site.removeEventListener(eventID, listener); } }
-
创建调用ocx的类
import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.ole.win32.OLE; import org.eclipse.swt.ole.win32.OleEvent; import org.eclipse.swt.ole.win32.OleListener; import org.eclipse.swt.ole.win32.Variant; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SwtOcx { public static void main(String[] args) { // 设置应用标题 Display display = Display.getDefault(); Shell shell = new Shell(); shell.setSize(900, 760); shell.setLayout(new RowLayout()); shell.setText("调用ocx程序"); // 初始化ActiveX控件 final ActiveXUtil util = new ActiveXUtil("{8975B773-7CF3-4C4C-B646-DA9F6A154260}", null, shell);//ClassID util.getFrame().setSize(shell.getClientArea().width, shell.getClientArea().height); util.doVerb(OLE.OLEIVERB_SHOW); //监听事件 final int nEventXXX = 210;// 某事件ID,使用工具查看事件的DispatchID util.addEventListener(nEventXXX, new OleListener() { @Override public void handleEvent(OleEvent event) { System.out.println(event.arguments[0].getString()); //监听事件对应的数据,打印 } }); // 调用方法 Button button1 = new Button(shell, SWT.PUSH); button1.setText("调用OCX方法"); button1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { Variant result = util.execute("mothed", new Variant( "参数"));//mothed为要调用的插件内的方法名 , 方法中的入参用new Variant("参数")进行传输,,多个参数则new 多个Variant if (result == null) { System.out.println("ActiveX method failure!"); } } }); // 显示窗口 shell.setSize(900, 800); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } }
-
操作过程中报错解答
-
UnsatisfiedLinkError: Cannot load 64-bit SWT libraries on 32-bit JVM
32位的JVM不能使用64位的SWT,修改对应的JVM或者SWT即可 -
org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
具体原因没有排查,但是肯定是出在ocx,jar包和JVM之前的关系不匹配,此处我是使用32位的OCX,然后是org.eclipse.swt.win32.win32.x86_64-4.6.jar包,64位的JVM报的这个错,不用多想,肯定是三者之间不匹配,多换jar包,jvm即可
- org.eclipse.swt.SWTException: Class ID not found in registry
ClassID不对,若确定classid正确,可能是你没有加{},此处我是直接拷贝的8975B773-7CF3-4C4C-B646-DA9F6A154260,报错后加上{}后即可{8975B773-7CF3-4C4C-B646-DA9F6A154260}
4)
空指针,方法名,参数,参数个数总有一个是错误,核查解决即可5)监听事件出不来数据,DispatchID不对,去检查DispatchID
-
-
调用成功后 ,窗口展示情况
** 附 : swt32位.jar包 失效留言重新发**
链接: https://pan.baidu.com/s/1o7EOnMM5BU8Z2BC2TaiODQ 提取码: x6dj 复制这段内容后打开百度网盘手机App,操作更方便哦
**附 : 32位jdk1.7 **
链接: https://pan.baidu.com/s/1GtsJPrKVxpQD9ps9vx2v6g 提取码: 97wq 复制这段内容后打开百度网盘手机App,操作更方便哦
**附 : swt包下载地址 : https://repo1.maven.org/maven2/swt/ **