Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can/how do you host a full VB6 Form in a C# WPF app?

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.

like image 608
jasonk Avatar asked Feb 10 '10 19:02

jasonk


3 Answers

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.

like image 74
jasonk Avatar answered Oct 16 '22 20:10

jasonk


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.

like image 23
Jeremy Wiebe Avatar answered Oct 16 '22 19:10

Jeremy Wiebe


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

like image 1
John Saunders Avatar answered Oct 16 '22 20:10

John Saunders