.NET应用程序中嵌入VB6表单

介绍 一般来说,可用的工具,. net代码和VB6代码之间提供互操作是基于代理,包装或其他形式的中间件,使VB6调用。net Winforms应用程序。到目前为止,我们还没有看到一个解决方案,允许我们做相反的事情。也就是说,在. net应用程序中嵌入VB6形式。因此,我们决定创建我们自己的解决方案。在MasterSoft,我们有许多应用程序开发的Visual Basic 6我们投资发展数千小时。现在我们面临移植到。net的必要性以循序渐进的方式,用最少的努力。 为了达到这一目标,我们设想一种VB6和. net间的互操作,允许我们在. net应用程序中打开VB6形式。这将给我们的机会逐渐迁移的应用程序,将新功能与“本地”。net代码和维护完整或尽可能完整的一切用VB6编写的。这一战略的主要优势是在利用一个。net框架由自己开发,这给了我们菜单设计和安全管理的强大工具,在许多其他的事情。所有这些好处将丢失,如果我们保持我们的应用程序的核心在VB6。 我们应用的解决方案是基于。net MDI环境我们可以打开VB6的形式包含在一个DLL,就好像他们是MDI的孩子。net的形式。而不是使用工具包或权力包.NET-VB6互操作,我们使用. net实例容器形式我们嵌入VB6形式。通过使用API函数,模拟嵌入式的正常行为形式。 实现细节 使用VB6形式从. net应用程序中,我们选择开发一个“壳”(容器)形式在VB。净与MDI子功能。这将创建一个VB6形式通过一个特定类的实例在DLL ActiveX, ClsForms。使用API函数和沟通的DLL, VB6表单实例化和嵌入式的容器。 在VB6 DLL中,有一个公共类实例化的工作形式与. net应用程序和沟通。该类充当控制器实例化形式的DLL。它提供了访问他们通过一些方法帮助容器像VB6形式会在VB6 MDI容器。由于VB6的形式驻留在一个DLL ActiveX,我们需要确保他们的MDIChild属性设置为False,因为我们不知道如何改变,在运行时属性。为了管理VB6的活动形式,. net容器使用一个计时器控制经常查询的VB6类来处理消息。 我们需要解决一个大问题是VB6之间的通信形式。在许多情况下,我们的应用程序形式相互调用,传递参数和结果的搜索,例如,它们之间通过属性。为了保持这种行为在VB6 . net应用程序与形式,有必要让VB6形式创建新实例的容器和嵌入其他VB6形式。这是做如下解释。 显示顺序 让事情更封装,我们开发一个FormController类在. net项目维护的实例DLL并创建多个实例的. net容器。因此,我们可以打开ClsForms的多种形式使用相同的实例。

'We instantiate FormController by passing 
'the MDI form and the Dll ActiveX name
Dim objFormController As New FormController(objMDIForm, "FormsVB6")

'then we just call the OpenForm function passing the VB6 form name
objFormController.OpenForm("frmChildForm")

显示对象之间的相互作用,最好的方法就是用这个UML序列图: FormController OpenForm功能创建ActiveX DLL中的ClsForms类的一个实例——一个包含所有VB6的形式——然后实例化frmContainer形式。最后,它调用OpenForm方法。容器中的OpenForm方法在ClsForms反过来调用OpenForm方法。它以表单的名称创建一个新的实例,通过论证使用隐藏VB6 Forms.Add (formname)指令。 创建表单实例时,OpenForm方法返回实例的处理容器。处理和通过API函数,以及通过ClsForms类的其他方法,VB6形式是“画”在。net容器。VB6 OpenForm容器获得属性值的形式如标题,宽度,高度,等为了复制他们的容器,即GetWindowTitle在上面的图中。容器形式还负责检查其嵌入形式的状态。通过这种方式,它可以知道VB6形式已经被卸载我关闭指令,从而可以关闭容器。 形式的行为 为了模拟的事件触发VB6形式,容器使用一个计时器控制不断检查是否有事件VB6形式,需要处理。我们可以选择通过事件直接从VB6 . net应用程序,但这将im对表单代码进行了更深入的修改,这正是我们想要避免的。 要使VB6表单能够打开“子”非模态表单并保持其MDIChild条件,有必要使用VB6中的ShowForm函数而不是通常的. show方法。ShowForm函数执行将. net环境中被调用的子窗体保存在其容器中的所有过程。为了将VB6表单嵌入到。net容器中,基本上所有的工作都已经完成了。

'Opens a new child form
ShowForm(frmChildForm, True)

'Opens a new modal form
ShowForm(frmModalForm, False)

因此,我们只需要将代码中的Show调用替换为ShowForm(),传递我们想要显示的表单和第二个布尔参数,该参数指示是否希望它是MDI子元素。如果是,则通过向容器传递消息“OpenForm”来调用该容器中的OpenForm。如果没有,它只是将表单作为常规模态表单打开。 保护的正常行为VB6形式和各自的容器MDI子形式——例如,参见右图的正常使用,重点改变形式或. net MDI的形式这一事实之间保持积极开放其他。net或VB6形式——我们需要使用各种API函数,像SendMessage窗体提前和LockWindow。 为了增强这种技术,我们计划向. net MDI表单和容器之间的中间类添加代码。这将允许从VB6触发影响。net环境的事件。例如修改MDI表单的标题属性,打开。net“原生”表单,等等。 参考文献 我们使用Stephen Kent的一个函数在运行时改变表单边界样式。 使用的代码 代码非常简单,并且在我认为需要的地方注释。我们没有使用高级编程技术,只有几个API调用来完成“魔术”。 结论 . net和VB6之间的这种互操作方式允许我们为我们的应用程序开始一个逐步迁移到. net的路径,而不会强迫我们立即对它们进行修改。它还立即将我们开发的。net框架的许多优点添加到应用程序中。作为附加特性,这种逐步迁移路径允许最终用户逐步学习如何使用. net版本的应用程序提供的新特性,而不必被迫一次学习所有的更改。 特别感谢MasterSoft公司的Gustavo Du Mortier和Mariano Aranda;他们真的很有帮助和配合。 历史 2007年7月12日——文章编辑并移至主CodeProject.com文章库 本文转载于:http://www.diyabc.com/frontweb/news2218.html

原文地址:https://www.cnblogs.com/Dincat/p/13457326.html