7

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

这甚至可能吗?我试过查看 Interop,似乎找不到一个可靠的例子来说明如何让它与除 Win32 控件之外的任何东西一起工作,而不是完整的形式。我可以完全访问旧的 VB6 代码,并且可以根据需要对其进行修改。

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

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

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

4

5 回答 5

12

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

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

    1. 您将失去以先前方式显示表单标题的能力。如果需要,您可以使用完成相同功能的替代控件(标签/无边框文本框等)来解决它。这不是优先事项,因为在我们的新 .Net 项目中,每个屏幕都托管在类似标签系统的浏览器中。

    2. 所有鼠标指针引用都必须从 Me.Mousepointer 更改为 Screen.mousepointer

    3. 您不能使用 Me.Hide 并且必须交替事件来隐藏 .Net 容器。

    4. 对 Me.[anything] 的任何和所有引用都必须删除或替换为 UserControl.[anything](如果适用)。

    5. 如果您在表单上使用任何引用 [yourcontrol].Contianer.Property 的函数,则需要更改它们以循环通过 UserControl.Controls 集合,并且“容器”对于 vb6 ActiveX 控件无效

    6. 必须从项目中删除所有非模态表单/对话框,因为现在 WPF 中没有要处理的 Hwnd。您会收到“非模式表单无法从 ActiveX DLL、ActiveX 控件或属性页显示在此主机应用程序中”的错误。在我们的例子中,我们有一个简单的闪屏,当显示某些长进程/报告时会显示它,让用户知道正在运行什么。

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

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

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

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

于 2010-02-25T23:14:51.510 回答
3

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

于 2010-02-10T23:19:53.297 回答
1

您甚至可以在另一个 VB6 表单中加载该 VB6 表单吗?我建议你先让它工作。

于 2010-02-10T19:54:00.287 回答
0

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

于 2010-02-10T23:00:02.687 回答
0

在这一点上,我找到了一种在 WinForms 而不是 WPF 中执行所需操作的方法。 http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx 我想如果我可以让它 100% 工作,我可以将它移植到 WPF 或更糟糕的情况下,如果我在 WPF 表单中托管 WinForm 元素绝对有(丑陋)。

无论如何,我已经接近了一点,但是在某些控件也绘制屏幕时遇到了一个非常奇怪的问题。单选/选项按钮呈现为纯黑色:

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

我已经尝试将控件的背景颜色从按钮面显式更改为固定颜色,但它仍然可以。我假设这是一个分层问题,选项按钮位于框架控件内。我对如何在不对 VB6 内容进行大量返工以将选项按钮更改为复选框的情况下进行操作有点茫然。这是一个庞大的应用程序,整个应用程序中有 600 多个选项按钮控件,我并不想处理这些控件。

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

于 2010-02-12T20:07:16.570 回答