OCX 控件开发及解决js获取第三方ocx变参(in/out类型)的方法
由于公司开发的原件用到了第三方的ocx插件,即做二次开发,不幸的是第三方的ocx部分函数是通过变参(通过var声明的参数)返回结果的,在Delphi 中开发可以获取这些结果,但是用js调用第三方插件的时候是无法直接获取这类型的(var声明的返回)结果。无奈之下(没有第三方ocx的源代码,就算有也不好改人家的东西,O(∩_∩)O~),自己写一个ocx控件协助第三方插件一起工作。
一、OCX插件的开发流程
主要是三个步骤:创建activeX library 工程,为工程创建接口 type library, 实现接口;
a)创建activeX工程
new|other|activeX|activeX library
Delphi会自动生成框架代码,直接编译的话就可以得到一个dll文件了,当然这个dll除了看,什么都做不了的;
library Project1;
uses
ComServ,
Project1_TLB in 'Project1_TLB.pas';
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
{$R *.TLB}
{$R *.RES}
begin
end.
如果想编译出来的是ocx文件,在export 上面独立一行加入 {$E ocx} 声明;
b)创建接口
new|other|activeX|type library
然后在接口编辑器设计你自己的接口,例如添加下面提到的getRecordFileName 方法;
需要注意的是,如果传入的是一个对象,而不是简单的数字、字符串类型的时候,接口函数的入参需要设置为variant类型;例如下面提到的传入第三方的ocx对象的时候。
c) 创建implementation
这里就是具体的实现自己定义的接口类了
myOCX.getRecordFileName(thdOCX: OleVariant): WideString; safecall;
var
sFileName: String;
begin
thdOCX.getRecordFileName(sFileName);
result := sFileName;
end;
二、OCX返回out类型参数或指针的解决办法
基本思路是在需要获取第三方ocx通过var参数返回时,将第三方ocx的对象作为参数送到自己写的ocx提供的函数,然后在自己的ocx内部执行第三方ocx的函数,获取结果后,在自己的ocx返回需要的结果;
假设第三方ocx为 thdOCX,自己的OCX为myOCX。
thdOCX有函数 getRecordFileName(var sFileName: WideString):integer; 该函数是通过变参获取文件名的,在js中不能直接执行该函数在变参中获得文件名。
可以用以下办法获取这个文件名,在myOCX中实现方法,
myOCX.getRecordFileName(thdOCX: OleVariant): WideString; safecall;
var
sFileName: String;
begin
thdOCX.getRecordFileName(sFileName);
result := sFileName;
end;
这样就可以通过myOCX.getRecordFileName的返回结果获取文件名了。
对应thdOCX的函数返回的结果是指针类型的情况,这种思路也可以解决。
由于公司开发的原件用到了第三方的ocx插件,即做二次开发,不幸的是第三方的ocx部分函数是通过变参(通过var声明的参数)返回结果的,在Delphi 中开发可以获取这些结果,但是用js调用第三方插件的时候是无法直接获取这类型的(var声明的返回)结果。无奈之下(没有第三方ocx的源代码,就算有也不好改人家的东西,O(∩_∩)O~),自己写一个ocx控件协助第三方插件一起工作。
一、OCX插件的开发流程
主要是三个步骤:创建activeX library 工程,为工程创建接口 type library, 实现接口;
a)创建activeX工程
new|other|activeX|activeX library
Delphi会自动生成框架代码,直接编译的话就可以得到一个dll文件了,当然这个dll除了看,什么都做不了的;
library Project1;
uses
ComServ,
Project1_TLB in 'Project1_TLB.pas';
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
{$R *.TLB}
{$R *.RES}
begin
end.
如果想编译出来的是ocx文件,在export 上面独立一行加入 {$E ocx} 声明;
b)创建接口
new|other|activeX|type library
然后在接口编辑器设计你自己的接口,例如添加下面提到的getRecordFileName 方法;
需要注意的是,如果传入的是一个对象,而不是简单的数字、字符串类型的时候,接口函数的入参需要设置为variant类型;例如下面提到的传入第三方的ocx对象的时候。
c) 创建implementation
这里就是具体的实现自己定义的接口类了
myOCX.getRecordFileName(thdOCX: OleVariant): WideString; safecall;
var
sFileName: String;
begin
thdOCX.getRecordFileName(sFileName);
result := sFileName;
end;
二、OCX返回out类型参数或指针的解决办法
基本思路是在需要获取第三方ocx通过var参数返回时,将第三方ocx的对象作为参数送到自己写的ocx提供的函数,然后在自己的ocx内部执行第三方ocx的函数,获取结果后,在自己的ocx返回需要的结果;
假设第三方ocx为 thdOCX,自己的OCX为myOCX。
thdOCX有函数 getRecordFileName(var sFileName: WideString):integer; 该函数是通过变参获取文件名的,在js中不能直接执行该函数在变参中获得文件名。
可以用以下办法获取这个文件名,在myOCX中实现方法,
myOCX.getRecordFileName(thdOCX: OleVariant): WideString; safecall;
var
sFileName: String;
begin
thdOCX.getRecordFileName(sFileName);
result := sFileName;
end;
这样就可以通过myOCX.getRecordFileName的返回结果获取文件名了。
对应thdOCX的函数返回的结果是指针类型的情况,这种思路也可以解决。