我创建了以下测试场景来跟踪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
答案 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