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

发布于 2024-08-21 04:51:01 字数 472 浏览 6 评论 0原文

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

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

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

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

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

I am currently exploring the option of porting some older VB6 application to WPF with C#. The plan, in phase one, is to port several key forms and not all the application. The theoretical goal is to open the VB6 form in a container of some sort within WPF via an ActiveX dll.

Is this even possible?
I've tried looking at the Interop and can't seem to find a solid example of how get it to work with anything but Win32 controls, not a full form. I have full access to the old VB6 code and can modify it in anyway needed.

The following screenshot of the main WPF app would serve as the wrapper/container:

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

The current VB6 maintenance screen that would be loaded in the “white space” section on the right side of the previous screen.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

流星番茄 2024-08-28 04:51:01

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

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

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

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

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

    4. 任何及所有引用
      我。[任何东西]都必须被删除或者
      替换为 UserControl。[任何内容]
      如果适用的话。

    5. 如果您使用任何以下功能
      参考一
      [yourcontrol].Contianer.Property 上
      他们需要更改为
      循环遍历 UserControl.Controls
      集合代替,“容器”是
      对于 vb6 ActiveX 控件无效

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

  2. 我无法通过互操作直接将 VB6 控件添加到 WPF 项目中。这样一个新的.Net“Windows Form Control Library”项目就创建了。对 VB6 OCX 的引用已添加到项目中。然后通过“右键”->将VB6 Control添加到.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. 将 vb6 控件包装在 .Net Winform 控件中解决了单选/选项按钮呈现为黑色的问题,如我对此问题的回答之一中其他地方概述的那样,而无需按照建议将框架转换为图片框。

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

I was able to accomplish the task with the following steps:

  1. Created a new VB6 Active X Control Project. Copied and pasted the entire contents of the VB6 form controls and code behind into the new control. There are several elements that have to be handled in switching to a control:

    1. you lose the ability to display
      the caption of the form in the
      previous manner. You can work around
      it with alternate controls
      (label/borderlesstextbox, etc) that
      accomplish the same functionality if
      needed. This wasn’t a priority since
      each screen was being hosted in a
      browser like tab system in our new
      .Net project.

    2. All mousepointer references have to
      be changed from Me.Mousepointer to
      Screen.mousepointer

    3. You cannot use Me.Hide and have to
      alternate events to hide the .Net
      container.

    4. Any and all references to
      Me.[anything] have to be removed or
      replaced with UserControl.[anything]
      if they are applicable.

    5. If you use any functions that
      reference a
      [yourcontrol].Contianer.Property on a
      form they will need to be altered to
      loop through the UserControl.Controls
      collection instead and “Container” is
      invalid for vb6 ActiveX controls

    6. All non-modal forms/dialog boxes
      must be removed from the project as
      there is now no Hwnd to handle in WPF.
      You get an error of 'Non-modal forms
      cannot be displayed in this host
      application from an ActiveX DLL,
      ActiveX Control, or Property page'.
      In our case we had a simple splash
      screen that would display when certain
      long processes/reports displayed to
      let the user know what was running.

  2. I was unable to directly add the VB6 control via the interop to a WPF project . As such a new .Net “Windows Form Control Library” project was created. A reference to the VB6 OCX was added to the project. The VB6 Control s were then added to the .Net toolbox by “right click” –> “Add Item” and pointing a com reference to the VB6 control ocx. The .Net control was then used to host/serve the VB6 Control.

  3. To display host a form in the VB6 and get it to fire the necessary initialization functionality the VB6 OCX controls were defaulted in a Visible.False manner so they were initially added to the .Net OCX as invisible controls. When needed the VB6 control is set to visible = True which fires the UserControl_Show() event. All code formerly in Form_Load() was moved to this event. The show event was the easiest method of accessing the Form_Load as needed. MSDN: “The control does not receive Show events if the form is hidden and then shown again, or if the form is minimized and then restored. The control’s window remains on the form during these operations, and its Visible property doesn’t change.”

  4. Wrapping the vb6 controls within a .Net Winform control resolved the issue with Radio/Option buttons being rendered as black as outlined elsewhere in one of my responses to this question without having to convert the frames to Picture boxes as suggested.

  5. In the WPF app as a menu choice is selected xaml code is dynamically created and displayed via a wrapper with a WindowsFormsHost tag. A dynamically created control object from the .Net winform app is then pushed into the WindowsFormsHost tag on the xaml and the control is made visible on the .net project which fires vb6 UserControl_Show and then load and display of the vb6 form.

怪异←思 2024-08-28 04:51:01

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

I think what you will have to do is extract the VB6 form contents into an ActiveX control. You can then expose this in your ActiveX dll and place that in your WPF form. I doubt it's possible to host a VB6 form within any other type of form.

你与昨日 2024-08-28 04:51:01

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

Can you even load that VB6 form in another VB6 form? I suggest you get that working first.

╭ゆ眷念 2024-08-28 04:51:01

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

There is no reliable way to set parent of a VB6 form. You can always hack it or use plain ActiveX control (UserControl in VB6) as UI container instead of VB6 forms.

抚你发端 2024-08-28 04:51:01

此时,我找到了一种方法可以在 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 多个选项按钮控件,但我并不想处理它们。

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

I found a method to do what was needed within WinForms rather than WPF at this point.
http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx
I figure if I can get it working 100% there I can port it over to WPF or worse case host the WinForm element in the WPF form if I absolutely have too (U-G-L-Y).

Anyway, I've gotten a bit closer, but am having a very odd issue with certain controls painting too the screen. Radio/Option buttons are rendering as solid black:

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

I've tried explicitly changing the controls' background color from buttonface to a fixed color and it still does it. I'm assuming it's a layering issue with the option buttons being within the frame control. I'm at a bit of a loss on how to proceed without massive rework of the VB6 content to change the options buttons to checkboxes. It's a hefty app and there are 600+ option button controls across the application that I don't exactly want to deal with.

EDIT:
I was able to confirm it has something to do with the layering of the option within a Frame control. If pulled out to the base form the issue does not occur:
http://www.evocommand.com/junk_delete_me/optionbuttons2.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文