可以/如何在C#WPF应用程序中托管完整的VB6表单?

时间:2010-02-10 19:49:31

标签: c# wpf vb6 vb6-migration interop

我目前正在探索使用C#将一些旧的VB6应用程序移植到WPF的选项。第一阶段的计划是移植几个关键形式而不是所有应用程序。理论上的目标是通过ActiveX DLL在WPF中的某种容器中打开VB6表单。

这甚至可能吗? 我试过看Interop并且似乎找不到一个可靠的例子,说明如何使用Win32控件,而不是完整的表单。我可以完全访问旧的VB6代码,并且无论如何都可以修改它。

主WPF应用程序的以下屏幕截图将用作包装器/容器:

http://www.evocommand.com/junk_delete_me/main_menu_mockup.png

当前VB6维护屏幕将加载到上一屏幕右侧的“空白区域”部分。

5 个答案:

答案 0 :(得分:11)

我能够通过以下步骤完成任务:

  1. 创建了一个新的VB6 Active X Control项目。将VB6表单控件和代码的全部内容复制并粘贴到新控件中。切换到控件时必须处理几个元素:

    1. 你失去了显示能力 形式的标题 以前的方式。你可以解决 它与备用控件 (label / borderlesstextbox等) 如果完成相同的功能 需要。这不是优先事项 每个屏幕都被托管在一个 像我们新的标签系统的浏览器 .Net项目。

    2. 所有鼠标指针必须参考 从Me.Mousepointer改为 Screen.mousepointer

    3. 你不能使用Me.Hide而且必须这样做 用于隐藏.Net的备用事件 容器

    4. 任何和所有引用 我。[任何]必须被删除或 用UserControl替换。[任何] 如果它们适用。

    5. 如果您使用任何功能 参考a [yourcontrol] .Contianer.Property on a 形式他们将需要改变 循环通过UserControl.Controls 相反,集合和“容器”是 对于vb6 ActiveX控件无效

    6. 所有非模态表单/对话框 必须从项目中删除 现在WPF中没有Hwnd可以处理。 您收到“非模态表单”错误 无法在此主机中显示 来自ActiveX DLL的应用程序, ActiveX控件或属性页'。 在我们的例子中,我们有一个简单的启发 屏幕会在确定时显示 显示的长进程/报告 让用户知道正在运行的是什么。

  2. 我无法通过互操作直接将VB6控件添加到WPF项目中。因此,创建了一个新的.Net“Windows窗体控制库”项目。项目中添加了对VB6 OCX的引用。然后通过“右键单击”将VB6控件添加到.Net工具箱中 - > “添加项目”并将com引用指向VB6控件ocx。然后使用.Net控件来托管/提供VB6控件。

  3. 要在VB6中显示主机表单并使其启动必要的初始化功能,VB6 OCX控件将以Visible.False方式进行默认,因此它们最初作为不可见控件添加到.Net OCX中。需要时,VB6控件设置为visible = True,触发UserControl_Show()事件。之前在Form_Load()中的所有代码都已移至此事件。 show事件是根据需要访问Form_Load的最简单方法。 MSDN:“如果窗体被隐藏然后再次显示,或者窗体最小化然后恢复,则控件不会收到Show事件。在这些操作期间,控件的窗口仍保留在窗体上,其Visible属性不会更改。“

  4. 在.Net Winform控件中包装vb6控件解决了无线电/选项按钮呈现为黑色的问题,如我对此问题的一个回答中所述,而无需按照建议将帧转换为图片框。

  5. 在WPF应用程序中,选择菜单选项时,xaml代码将通过带有WindowsFormsHost标记的包装器动态创建和显示。然后,来自.Net winform应用程序的动态创建的控制对象被推送到xaml上的WindowsFormsHost标记中,并且该控件在.net项目上可见,该项目将触发vb6 UserControl_Show,然后加载并显示vb6表单。

答案 1 :(得分:3)

我认为您需要做的是将VB6表单内容解压缩到ActiveX控件中。然后,您可以在ActiveX dll中公开它并将其放在WPF表单中。我怀疑在任何其他类型的表单中托管VB6表单是可能的。

答案 2 :(得分:1)

你甚至可以在另一个VB6表单中加载VB6表单吗?我建议你先做好准备。

答案 3 :(得分:0)

没有可靠的方法来设置VB6表单的父级。您可以随时破解它或使用普通的ActiveX控件(VB6中的UserControl)作为UI容器而不是VB6表单。

答案 4 :(得分:0)

我发现了一种方法,可以在WinForms中执行所需的操作,而不是WPF。 http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx 我想如果我可以100%在那里工作,我可以将它移植到WPF或者更糟糕的情况下,如果我绝对拥有WPF格式的WinForm元素( U-G-L-Y )。

无论如何,我已经离得更近一点了,但是对于某些控件也有一个非常奇怪的问题。 Radio / Option按钮呈现为纯黑色:

http://www.evocommand.com/junk_delete_me/optionbuttons.png

我已经尝试将控件的背景颜色从按钮面更改为固定颜色,但仍然可以。我假设这是一个分层问题,选项按钮在框架控件内。如果不对VB6内容进行大量修改以将选项按钮更改为复选框,我将无法继续进行操作。这是一个沉重的应用程序,应用程序中有600多个选项按钮控件,我并不想完全处理。

编辑: 我能够确认它与Frame控件中的选项分层有关。如果拉出到基本形式,则不会发生问题: http://www.evocommand.com/junk_delete_me/optionbuttons2.png