项目需求:复用原来已有的一个ACTIVEX控件到ECLIPSE 插件开发的产品环境中
问题:activeX控件嵌入swt;他们之间的交互通信
解决:
1.嵌入可以用org.eclipse.swt.ole.win32包中的OleFrame,OleControlSite,OleAutomation,来解决。具体代码如下:
/******************************************************************/
public abstract class ActiveXControl extends Composite {
protected OleControlSite site;
protected OleAutomation auto;
/**
* @param parent
* @param style
* @param progId
*/
public ActiveXControl(Composite parent, int style, String progId) {
super(parent, SWT.NONE);
setLayout(new GridLayout());
OleFrame frame = new OleFrame(this, SWT.NONE);
frame.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 0, 0));
try {
site = new OleControlSite(frame, SWT.NONE, progId);
} catch (RuntimeException e) {
System.out.println(String.format("ActiveX初始化异常", progId));
throw e;
}
auto = new OleAutomation(site);
site.doVerb(OLE.OLEIVERB_SHOW);
}
protected Variant invoke(String methodName, Variant[] args) {
int methodId = auto.getIDsOfNames(new String[] { methodName })[0];
return auto.invoke(methodId, args);
}
}
其中的progId是activeX控件的ProgID.可以用例如COM Explorer之类软件得到
/******************************************************************/
2.交互通信
(1)swt主动调用activeX方法
用1中的方法invoke(控件方法名,控件方法参数)即可
(2)activeX调用swt中内容
A.由于ACTIVEX不能直接调用swt中内容。只能间接实现思路是用swt来监听activex的事件。如果activex触发了相应具体
事件。swt就可监听到。并得到activex控件事件参数进行相应处理。在监听处理过程中activex线程是阻塞的,直到监听方法
返回。activex的线程才会继续进行。这就可以帮助我们实现swt中进行相应处理得到的结果数据传递到activex后。activex线程
才会继续进行下去。才可以使用传回数据而不出异常。
B.如何传回数据
在activex控件中自定义一个事件比如getSwtData(传递给swt的参数),这个自定义事件会分配一个dispId,这个dispId就是关键。在swt中可以对dispId进行监听。当activex控件中调用此事件的时候。swt即可监听到。也就是说在你想用swt处理数据的
地方fire一下这个事件即可。swt中代码如下:
/**
* 监听activex控件的事件。通过eventid监听。
* eventid在delphi中即dispId,
* 此调用会阻塞控件中相应事件直到此方法结束
* */
site.addEventListener(dispId, new OleListener(){
@Override
public void handleEvent(OleEvent event) {
此时event.arguments即为getSwtData(传递给swt的参数)中的参数;
进行相应处理处理
}
});
处理结果返回方式:在activex控件中自定义一个属性接口。此属性接口也会有一个相应的dispId,只要在swt中处理完
后把结果集写入到此activex属性中。swt监听事件返回后。在activex中就可以访问此属性值了。swt具体代码如下:
/**向数据共享区属性中赋值,供activex控件使用*/
auto.setProperty(属性dispId,new Variant (sData));
/**************************************************/
以上就是关于这个问题的解决方法。别的方式暂时没有想到。大家还有什么新的思路可以一起来讨论