Question

I created the following test scenario to track down a bug with VB6-WPF interop:

There is a .Net WPF DLL that displays a form with a textbox. The textbox does not handle the keyboard input - there is no databinding, no event handler. The DLL is COM visible.

A VB6 .exe calls the DLL ShowWindow function to display the WPF form. When I type any key in the textbox, it causes a "Run-time error '6' Overflow" error in the VB app. The error occurs in the "dVal = 0" line of the Timer1 event.

I guess the error occurs because the unhandled key event is bubbled up to the VB6 app. Should WPF events bubble up to VB6? Why does the problem show up in the timer? Why does it only occur if a double variable is set? It does not occur if the "dVal = 0" line is not present. Any thoughts?

C# code from public class that displays the window:

public class NetFormIFace : INetFormIFace
{

    public void ShowWindow1()
    {
        Window1 w1;
        w1 = new Window1();
        w1.Show();
    }

}

XAML for window. Nothing is added to the code-behind:

<Window x:Class="SSEC.NetForm.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Canvas>
        <TextBox Height="34" Canvas.Left="35" TextWrapping="Wrap" Text="TextBox" Canvas.Top="52" Width="94" />
    </Canvas>
</Window>

VB6 code:

Option Explicit

Dim IFace As NetFormIFace

Private Sub Command1_Click()
    IFace.ShowWindow1
End Sub

Private Sub Form_Load()
    Set IFace = New NetFormIFace
    Timer1.Interval = 50
    Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
    Dim iVal As Integer
    Dim dVal As Double

    iVal = 0    ' Does not cause an error
    dVal = 0    ' Causes an error
End Sub
Was it helpful?

Solution

You're creating a modeless WPF popup window, which runs on the message loop of an unmanaged VB6 app. There're some rules about this: Sharing Message Loops Between Win32 and WPF. I'm not sure though that would help in your specific case, even if you managed to implement the message loop requirements on the VB6 side.

Ideally, you should create an unmanaged Win32 popup window on the VB6 side, and use HwndSource to host your WPF content inside that window. Check Walkthrough: Hosting WPF Content in Win32.

Alternatively, you could try exposing a WPF Composite Control as an ActiveX control for VB6. First, you'd need to make sure it works inside a VB.NET WinForms UserControl, check Walkthrough: Hosting a WPF Composite Control in Windows Forms. Then, expose the WinForms UserControl as ActiveX control to VB6 with Microsoft InteropForms Toolkit. I'd probably go that route.

OTHER TIPS

We discovered that the error did not occur if we added a line of code at the start of the VB6 timer routine that accesses a GUI element. In this case, we added a line to read the Timer interval. We are using this as a temporary fix while we evaluate a better way to proceed.

Private Sub Timer1_Timer()
    Dim iVal As Integer
    Dim dVal As Double
    Dim lTemp as long

    lTemp = Timer1.Interval ' The error does not occur if this (any GUI?) element is read. I don't know why.

    iVal = 0    ' Does not cause an error
    dVal = 0    ' Causes an error
End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top