WPF-VB6 Interop导致计时器运行时错误

时间:2014-02-13 21:52:10

标签: c# wpf vb6 com-interop

我创建了以下测试场景来跟踪VB6-WPF互操作的错误:

有一个.Net WPF DLL,它显示带有文本框的表单。文本框不处理键盘输入 - 没有数据绑定,没有事件处理程序。 DLL是COM可见。

VB6 .exe调用DLL ShowWindow函数来显示WPF表单。当我在文本框中键入任何键时,它会在VB应用程序中导致“运行时错误'6'溢出”错误。错误发生在Timer1事件的“ dVal = 0 ”行中。

我猜错误的发生是因为未处理的键事件冒泡到了VB6应用程序。 WPF活动应该升级到VB6吗?为什么问题出现在计时器中?为什么只有在设置了双变量时才会出现?如果“ dVal = 0 ”行不存在,则不会发生。有什么想法吗?

显示窗口的公共类的C#代码:

public class NetFormIFace : INetFormIFace
{

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

}

XAML for window。代码隐藏中没有添加任何内容:

<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代码:

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

2 个答案:

答案 0 :(得分:1)

您正在创建一个无模式WPF弹出窗口,该窗口在非托管VB6应用程序的消息循环上运行。对此有一些规则:Sharing Message Loops Between Win32 and WPF。我不确定这会对你的具体情况有所帮助,即使你设法在VB6端实现了消息循环要求。

理想情况下,您应该在VB6端创建一个非托管的Win32弹出窗口,并使用HwndSource在该窗口中托管您的WPF内容。检查Walkthrough: Hosting WPF Content in Win32

或者,您可以尝试将WPF复合控件公开为VB6的ActiveX控件。首先,您需要确保它在VB.NET WinForms UserControl中运行,请检查Walkthrough: Hosting a WPF Composite Control in Windows Forms。然后,使用Microsoft InteropForms Toolkit将WinForms UserControl作为ActiveX控件公开给VB6。我可能会走那条路。

答案 1 :(得分:0)

我们发现如果我们在访问GUI元素的VB6计时器例程的开头添加了一行代码,则不会发生错误。在这种情况下,我们添加了一行来读取Timer间隔。我们正在使用它作为临时修复,同时我们评估一种更好的方法。

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