2011-12-19 36 views
5

Tôi có một ứng dụng VB6 cho thấy một hình thức DLL NET thông qua interop.Vượt qua đối tượng VB6 đối tượng .NET qua interop?

Tôi muốn có sự kiện trong .NET DLL để tạo biểu mẫu trong ứng dụng VB6 được hiển thị.

Ý tưởng của tôi là để ứng dụng VB6 chuyển một tham chiếu tới biểu mẫu tới .NET DLL. Ví dụ:

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

Điều này có hiệu quả không?

Tôi đã đọc ở nơi khác để gửi các đối tượng qua một 'ranh giới quy trình' có thể gây ra sự cố. Điều này có đúng không?

+1

Đây không phải là một ranh giới quy trình ... nó là quá trình tương tự. Vâng, đó là một nỗi đau, nhưng nó có thể hoạt động. – Jeff

Trả lời

4

Một tuyến đường sẽ được xác định một giao diện COM trong .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 

Thực hiện giao diện này trong 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 

và sau đó có một Đăng ký trong .NET với một bộ sưu tập tĩnh của 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 

Mã .NET của bạn sẽ gọi FireEvent và nếu VB6 trước đây gọi là Regi sterHandler, trình duyệt IE6 của bạn sẽ được gọi.

+0

Cách tiếp cận của tôi có đơn giản hơn không? Tôi đã cố gắng tránh tất cả những thứ xử lý sự kiện đó. – CJ7

+0

Có, đơn giản hơn, nhưng bạn sẽ cần sử dụng kết buộc muộn để thực hiện cuộc gọi lại. – Jeff

+0

Những rủi ro khi ràng buộc trễ trong kịch bản này là gì? – CJ7

0

Bạn cũng có thể sử dụng ComSourceInterfacesAttribute để có thể làm cho mã của bạn đơn giản hơn một chút (hoặc ít nhất là tự nhiên hơn từ phía VB6). Bạn muốn có một số mã như sau: thư viện

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

Và client 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 

Nếu bạn đang đi để được sử dụng rất nhiều NET UI từ ứng dụng VB6 của bạn tôi rất muốn giới thiệu các Interop Forms Toolkit như một cách để làm cho mọi thứ đơn giản hơn. (Nó giúp tạo mã như các mẫu này, cũng như xử lý một số tình huống phổ biến khác).

Các vấn đề liên quan