Exemplarische Vorgehensweise: Unterstützen von COM-Interop durch das Anzeigen jedes Windows Forms in einem eigenen 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:
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.
Durch das folgende Verfahren wird veranschaulicht, wie ein Windows Form in einem separaten Thread angezeigt wird.
Informationen zum Kopieren des in diesem Thema behandelten Codes als einzelne Auflistung finden Sie unter Gewusst wie: Unterstützen von COM-Interop durch das Anzeigen einzelner Windows Forms in einem eigenen Thread.
Prozedur
Legen Sie das Formular in einem separaten Thread ab, und rufen Sie die Application.Run-Methode auf, um ein Windows Forms-Nachrichtensystem in diesem Thread zu starten. Um diese Vorgehensweise zu verwenden, müssen Sie alle Aufrufe der nicht verwalteten Anwendung an das Formular marshallen, indem Sie die Invoke-Methode verwenden.
Dieser Ansatz setzt voraus, dass jede Instanz eines Formulars in einem eigenen Thread unter Verwendung einer eigenen Meldungsschleife ausgeführt wird. Es können nicht mehrere Meldungsschleifen pro Thread ausgeführt werden. Deshalb kann die Meldungsschleife der Clientanwendung nicht geändert werden. Sie können jedoch die .NET Framework-Komponente ändern, um einen neuen Thread zu beginnen, der eine eigene Meldungsschleife verwendet.
So erstellen Sie jede Instanz eines Windows Forms in einem neuen Thread
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 den 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.
[Visual Basic]
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