2011-12-19 14 views
5

Tengo una aplicación VB6 que muestra un formulario .NET DLL a través de la interoperabilidad.¿Pasar objeto VB6 al objeto .NET a través de interoperabilidad?

Me gustaría un evento en la DLL .NET para hacer que se muestre un formulario en la aplicación VB6.

Mi idea es hacer que la aplicación VB6 pase una referencia a un formulario a .NET DLL. Por ejemplo:

[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(); } 

¿Funciona?

He leído en otra parte que enviar objetos a través de un 'límite de proceso' puede causar problemas. ¿Es esto correcto?

+1

Esto no es un límite de proceso ... es el mismo proceso. Sí, es un dolor, pero puede funcionar. – Jeff

Respuesta

4

Una ruta sería definir una interfaz COM en .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 

implementar esta interfaz en 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 

y luego tener un Registrador en .NET con una colección estática de 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 

Su código .NET llamaría FireEvent y si VB6 había llamado anteriormente Regi sterHandler, su IEntHandler VB6 sería llamado.

+0

¿No es mi enfoque más simple? Estaba tratando de evitar todo ese evento manejando cosas. – CJ7

+0

Sí, es más simple, pero deberá usar el enlace tardío para realizar su devolución de llamada. – Jeff

+0

¿Cuáles son los riesgos de vinculación tardía en este escenario? – CJ7

0

También podría usar el ComSourceInterfacesAttribute que podría hacer que su código sea un poco más simple (o al menos más natural desde el lado VB6). Tendrías algún código como el siguiente: # biblioteca

C:

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(); 
      } 
     } 
    } 
} 

y el cliente de Visual Basic 6:

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 

Si va a utilizar una gran cantidad de .NET interfaz de usuario de su aplicación VB6, recomendaría el Interop Forms Toolkit como una forma de simplificar las cosas. (Ayuda a generar código como estas muestras, así como a manejar algunos otros escenarios comunes).

Cuestiones relacionadas