您可以/如何在 C# WPF 应用程序中托管完整的 VB6 表单? [英] Can/how do you host a full VB6 Form in a C# WPF app?

查看:21
本文介绍了您可以/如何在 C# WPF 应用程序中托管完整的 VB6 表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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.

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

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

将在前一屏幕右侧的空白"部分加载的当前 VB6 维护屏幕.

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

推荐答案

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

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

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

  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. 你失去了展示的能力表格中的标题以前的方式.你可以解决它带有备用控件(标签/无边框文本框等)完成相同的功能,如果需要.这不是优先事项,因为每个屏幕都托管在一个像我们新的标签系统一样的浏览器.Net 项目.

  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.

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

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

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

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

任何和所有对Me.[anything] 必须被删除或替换为 UserControl.[anything]如果适用.

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

如果您使用的任何功能参考[yourcontrol].Contianer.Property on a需要将它们更改为循环通过 UserControl.Controls集合代替,容器"是对 vb6 ActiveX 控件无效

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

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

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.

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

  • 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.

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

    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."

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

    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.

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

    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.

    这篇关于您可以/如何在 C# WPF 应用程序中托管完整的 VB6 表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆