zoukankan      html  css  js  c++  java
  • 在Web中使用Windows控件

     
     

          最近做的一个Web版的视频会议项目,需要在网页中播放来自远程摄像头采集的实时视频,我们已经有了播放远程实时视频的使用C#编写的windows控件,如何将其嵌入到网页中去了?这需要使用一种古老的技术,ActiveX。

     

    1.将.Net控件转化为ActiveX控件

          首先要做的就是将我们的windows视频播放控件转化为ActiveX控件。先看看我们视频播放控件的定义,其基于OMCS实现,相当简单:

    1. public partial class CameraVideoPlayer : UserControl  
    2.    {  
    3.        private IMultimediaManager multimediaManager;  
    4.        public CameraVideoPlayer()  
    5.        {  
    6.            InitializeComponent();  
    7.        }  
    8.   
    9.        public void Test()  
    10.        {  
    11.            Random ran = new Random();  
    12.            string userID = "bb" + ran.Next(1001,9999).ToString();  
    13.            this.Initialize("223.4.*.*", 9900, userID, "aa01");  
    14.        }  
    15.   
    16.        public void Initialize(string serverIP, int port, string userID, string targetUserID)  
    17.        {  
    18.            try  
    19.            {  
    20.                this.multimediaManager = MultimediaManagerFactory.GetSingleton();  
    21.                this.multimediaManager.Initialize(userID, "", serverIP, port);  
    22.                this.cameraConnector1.BeginConnect(targetUserID);  
    23.            }  
    24.            catch (Exception ee)  
    25.            {  
    26.                MessageBox.Show(ee.Message);  
    27.            }  
    28.   
    29.        }  
    30.      }   
     public partial class CameraVideoPlayer : UserControl
        {
            private IMultimediaManager multimediaManager;
            public CameraVideoPlayer()
            {
                InitializeComponent();
            }
    
            public void Test()
            {
                Random ran = new Random();
                string userID = "bb" + ran.Next(1001,9999).ToString();
                this.Initialize("223.4.*.*", 9900, userID, "aa01");
            }
    
            public void Initialize(string serverIP, int port, string userID, string targetUserID)
            {
                try
                {
                    this.multimediaManager = MultimediaManagerFactory.GetSingleton();
                    this.multimediaManager.Initialize(userID, "", serverIP, port);
                    this.cameraConnector1.BeginConnect(targetUserID);
                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }
    
            }
          } 

            当调用其Initialize方法时,将连接到目标用户的摄像头,并在其内含的cameraConnector1控件上播放视频。这个控件在Windows Form应用程序中工作良好,现在我们一步步来将其转换为ActiveX控件。

    (1)GUID

          ActiveX控件首先是COM组件,COM组件有唯一的GUID。后面我们可以看到,在Web中,需要通过GUID定位并加载已经注册的ActiveX控件。

          如果使用的是VS2010,工具菜单下有个“创建GUID”菜单,点击它可以创建一个新的GUID,然后把其复制作为CameraVideoPlayer的特性:

    1. [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]  
    2. public partial class CameraVideoPlayer : UserControl  
        [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
        public partial class CameraVideoPlayer : UserControl

    (2)实现IObjectSafety接口

          当ActiveX控件在浏览器中调用的时候,往往会出现警告框,提示不安全的控件正在运行。这是由浏览器安全策略所限定的,控件通过实现IObjectSafety接口以向浏览器表明自己是合法的。在项目中增加IObjectSafety接口的定义:

    1. [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]  
    2. public interface IObjectSafety  
    3. {         
    4.     void GetInterfacceSafyOptions(System.Int32 riid,out System.Int32 pdwSupportedOptions,out System.Int32 pdwEnabledOptions);  
    5.   
    6.     void SetInterfaceSafetyOptions(System.Int32 riid, System.Int32 dwOptionsSetMask, System.Int32 dwEnabledOptions);  
    7. }  
        [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IObjectSafety
        {       
            void GetInterfacceSafyOptions(System.Int32 riid,out System.Int32 pdwSupportedOptions,out System.Int32 pdwEnabledOptions);
    
            void SetInterfaceSafetyOptions(System.Int32 riid, System.Int32 dwOptionsSetMask, System.Int32 dwEnabledOptions);
        }
    

          并让CameraVideoPlayer实现这个接口:

    1. [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]  
    2. public partial class CameraVideoPlayer : UserControl, IObjectSafety  
    3. {  
    4.     private IMultimediaManager multimediaManager;  
    5.     public CameraVideoPlayer()  
    6.     {  
    7.         InitializeComponent();  
    8.     }  
    9.   
    10.     public void Test()  
    11.     {  
    12.         Random ran = new Random();  
    13.         string userID = "bb" + ran.Next(1001,9999).ToString();  
    14.         this.Initialize("223.4.180.116", 9900, userID, "aa01");  
    15.     }  
    16.   
    17.     public void Initialize(string serverIP, int port, string userID, string targetUserID)  
    18.     {  
    19.         try  
    20.         {  
    21.             this.multimediaManager = MultimediaManagerFactory.GetSingleton();  
    22.             this.multimediaManager.Initialize(userID, "", serverIP, port);  
    23.             this.cameraConnector1.BeginConnect(targetUserID);  
    24.         }  
    25.         catch (Exception ee)  
    26.         {  
    27.             MessageBox.Show(ee.Message);  
    28.         }  
    29.   
    30.     }  
    31.   
    32.     public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)  
    33.     {  
    34.         pdwSupportedOptions = 1;  
    35.         pdwEnabledOptions = 2;  
    36.     }  
    37.   
    38.     public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)  
    39.     {  
    40.   
    41.     }  
    42. }  
        [Guid("D9906B42-56B3-4B94-B4F9-A767194A382F")]
        public partial class CameraVideoPlayer : UserControl, IObjectSafety
        {
            private IMultimediaManager multimediaManager;
            public CameraVideoPlayer()
            {
                InitializeComponent();
            }
    
            public void Test()
            {
                Random ran = new Random();
                string userID = "bb" + ran.Next(1001,9999).ToString();
                this.Initialize("223.4.180.116", 9900, userID, "aa01");
            }
    
            public void Initialize(string serverIP, int port, string userID, string targetUserID)
            {
                try
                {
                    this.multimediaManager = MultimediaManagerFactory.GetSingleton();
                    this.multimediaManager.Initialize(userID, "", serverIP, port);
                    this.cameraConnector1.BeginConnect(targetUserID);
                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }
    
            }
    
            public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
            {
                pdwSupportedOptions = 1;
                pdwEnabledOptions = 2;
            }
    
            public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
            {
    
            }
        }

          IObjectSafety接口的两个方法的实现都可以采用上面的代码来做。

    (3)程序集设定

            接下来,我们需要对控件的程序集(OMCS_ActiveX)做一个设置,以表明其将作为一个COM组件使用。打开AssemblyInfo.cs文件,首先将ComVisible特性设置为true。其次,增加AllowPartiallyTrustedCallers特性。如下所示:

    1. // 将 ComVisible 设置为 false 使此程序集中的类型  
    2.  // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,  
    3.  // 则将该类型上的 ComVisible 特性设置为 true。  
    4.  [assembly: ComVisible(true)]  
    5. [assembly: AllowPartiallyTrustedCallers()]  
        // 将 ComVisible 设置为 false 使此程序集中的类型
         // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
         // 则将该类型上的 ComVisible 特性设置为 true。
         [assembly: ComVisible(true)]
        [assembly: AllowPartiallyTrustedCallers()]

          最后,在项目属性的“生成”页中,将“为COM互操作注册”的CheckBox勾上。

         

          这样,编译生成的产物中除了OMCS_ActiveX.dll外,还有OMCS_ActiveX.tlb(COM用到的类型库文件)。

     

    2.制作安装程序

          转化后的CameraVideoPlayer ActiveX控件会被部署在IIS服务器上,用户第一次打开网页时,在用户的机器上是不存在这个控件的,所以,需要下载安装并在用户的机器上注册该ActiveX控件。这些可以通过VS自带的制作安装程序的功能来实现,也相当简单。

    (1)在当前解决方案中添加一个新的安装项目。

    (2)将OMCS_ActiveX项目的主输出导入到安装项目的“应用程序文件夹”下面。

         

    (3)修改主输出的文件安装属性中的Register项为vsdrpCOM。

    (4)设置安装项目的项目属性,主要是“安装URL”项,要设置为部署时地址。     

         

    (5)如果需要,将“系统必备”中的一些项目勾上或去掉。

    (6)编译安装项目,将会生成两个文件setup.exe、Setup1.msi。将它们拷贝到网站虚拟目录的根目录下。

    3.Web集成

            现在我们写一个最简单的HTML来试试加载视频播放的ActiveX控件CameraVideoPlayer。如下所示:

    1. <html xmlns="http://www.w3.org/1999/xhtml" >  
    2. <head>  
    3.     <title>摄像头视频播放器测试</title>  
    4. </head>  
    5. <body>  
    6. <form id="form1">  
    7.        <table>  
    8.   <tr>  
    9.    <td align="center">  
    10.     <object id="cameraVideoPlayer"   
    11.     <strongclassid="clsid:{D9906B42-56B3-4B94-B4F9-A767194A382F}" codebase="setup.exe"</strongwidth="320" height="240">   
    12.     </object>  
    13.    </td>  
    14.   </tr>  
    15.   <tr>  
    16.    <td align="center">  
    17.     <input type=button id="Button1" value="连接摄像头" onclick="javascript:doTest()"/>  
    18.   </td>  
    19. </tr>  
    20. </table>   
    21.   
    22. <script type="text/javascript">  
    23. function doTest()  
    24. {  
    25.   var obj = document.getElementById("cameraVideoPlayer");   
    26.   obj.Test();  
    27. }  
    28. </script>  
    29. </form>  
    30.     </body>   
    31. </html>   
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>摄像头视频播放器测试</title>
    </head>
    <body>
    <form id="form1">
           <table>
      <tr>
       <td align="center">
        <object id="cameraVideoPlayer" 
         classid="clsid:{D9906B42-56B3-4B94-B4F9-A767194A382F}" codebase="setup.exe" width="320" height="240"> 
        </object>
       </td>
      </tr>
      <tr>
       <td align="center">
        <input type=button id="Button1" value="连接摄像头" onclick="javascript:doTest()"/>
      </td>
    </tr>
    </table> 
    
    <script type="text/javascript">
    function doTest()
    {
      var obj = document.getElementById("cameraVideoPlayer"); 
      obj.Test();
    }
    </script>
    </form>
        </body> 
    </html> 
    
            注意加粗的部分,说明了两点:

    (1)浏览器是通过GUID来定位ActiveX控件的。

    (2)如果本机不存在目标ActiveX控件,则自动下载codebase属性指示的安装程序进行安装。

            将HTML文件部署好后,第一次打开网页,如下所示:      

         

           运行安装,完成后,页面会刷新,并可以看到ActiveX控件已经成功加载进来了。然后,点击“连接摄像头”按钮,测试一下ActiveX控件是否可以显示远程摄像头采集的视频,如下所示:     

         

             这样,嵌入到网页中的ActiveX控件就像普通的windows控件一样正常运行了:) 

  • 相关阅读:
    Core Animation 文档翻译—附录C(KVC扩展)
    Core Animation 文档翻译—附录B(可动画的属性)
    Core Animation 文档翻译—附录A(Layer样貌相关属性动画)
    Core Animation 文档翻译 (第八篇)—提高动画的性能
    Core Animation 文档翻译 (第七篇)—改变Layer的默认动画
    Core Animation 文档翻译 (第六篇)—高级动画技巧
    Core Animation 文档翻译 (第五篇)—构建Layer的层次结构
    用Markdown快速排版一片文章
    Core Animation 文档翻译 (第四篇)—让Layer的content动画起来
    Core Animation 文档翻译(第三篇)—设置Layer对象
  • 原文地址:https://www.cnblogs.com/Brainpan/p/5761630.html
Copyright © 2011-2022 走看看