2011-12-19 12 views
5

Mam aplikację VB6, która pokazuje formularz .NET DLL za pośrednictwem interop.Przepuścić obiekt VB6 do obiektu .NET przez interop?

Chciałbym wydarzenie w .NET DLL, aby spowodować wyświetlanie formularza w aplikacji VB6.

Mój pomysł polega na przekazaniu aplikacji VB6 odwołania do formularza do biblioteki .NET DLL. Np .:

[VB6] 
Dim objNetDllObject As New NetDllObject 
objNetDllObject.PassVb6Form(MyForm) 
objNetDllObject.ShowForm 

[C#] 
object Vb6Form; 
private void PassVb6Form(object form) { Vb6Form = form; } 
private void button1_Click(object sender, EventArgs e) { Vb6Form.Show(); } 

Czy to zadziała?

Czytałem gdzie indziej, że wysyłanie obiektów przez "granicę procesu" może powodować problemy. Czy to jest poprawne?

+1

To nie jest granica procesu ... to ten sam proces. Tak, to ból, ale może zadziałać. – Jeff

Odpowiedz

4

Jedna trasa będzie zdefiniowanie interfejsu COM w .NET:

<System.Runtime.InteropServices.GuidAttribute("0896D946-8A8B-4E7D-9D0D-BB29A52B5D08"), _ 
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _ 
Public Interface IEventHandler 
    Sub OnEvent(ByRef sender As Object, ByRef e As Object) 
End Interface 

wdrożyć ten interfejs w VB6

Implements MyInterop.IEventHandler 

Private Sub IEventHandler_OnEvent(ByRef sender As Variant, ByRef e As Variant) 
    Dim id 
    id = e.Entity.Id 
    ' As long as e is COM Visible (not necessarily COM registered, this will work) 
End Sub 

a następnie mieć sekretarza w .NET ze statycznym kolekcji IEventHandlers :

<ComClass(ComRegistrar.ClassId, ComRegistrar.InterfaceId, ComRegistrar.EventsId> 
Public Class ComRegistrar 

    Private Shared ReadOnly _eventHandlers As New Dictionary(Of String, List(Of IEventHandler)) 


    ' This is called by .NET code to fire events to VB6 
    Public Shared Sub FireEvent(ByVal eventName As String, ByVal sender As Object, ByVal e As Object) 
     For Each eventHandler In _eventHandlers(eventName) 
       eventHandler.OnEvent(sender, e) 
     Next 
    End Sub 

    Public Sub RegisterHandler(ByVal eventName As String, ByVal handler As IEventHandler) 
     Dim handlers as List(Of IEventHandler) 
     If Not _eventHandlers.TryGetValue(eventName, handlers) 
      handlers = New List(Of IEventHandler) 
      _eventHandlers(eventName) = handlers 
     End If 
     handlers.Add(handler) 
    End Sub 

End Class 

Twój kod .NET zadzwoniłby do FireEvent i gdyby VB6 wcześniej nazwał Regi SterHandler, twój VB6 IEventHandler zostanie wywołany.

+0

Czy moje podejście nie jest prostsze? Próbowałem uniknąć wszystkich tych zdarzeń związanych z obsługą zdarzeń. – CJ7

+0

Tak, prostsze, ale będziesz musiał użyć późnego wiązania, aby wykonać wywołanie zwrotne. – Jeff

+0

Jakie są zagrożenia związane z późnym wiązaniem w tym scenariuszu? – CJ7

0

Można również użyć kodu ComSourceInterfacesAttribute, który może uczynić twój kod nieco prostszym (lub co najmniej bardziej naturalnym od strony VB6). Trzeba trochę kodu jak poniżej:

C# Library:

namespace WindowsFormsControlLibrary1 
{ 
    using System; 
    using System.Runtime.InteropServices; 
    using System.Windows.Forms; 

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface IMyFormEvents 
    { 
     [DispId(1)] 
     void MyEvent(); 
    } 

    public delegate void MyEventEventHandler(); 

    [ComSourceInterfaces(typeof(IMyFormEvents))] 
    public partial class MyForm : Form 
    { 
     public event MyEventEventHandler MyEvent; 

     public MyForm() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      if (this.MyEvent != null) 
      { 
       this.MyEvent(); 
      } 
     } 
    } 
} 

a klient VB6:

Option Explicit 

Private WithEvents f As WindowsFormsControlLibrary1.MyForm 

Private Sub Command1_Click() 
    Set f = New WindowsFormsControlLibrary1.MyForm 
    Call f.Show 
End Sub 

Private Sub f_MyEvent() 
    MsgBox "Event was raised from .NET" 
    'Open another VB6 form or do whatever is needed 
End Sub 

Jeśli masz zamiar używać dużo .NET UI z Twoja aplikacja VB6 Gorąco polecam Interop Forms Toolkit jako sposób na uproszczenie. (Pomaga to w generowaniu kodu podobnego do tych próbek, a także w obsłudze innych typowych scenariuszy).

Powiązane problemy