Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen von Windows Forms in einem freigegebenen Thread

Sie können Probleme mit der COM-Interoperabilität beheben, indem Sie das Formular in einer .NET Framework-Meldungsschleife anzeigen, die mit der Application.Run-Methode erstellt wird.

Damit ein Windows Form über eine COM-Clientanwendung ordnungsgemäß funktioniert, müssen Sie es in einer Windows Forms-Meldungsschleife ausführen. Verwenden Sie hierzu eines der folgenden Verfahren:

Im folgenden Verfahren wird veranschaulicht, wie Sie ein Windows Form in einem neuen Thread mit freigegebener Meldungsschleife anzeigen.

Informationen zum Kopieren des in diesem Thema behandelten Codes als einzelne Auflistung finden Sie unter Gewusst wie: Unterstützen von COM-Interop durch Anzeigen von Windows Forms in einem freigegebenen Thread.

Prozedur

Diese Vorgehensweise ist vergleichbar mit der unter Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen jedes Windows Forms in einem eigenen Thread. Anstatt jedoch jedes Formular unter Verwendung einer eigenen Meldungsschleife in einem eigenen Thread anzuzeigen, erstellen Sie in diesem Verfahren eine freigegebene Meldungsschleife, die nur für einen neuen Thread in der .NET Framework-Komponente ausgeführt wird.

Diese Vorgehensweise ist dem Verhalten einer Windows Forms-Standardanwendung etwas ähnlicher. So können Sie auch Ressourcen zwischen mehreren Formularen mithilfe dieser Vorgehensweise einfacher freigeben, da alle Formulare im selben Thread ausgeführt werden. Durch die Projektmappe in Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen jedes Windows Forms in einem eigenen Thread wird ein neuer Thread für jedes Formular erstellt. Diese Projektmappe erfordert zusätzlichen Code zur Threadsynchronisierung, damit Ressourcen zwischen verschiedenen Formularen freigegeben werden können.

Da diese Vorgehensweise eher dem Verhalten einer Windows Forms-Anwendung ähnelt, werden Sie beobachten, dass von der Clientanwendung geöffnete .NET Framework Windows Forms geschlossen werden, wenn die .NET Framework-Meldungsschleife angehalten wird. Dieses Verhalten tritt auf, wenn der Benutzer das Formular schließt, das als Hauptformular für ApplicationContext definiert wurde. Die Meldungsschleife wird über ApplicationContext gestartet.

In den folgenden Codebeispielen wird das Hauptformular von ApplicationContext auf das erste Formular festgelegt, das von der Clientanwendung geöffnet wird. Wenn der Benutzer diese Formularinstanz schließt, wird die .NET Framework-Meldungsschleife folglich beendet, und alle anderen Windows Forms werden geschlossen.

So erstellen Sie eine freigegebene Meldungsschleife in einem neuen Thread, die von allen Formularen verwendet werden kann

  1. Erstellen Sie ein neues Klassenbibliotheksprojekt, und nennen Sie es COMWinform.

  2. Löschen Sie die Class1.vb-Standarddatei.

  3. Klicken Sie im Menü Projekt auf Klasse hinzufügen.

  4. Wählen Sie die Vorlage COM-Klasse aus.

  5. Geben Sie in das Feld Name den Namen COMForm.vb ein, und klicken Sie dann auf Hinzufügen.

  6. Fügen Sie die folgenden Codeanweisungen am Anfang der Datei COMForm vor der Klassendefinition ein.

    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    
  7. Fügen Sie den folgenden Code unter der Konstruktordefinition in der COMForm-Klassendefinition ein.

    Private WithEvents frmManager As FormManager
    
    Public Sub ShowForm1()
        ' Call the StartForm method by using a new instance
        ' of the Form1 class.
        StartForm(New Form1)
    End Sub
    
    Private Sub StartForm(ByVal frm As Form)
    
        ' This procedure is used to show all forms
        ' that the client application requests. When the first form
        ' is displayed, this code will create a new message
        ' loop that runs on a new thread. The new form will
        ' be treated as the main form.
    
        ' Later forms will be shown on the same message loop.
        If IsNothing(frmManager) Then
            frmManager = New FormManager(frm)
        Else
            frmManager.ShowForm(frm)
        End If
    End Sub
    
    Private Sub frmManager_MessageLoopExit() Handles frmManager.MessageLoopExit
        'Release the reference to the frmManager object.
        frmManager = Nothing
    End Sub
    
  8. Klicken Sie im Menü Projekt auf Klasse hinzufügen, und wählen Sie die Vorlage Klasse aus.

  9. Geben Sie in das Feld Name den Namen FormManager.vb ein, und klicken Sie dann auf Hinzufügen.

  10. Ersetzen Sie den Inhalt der Datei FormManager durch folgenden Code:

    Imports System.Runtime.InteropServices
    Imports System.Threading
    Imports System.Windows.Forms
    
    <ComVisible(False)> _
    Friend Class FormManager
        ' This class is used so that you can generically pass any
        ' form that you want to the delegate.
    
        Private WithEvents appContext As ApplicationContext
        Private Delegate Sub FormShowDelegate(ByVal form As Form)
        Event MessageLoopExit()
    
        Public Sub New(ByVal MainForm As Form)
            Dim t As Thread
            If IsNothing(appContext) Then
                appContext = New ApplicationContext(MainForm)
                t = New Thread(AddressOf StartMessageLoop)
                t.IsBackground = True
                t.SetApartmentState(ApartmentState.STA)
                t.Start()
            End If
        End Sub
    
        Private Sub StartMessageLoop()
            ' Call the Application.Run method to run the form on its own message loop.
            Application.Run(appContext)
        End Sub
    
        Public Sub ShowForm(ByVal form As Form)
    
            Dim formShow As FormShowDelegate
    
            ' Start the main form first. Otherwise, focus will stay on the 
            ' calling form.
            appContext.MainForm.Activate()
    
            ' Create a new instance of the FormShowDelegate method, and
            ' then invoke the delegate off the MainForm object.
            formShow = New FormShowDelegate(AddressOf ShowFormOnMainForm_MessageLoop)
            appContext.MainForm.Invoke(formShow, New Object() {form})
        End Sub
    
        Private Sub ShowFormOnMainForm_MessageLoop(ByVal form As Form)
            form.Show()
        End Sub
    
        Private Sub ac_ThreadExit(ByVal sender As Object, ByVal e As System.EventArgs) Handles appContext.ThreadExit
            appContext.MainForm.Dispose()
            appContext.MainForm = Nothing
            appContext.Dispose()
            appContext = Nothing
            RaiseEvent MessageLoopExit()
        End Sub
    End Class
    
  11. Klicken Sie im Menü Projekt auf Windows Form hinzufügen und dann auf Hinzufügen.

  12. Fügen Sie dem Formular einige TextBox-Steuerelemente und ein Button-Steuerelement hinzu.

  13. Doppelklicken Sie auf Button1, um einen Click-Ereignishandler hinzuzufügen.

  14. Fügen Sie dem Click-Ereignishandler folgenden Code hinzu.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MessageBox.Show("Clicked button")
    End Sub
    
  15. Erstellen Sie die Projektmappe.

    Durch diesen Schritt wird das Projekt auf diesem Computer auch für COM-Interop registriert.

So erstellen Sie eine ausführbare Datei, die COM-Interop veranschaulicht

  1. Starten Sie Microsoft Visual Basic 6.0.

  2. Erstellen Sie ein neues EXE-Standardprojekt.

  3. Klicken Sie im Menü Projekt auf Verweise.

  4. Fügen Sie einen Verweis auf die COMWinform-Typbibliothek hinzu, die beim Erstellen der Visual Basic 2005-Projektmappe generiert wurde.

    - oder -

    Falls die Typbibliothek nicht in der Liste angezeigt wird, klicken Sie auf Durchsuchen, um die Datei der Typbibliothek (.tlb) manuell zu suchen.

  5. Fügen Sie dem Formular eine Schaltfläche hinzu.

  6. Klicken Sie im Menü Ansicht auf Code, und fügen Sie dem Formularmodul den folgenden Code hinzu.

Option Explicit

Private Sub Command1_Click()
    Dim frm As COMWinform.COMForm
    Set frm = New COMWinform.COMForm
    frm.ShowForm1
End Sub
  1. Klicken Sie im Menü Datei auf EXE erstellen, um das Projekt zu kompilieren.

  2. Führen Sie die kompilierte ausführbare Visual Basic 6.0-Datei aus.

  3. Klicken Sie auf die Schaltfläche, um das Windows Form aus der Klassenbibliothek anzuzeigen, das Sie früher erstellt haben.

  4. Legen Sie den Fokus auf eines der TextBox-Steuerelemente im Windows Form fest, und drücken Sie die TABULATORTASTE, um zwischen den Steuerelementen hin und her zu wechseln.

    Beachten Sie, dass mit der TABULATORTASTE der Fokus von Steuerelement zu Steuerelement verschoben werden kann. Beachten Sie auch, dass das Click-Ereignis der Schaltfläche ausgelöst wird, wenn Sie die EINGABETASTE drücken.

Siehe auch

Aufgaben

Gewusst wie: Unterstützen von COM-Interop durch Anzeigen eines Windows Forms mit der ShowDialog-Methode

Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen jedes Windows Forms in einem eigenen Thread

Konzepte

Verfügbarmachen von .NET Framework-Komponenten in COM

Verpacken einer Assembly für COM

Registrieren von Assemblys mit COM

Übersicht über Windows Forms und nicht verwaltete Anwendungen