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. T
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
Can you even load that VB6 form in another VB6 form? I suggest you get that working first.
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.
I was able to accomplish the task with the following steps:
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:
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.
All mousepointer references have to be changed from Me.Mousepointer to Screen.mousepointer
You cannot use Me.Hide and have to alternate events to hide the .Net container.
Any and all references to Me.[anything] have to be removed or replaced with UserControl.[anything] if they are applicable.
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
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.
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.
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.”
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.
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.
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.