• 在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控件一样正常运行了:) 

  • 相关阅读:
    2018-2019-2 20175214 实验四《Android程序设计》实验报告
    20175214 《Java程序设计》第11周学习总结
    2018-2019-2 20175214 实验三《敏捷开发与XP实践》实验报告
    20175214 《Java程序设计》第9周学习总结
    编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能
    20175214 《Java程序设计》第8周学习总结
    2018-2019-2 20175214 实验二《面向对象程序设计》实验报告
    结对编程项目—四则运算 第二周 整体总结
    事物的传播行为
    mysql数据语句
  • 原文地址:https://www.cnblogs.com/Brainpan/p/5761630.html
Copyright © 2020-2023  润新知