注意事项

在OCX控件中,重写COleControl.IsInvokeAllowed (DISPID)方法,即在控件的CMyNameCtrl中增加一个方法

BOOL CMyNameCtrl::IsInvokeAllowed (DISPID)
    {
       return TRUE;
    }

下面的链接给出了说明




这个错误是由ActiveX结构设计造成的。



程序是可以直接调用OCX中方法的。Ole4.0之后,每次调用控件中的方法,系统会自动检查是否允许调用,即运行COleControl.IsInvokeAllowed (DISPID)



该方法检查控件是否正确的初始化或者是否通过持久存储接口正确加载,如果两个条件有一个满足,即返回TRUE,否则返回FALSE。



当控件在MFC中使用时,很多细节,如初始化,都被过滤了,这样,大多数用户都不会遇到这个问题。但是,当我们从C、C++的dll中调用控件时,不满足上述条件,该方法返回FALSE,这时候再调用任何控件方法,都会出现上述异常。



这种办法显然不行,因为ocx第三方控件是另一家公司提供的。我之后用vs2010建了一个winform 工程,然后导入ocx控件,控件竟然能用,不报错误。所以,我采取了另一种办法,java 调用exe应用程序。


===============================================================================

最近有多位兄弟留言给我询问调用ocx的问题,这个问题我已经解决了,不过不是调用的视频ocx控件,是实现另外一个ocx的调用.(需要注意的是:因为使用ocx,所以服务器只能使用MS系列的)
调用的简单过程如下:

1.下载jacob:http://sourceforge.net/projects/jacob-project/files/jacob-project/1.15-M4/;
2.将jacob-1.15-M4包中的jacob-1.15-M4-x86.dll复制到系统环境变量中,我放在sytem32目录中;(官方说:在x64位系统时,copy jacob-1.15-M4-x64.dll至syswow64目录,不过我尝试后发现在x64位系统中仍然还是使用jacob-1.15-M4-x86.dll有效);
3.copy需要调用的ocx到系统环境变量中,我放在system32目录中,并且注册ocx控件,注意:注册你的ocx时需要注意此ocx有木有依赖其它的文件,比如我的ocx厂家就需要一个.lic文件与ocx在同一目录;
复制和注册过程可以自己写一个批处理(.bat),我的批处理如下:

@echo off
@echo 注册控件(32位系统)
set sys=%windir%\system32
copy jacob-1.15-M4-x86.dll %sys%
copy *****.ocx %sys%
copy *****.lic %sys%

c:
cd\
cd %sys%
regsvr32 /s *****.ocx

4.项目中导入jacob.jar包;
5.使用jacob api调用ocx;
Demo:

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class JacobDemo
{
	private static ActiveXComponent activeX;//ActiveX控件对象
	private static Dispatch dispath;//MS级别的调度对象
		
	static
	{
		//创建ActiveX控件对象
		//可以使用CLSID,也可以使用ProgID
		activeX = new ActiveXComponent("CLSID:A71B53F3-562C-451E-9F92-DCF5B8852B6E");
		//获得调度对象
		dispath = activeX.getObject();
	}
	
	/**
	 * 登陆110报警服务器
	 * @param ip ip地址
	 * @param port 端口号
	 * @param clientType 客户端类别
	 * @param loginName 登陆中心名称,格式为:(分中心名称:操作员代码:操作员名称)
	 * @return -1:登陆失败;0 开始登陆;1,2 已登陆 ; 3,4 登陆中
	 */
	public int loginSvr(String ip,String port,int clientType,String loginName)
	{	
		//登陆后返回值(默认为-1)
		int result=-1;
	    if(!ip.isEmpty()&&!port.isEmpty())
	    {	    	
	    	//尝试登陆5次,每间隔1秒一次
	    	for(int i=0;i<5;i++)
	    	{
	    		System.out.println("尝试第"+(i+1)+"次登陆.");
	    		//调用控件的登陆函数
	    		Variant loginVar =Dispatch.call(dispath, "Login", ip,port,clientType,loginName);
			    //给结果赋值
			    result= loginVar.getInt();
			    //如果登陆成功,跳出循环
			    if(result==1||result==2)
			    {
			    	break;
			    }
			    else
			    {
			    	//线程休眠1秒
			    	try
					{
						Thread.sleep(1*1000);
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
			    }
	    	}
	    }	    
	    return result;
	}
	
	public static void main(String[] args)
	{
		JacobDemo demo = new JacobDemo();
		int result = demo.loginSvr("192.168.1.174", "6986", 0x1000000, "江苏明道保全报警中心:mingdao:mingdao");
		if(result==1||result==2)
		{
			System.out.println("登陆成功!");
		}
	}
}

6.如果需要知道你的ocx控件注册后的CLSID,可以在注册表中搜索得出:
假设我的控件名称是abc.ocx,
打开注册表:运行regedit
Ctrl+F打开查找对话框,查找abc.ocx,会展开一个目录类似:{A71B53F3-562C-451E-9F92-DCF5B8852B6E}
这个目录名即是CLSID.




注意事项

在OCX控件中,重写COleControl.IsInvokeAllowed (DISPID)方法,即在控件的CMyNameCtrl中增加一个方法
BOOL CMyNameCtrl::IsInvokeAllowed (DISPID)
   {
      return TRUE;
   }

下面的链接给出了说明




这个错误是由ActiveX结构设计造成的。



程序是可以直接调用OCX中方法的。Ole4.0之后,每次调用控件中的方法,系统会自动检查是否允许调用,即运行COleControl.IsInvokeAllowed (DISPID)



该方法检查控件是否正确的初始化或者是否通过持久存储接口正确加载,如果两个条件有一个满足,即返回TRUE,否则返回FALSE。



当控件在MFC中使用时,很多细节,如初始化,都被过滤了,这样,大多数用户都不会遇到这个问题。但是,当我们从C、C++的dll中调用控件时,不满足上述条件,该方法返回FALSE,这时候再调用任何控件方法,都会出现上述异常。



这种办法显然不行,因为ocx第三方控件是另一家公司提供的。我之后用vs2010建了一个winform 工程,然后导入ocx控件,控件竟然能用,不报错误。所以,我采取了另一种办法,java 调用exe应用程序。


===============================================================================

最近有多位兄弟留言给我询问调用ocx的问题,这个问题我已经解决了,不过不是调用的视频ocx控件,是实现另外一个ocx的调用.(需要注意的是:因为使用ocx,所以服务器只能使用MS系列的)
调用的简单过程如下:

1.下载jacob:http://sourceforge.net/projects/jacob-project/files/jacob-project/1.15-M4/;
2.将jacob-1.15-M4包中的jacob-1.15-M4-x86.dll复制到系统环境变量中,我放在sytem32目录中;(官方说:在x64位系统时,copy jacob-1.15-M4-x64.dll至syswow64目录,不过我尝试后发现在x64位系统中仍然还是使用jacob-1.15-M4-x86.dll有效);
3.copy需要调用的ocx到系统环境变量中,我放在system32目录中,并且注册ocx控件,注意:注册你的ocx时需要注意此ocx有木有依赖其它的文件,比如我的ocx厂家就需要一个.lic文件与ocx在同一目录;
复制和注册过程可以自己写一个批处理(.bat),我的批处理如下:

@echo off
@echo 注册控件(32位系统)
set sys=%windir%\system32
copy jacob-1.15-M4-x86.dll %sys%
copy *****.ocx %sys%
copy *****.lic %sys%

c:
cd\
cd %sys%
regsvr32 /s *****.ocx

4.项目中导入jacob.jar包;
5.使用jacob api调用ocx;
Demo:

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class JacobDemo
{
	private static ActiveXComponent activeX;//ActiveX控件对象
	private static Dispatch dispath;//MS级别的调度对象
		
	static
	{
		//创建ActiveX控件对象
		//可以使用CLSID,也可以使用ProgID
		activeX = new ActiveXComponent("CLSID:A71B53F3-562C-451E-9F92-DCF5B8852B6E");
		//获得调度对象
		dispath = activeX.getObject();
	}
	
	/**
	 * 登陆110报警服务器
	 * @param ip ip地址
	 * @param port 端口号
	 * @param clientType 客户端类别
	 * @param loginName 登陆中心名称,格式为:(分中心名称:操作员代码:操作员名称)
	 * @return -1:登陆失败;0 开始登陆;1,2 已登陆 ; 3,4 登陆中
	 */
	public int loginSvr(String ip,String port,int clientType,String loginName)
	{	
		//登陆后返回值(默认为-1)
		int result=-1;
	    if(!ip.isEmpty()&&!port.isEmpty())
	    {	    	
	    	//尝试登陆5次,每间隔1秒一次
	    	for(int i=0;i<5;i++)
	    	{
	    		System.out.println("尝试第"+(i+1)+"次登陆.");
	    		//调用控件的登陆函数
	    		Variant loginVar =Dispatch.call(dispath, "Login", ip,port,clientType,loginName);
			    //给结果赋值
			    result= loginVar.getInt();
			    //如果登陆成功,跳出循环
			    if(result==1||result==2)
			    {
			    	break;
			    }
			    else
			    {
			    	//线程休眠1秒
			    	try
					{
						Thread.sleep(1*1000);
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
			    }
	    	}
	    }	    
	    return result;
	}
	
	public static void main(String[] args)
	{
		JacobDemo demo = new JacobDemo();
		int result = demo.loginSvr("192.168.1.174", "6986", 0x1000000, "江苏明道保全报警中心:mingdao:mingdao");
		if(result==1||result==2)
		{
			System.out.println("登陆成功!");
		}
	}
}

6.如果需要知道你的ocx控件注册后的CLSID,可以在注册表中搜索得出:
假设我的控件名称是abc.ocx,
打开注册表:运行regedit
Ctrl+F打开查找对话框,查找abc.ocx,会展开一个目录类似:{A71B53F3-562C-451E-9F92-DCF5B8852B6E}
这个目录名即是CLSID.