最近公司在做一个项目中有需要调用远程视频监控的部分。
远程的视频服务器是由第三方公司开发的,他们提供了ocx控件用于做开发调用。在Javascript已经实现调用,远程视频可以调用出来。
但是在js中调用,每台客户机就都得下载安装ocx控件(当然这样也可以)。想要实现的是在服务器端安装ocx控件,由服务器端的java后台程序去调用ocx控件对远端视频服务器进行操作,
这样客户端机器上就不用每台机器都安装ocx控件了。(想法是这样的)如是开始寻找java中调用ocx控件的办法方法,jni、jacob....但是试验下来发现调用像word、excel这些ActiveX控件是可以的,操作没有问题,换作视频的ocx控件就不能调用了。
请各位来帮忙解决解决。JavaScript下调用的代码如下:(这种方式是Ok的)<HTML>
<HEAD>
<TITLE>视频调用</TITLE>
<script language="javascript" for="NVS5000" event="OnLoginNVSResult(nResult)">
//ocx对象的OnLoginNVSResult事件触发时
OnLoginNVS(nResult);
</script>
<script type="text/javascript" language="javascript">
function $() 
{
  var elements = new Array();
  for (var i = 0; i < arguments.length; i++) 
  {
    var element = arguments[i];
    if (typeof element == 'string')
    {
      element = document.getElementById(element);
    }
    if (arguments.length == 1)
    {
      return element;
    }
    elements.push(element);
  }
  return elements;
}
//初始化方法
function init()
{
  try{
//为ocx对象属性赋值
$("NVS5000").URL       = "192.168.15.153"; //前端设备地址
$("NVS5000").Port      = 5200; //端口号
$("NVS5000").NVSName = "NVS";
$("NVS5000").UserName  = "admin"; //用户名
$("NVS5000").UserPswd  = "admin"; //密码
$("NVS5000").SetLoginMode(1); //设置登录模式
$("NVS5000").Tips_Off();
$("NVS5000").AlarmBox_Off();
$("NVS5000").FullWnd_Off();
$("NVS5000").SocketProtocol=0; //设置套接字协议
$("NVS5000").ChannelNum= 0; //频道号

//登录前端设备
$("NVS5000").LoginNVS();
//浏览器状态显示
window.status = $("NVS5000").URL+":"+$("NVS5000").Port+" , Account:"+$("NVS5000").UserName+"/"+$("NVS5000").UserPswd;
  }catch(e){}
}
//登录时触发方法
function OnLoginNVS(nResult)
{
  try{
if(nResult < 2)
{
  switch(nResult)
  {
case -1:
window.status = " 操作失败!";
break;
case -2:
window.status = " 请求被拒绝!";
break;
case -3:
window.status = " 登录用户已满!";
break;
case -4:
window.status = " 用户名或密码和系统不匹配!";
break;
case -5:
window.status = " 已经关闭IE!";
break;
case -6:
window.status = " 连接DDNS失败!";
break;
case -7:
window.status = " 获取设备信息失败!";
break;
default:
window.status = " 其他未知错误! " + nResult;
break;
  }
  return false;
}else{
//启动视频
$("NVS5000").StartView();
}
  }catch(e){}
}
</script></HEAD>
<BODY onLoad="init()">
<object name="NVS5000" ID="NVS5000" width="705" height="570"
    CLASSID="CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A">
</object>
</BODY>
</HTML>
尝试在Java下使用jacob调用的代码如下:package com.mdbq.jni;import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class XDViewDemo
{
public static void main(String[] args)
{
//初始化线程
ComThread.InitSTA();

ActiveXComponent activeX = new ActiveXComponent("CLSID:08353A15-031B-4FE1-9BF5-5B4F721BA61A");
Dispatch NVS5000 = (Dispatch)activeX.getObject();

Variant result = Dispatch.call(NVS5000,"LoginNVS","");

//释放线程
ComThread.Release();
}
}
出错语句在:Variant result = Dispatch.call(NVS5000,"LoginNVS","");
(只要是调用ocx的方法就会出错。)eclipse控制台下的错误如下:Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: LoginNVS
Description: 灾难性故障 at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:858)
at com.jacob.com.Dispatch.callN(Dispatch.java:455)
at com.jacob.com.Dispatch.call(Dispatch.java:544)
at com.mdbq.jni.XDViewDemo.main(XDViewDemo.java:18)
请各位大大帮忙看看是什么问题?

解决方案 »

  1.   

    http://topic.csdn.net/t/20050826/17/4233746.html看看这个
      

  2.   

    用jacob操作word和Excel已经尝试过了,是成功的。我主要是要用jacob来操作第三方提供的这个ocx控件,
    但是操作失败,不太明白。ocx控件在系统中已经注册,用js是可以操作成功的。在想,有没有可能是使用jacob来操作的ocx必须是使用某种语言开发的。想想也不应该啊。
      

  3.   

    OCX是vb的控件么 本人理解这种东西类似 dll 应该不会需要固定的语言去调用 里面封装各种处理方法 规定了调用的数据格式和返回的数据格式 至于操作失败 要自己找找原因 多打印一些数据 看看 ocx的帮助文档 如果需要和ocx的客服研究一下 
      

  4.   

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

  5.   

    最近有多位兄弟留言给我询问调用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 *****.ocx4.项目中导入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.大致过程就是这样,如果有需要后续再写博文给大伙分享.
      

  6.   

    楼主,你的调用视频ocx的功能实现了吗?求指导啊!顺便再问一个问题哦,如果在后台用java能够调用成功,那个视频播放界面在哪展现呢