Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen von Windows Forms in einem freigegebenen Thread
Aktualisiert: November 2007
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:
Zeigen Sie das Windows Form mithilfe der Form.ShowDialog-Methode an. Weitere Informationen finden Sie unter Gewusst wie: Unterstützen von COM-Interop durch Anzeigen eines Windows Forms mit der ShowDialog-Methode.
Zeigen Sie jedes Windows Form in einem separaten Thread an. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen jedes Windows Forms in einem eigenen Thread.
Erstellen Sie in einem neuen Thread in der .NET Framework-Komponente eine freigegebene Meldungsschleife.
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
Erstellen Sie ein neues Klassenbibliotheksprojekt, und nennen Sie es COMWinform.
Löschen Sie die Class1.vb-Standarddatei.
Klicken Sie im Menü Projekt auf Klasse hinzufügen.
Wählen Sie die Vorlage COM-Klasse aus.
Geben Sie in das Feld Name den Namen COMForm.vb ein, und klicken Sie dann auf Hinzufügen.
Fügen Sie die folgenden Codeanweisungen am Anfang der Datei COMForm vor der Klassendefinition ein.
Imports System.Windows.Forms Imports System.Runtime.InteropServices
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
Klicken Sie im Menü Projekt auf Klasse hinzufügen, und wählen Sie die Vorlage Klasse aus.
Geben Sie in das Feld Name den Namen FormManager.vb ein, und klicken Sie dann auf Hinzufügen.
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
Klicken Sie im Menü Projekt auf Windows Form hinzufügen und dann auf Hinzufügen.
Fügen Sie dem Formular einige TextBox-Steuerelemente und ein Button-Steuerelement hinzu.
Doppelklicken Sie auf Button1, um einen Click-Ereignishandler hinzuzufügen.
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
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
Starten Sie Microsoft Visual Basic 6.0.
Erstellen Sie ein neues EXE-Standardprojekt.
Klicken Sie im Menü Projekt auf Verweise.
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.
Fügen Sie dem Formular eine Schaltfläche hinzu.
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
Klicken Sie im Menü Datei auf EXE erstellen, um das Projekt zu kompilieren.
Führen Sie die kompilierte ausführbare Visual Basic 6.0-Datei aus.
Klicken Sie auf die Schaltfläche, um das Windows Form aus der Klassenbibliothek anzuzeigen, das Sie früher erstellt haben.
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
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