Procédure pas à pas : prise en charge de l'interopérabilité COM en affichant chaque Windows Form sur son propre thread
Vous pouvez résoudre les problèmes d'interopérabilité COM en affichant le formulaire dans une boucle de message .NET Framework, laquelle est créée à l'aide de la méthode Application.Run.
Pour qu'un Windows Form fonctionne correctement à partir d'une application cliente COM, vous devez l'exécuter sur une boucle de message Windows Forms. Pour cela, utilisez l'une des approches suivantes :
Utilisez la méthode Form.ShowDialog pour afficher le Windows Form. Pour plus d'informations, consultez Comment : prendre en charge COM Interop en affichant un Windows Form avec la méthode ShowDialog.
Affichez chaque Windows Form sur un thread séparé.
La procédure suivante montre comment afficher un Windows Form sur un thread distinct.
Pour copier le code dans cette rubrique sous forme de liste unique, consultez Comment : prendre en charge l'interopérabilité COM en affichant chaque Windows Form sur son propre thread.
Procédure
Placez le formulaire sur un thread distinct et appelez la méthode Application.Run pour démarrer une pompe de messages Windows Forms sur ce thread. Pour utiliser cette approche, vous devez marshaler tous les appels passés au formulaire à partir de l'application non managée en utilisant la méthode Invoke.
Cette approche requiert que chaque instance d'un formulaire s'exécute sur son propre thread en utilisant sa propre boucle de message. Plusieurs boucles de message ne peuvent pas s'exécuter par thread. Par conséquent, vous ne pouvez pas modifier la boucle de message de l'application cliente. Toutefois, vous pouvez modifier le composant .NET Framework pour démarrer un nouveau thread qui utilise sa propre boucle de message.
Pour créer chaque instance d'un Windows Form sur un nouveau thread
Créez un projet Bibliothèque de classes et nommez-le COMWinform.
Supprimez le fichier Class1.vb par défaut.
Dans le menu Projet, cliquez sur Ajouter une classe.
Sélectionnez le modèle Classe COM.
Dans la zone Nom, tapez COMForm.vb, puis cliquez sur Ajouter.
Collez les instructions de code suivantes au haut du fichier COMForm, avant la définition de classe.
Imports System.Windows.Forms Imports System.Runtime.InteropServices
Dans la définition de classe COMForm, collez le code suivant sous la définition de constructeur.
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
Dans le menu Projet, cliquez sur Ajouter une classe, puis sélectionnez le modèle Classe.
Dans la zone Nom, tapez FormManager.vb, puis cliquez sur Ajouter.
Remplacez le contenu du fichier FormManager par le code suivant.
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
Dans le menu Projet, cliquez sur Ajouter un formulaire Windows, puis cliquez sur Ajouter.
Ajoutez des contrôles TextBox et un contrôle Button au formulaire.
Double-cliquez sur Bouton1 pour ajouter un gestionnaire d'événements Click.
Ajoutez le code suivant au gestionnaire d'événements Click.
Private Sub Button1_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click MessageBox.Show("Clicked button") End Sub
Générez la solution.
Cette étape enregistre également le projet pour COM Interop sur cet ordinateur.
Pour créer un fichier exécutable qui présente COM Interop
Démarrez Microsoft Visual Basic 6.0.
Créer un projet EXE standard.
Dans le menu Projet, cliquez sur Références.
Ajoutez une référence à la bibliothèque de types COMWinform qui a été générée lorsque vous avez conçu la solution Visual Basic 2005.
ou
Si vous ne la voyez pas dans la liste, cliquez sur Parcourir pour repérer manuellement le fichier bibliothèque de types (.tlb).
Ajoutez un bouton au formulaire.
Dans le menu Affichage, cliquez sur Code, puis ajoutez le code suivant au module de formulaire.
[Visual Basic]
Option Explicit
Private Sub Command1_Click()
Dim frm As COMWinform.COMForm
Set frm = New COMWinform.COMForm
frm.ShowForm1
End Sub
Dans le menu Fichier, cliquez sur Créer EXE pour compiler le projet.
Exécutez le fichier exécutable Visual Basic 6.0 compilé.
Cliquez sur le bouton pour afficher Windows Form à partir de la bibliothèque de classes que vous avez créée précédemment.
Définissez le focus sur l'un des contrôles TextBox dans Windows Form, puis appuyez sur la touche de tabulation pour naviguer entre les contrôles.
Notez que la touche de tabulation déplace le focus d'un contrôle à l'autre. Vous remarquerez aussi que l'événement Click du bouton est déclenché lorsque vous appuyez sur la touche Entrée.
Voir aussi
Tâches
Comment : prendre en charge COM Interop en affichant un Windows Form avec la méthode ShowDialog
Concepts
Exposition de composants .NET Framework à COM
Empaquetage d'un assembly pour COM
Inscription d'assemblys dans COM
Vue d'ensemble des applications Windows Forms et non managées