ActiveX是Microsoft对于一系列策略性面向对象程序技术和工具的称呼,其中主要的技术是组件对象模型(COM)。在有目录和其它支持的网络中,COM变成了分布式COM(DCOM)
网上绝大部分ActiveX控件的使用都是c++,今天我来记录一下javaActiveX的使用
这里我们创建一个普通的java项目,我创建了2个文件夹,lib用来存放依赖包,ocx则是代码包,当然这个没有要求,随便怎么放都可以
首先我们需要添加一个依赖包:org.eclipse.swt.win32.win32.x86_3.103.1.v20140903-1947.jar
这个依赖包是swt组件的包,如果你的开发工具是MyEclipse的话,在安装目录的plugins文件夹下面就能找到这个包
这个包分为有32位和64位的区别,建议大家用32位,因为绝大部分Windows控件都是32位
我们创建一个java文件,代码如下
package ocx;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.Variant;
public class Controller {
private OleAutomation oleAutomation;
public Controller(OleAutomation oleAutomation)
{
this.oleAutomation = oleAutomation;
}
public OleAutomation GetOleAutomation(){
return oleAutomation;
}
public Variant execute(String methodName) {
return execute(methodName, null);
}
public Variant execute(String methodName, Variant[] args) {
int mid = getID(methodName);
return execute(mid,args);
}
public Variant execute(int mid, Variant[] args) {
if (mid < 0) {
return null;
}
Variant rtnv = null;
if (args == null) {
rtnv = oleAutomation.invoke(mid);
} else {
rtnv = oleAutomation.invoke(mid, args);
}
return rtnv;
}
private int getID(String name) {
try {
int[] ids = oleAutomation.getIDsOfNames(new String[] { name });
if(ids == null)
{
return -1;
}
if (ids.length >= 0)
return ids[0];
} catch (RuntimeException e) {
e.printStackTrace();
}
return -1;
}
}
这里面有2个方法,分别是
private int getID(String name)
public Variant execute(String methodName)
他们的作用是什么呢?
getID看名字就知道是获取id的,这个方法里面通过getIDsOfNames方法来获取id
其实这个获取到的值并不是什么id,而是函数在已经加载的内存中的内存地址,因为在java之中并没有内存地址这个概念,所有的内存都由虚拟机管理,所以取名叫id,他的原理是通过一个本地函数库执行获取的
函数原型如下
public static final native int VtblCall
这个函数位于org.eclipse.swt.internal.ole.win32.Com包下面,从名字就可以看出只执行win32的con组件的类库
而execute则是执行指定内存地址的函数
在创建一个java文件,代码如下
package ocx;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.ole.win32.*;
import org.eclipse.swt.widgets.*;
public class JavaOcx {
public static void main(String[] args){
JavaOcx mJavaOcx = new JavaOcx();
try {
mJavaOcx.start();
}catch (Exception e){}
}
OleFrame m_oleVideoFrame;
OleControlSite m_oleControlSite;
Controller m_controller;
Shell m_shell;
Display m_display;
Button m_btnInitDevice;
String m_strDeviceIdx;
Label m_labelInfo;
public void start() throws InterruptedException {
m_strDeviceIdx = "0";
m_display = Display.getDefault();
m_shell = new Shell();
m_shell.setSize(528, 620);
m_shell.setText("Java-OCX示例");
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 1;
gridLayout.makeColumnsEqualWidth = false;
//m_shell.setLayout(gridLayout);
m_shell.setLayout(null);
// 创建OLEFrame
// m_oleVideoFrame = new OleFrame(m_shell, SWT.ON_TOP);// 绑定OCX
m_oleVideoFrame = new OleFrame(m_shell, SWT.Activate);
m_oleControlSite = new OleControlSite(m_oleVideoFrame, SWT.Activate,
"ICAPTUREVIDEOTY.ICaptureVideoCtrlTY.1");
m_oleControlSite.doVerb(OLE.OLEIVERB_SHOW);
m_controller = new Controller(new OleAutomation(m_oleControlSite));
m_oleVideoFrame.setBounds(5, 5, 500, 500);
m_labelInfo = new Label(m_shell, SWT.NONE);
m_labelInfo.setBounds(10, 550, 500, 30);
m_labelInfo.setText("Java-OCX示例");
m_btnInitDevice = new Button(m_shell, SWT.NONE);
m_btnInitDevice.setBounds(10, 510, 80, 30);
m_btnInitDevice.setText("ocx测试");
m_btnInitDevice.addListener(SWT.MouseDown, new Listener(){
public void handleEvent(Event e){
//执行函数
//m_controller.execute("ReleaseDevice");
}
});
m_shell.open();
while (!m_shell.isDisposed()) {
if (!m_display.readAndDispatch())
m_display.sleep();
}
}
}
OleFrame:窗口外套 Shell:桥接类
swt包所有监听事件都是addListener,至于监听什么则由第一个参数决定
我们执行看一下
显示出这么一个窗口
m_controller.execute(String)则可以执行具体的函数,至于执行什么函数就看各种需要了