Share via


Procédure pas à pas : prise en charge de l'interopérabilité COM en affichant les Windows Forms sur un thread partagé

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 :

La procédure suivante montre comment afficher un Windows Form sur un nouveau thread avec une boucle de message partagée.

Pour copier le code dans cette rubrique sous forme de liste unique, consultez Comment : prendre en charge l'interopérabilité COM en affichant les Windows Forms sur un thread partagé.

Procédure

Cette approche est semblable à celle qui est décrite dans Procédure pas à pas : prise en charge de l'interopérabilité COM en affichant chaque Windows Form sur son propre thread. Toutefois, au lieu d'afficher chaque formulaire sur son propre thread à l'aide de sa propre boucle de message, cette approche crée une boucle de message partagée qui s'exécute uniquement sur un nouveau thread dans le composant .NET Framework.

Cette approche représente plus exactement le comportement d'une application Windows Forms standard. Cette approche simplifie également le partage des ressources entre plusieurs formulaires, car tous les formulaires sont exécutés sur le même thread. La solution dans Procédure pas à pas : prise en charge de l'interopérabilité COM en affichant chaque Windows Form sur son propre thread crée un nouveau thread pour chaque formulaire. Cette solution requiert un code de synchronisation de threads supplémentaire pour partager les ressources entre les différents formulaires.

Étant donné que cette approche ressemble davantage au comportement d'une application Windows Forms, vous constaterez que le Windows Forms .NET Framework ouvert par l'application cliente se ferme lorsque la boucle de message .NET Framework s'arrête. Ce comportement se produit lorsque l'utilisateur ferme le formulaire qui est désigné comme formulaire principal pour ApplicationContext. ApplicationContext est utilisé pour démarrer la boucle de message.

Dans les exemples de code suivants, le formulaire principal de ApplicationContext a pour valeur le premier formulaire que l'application cliente ouvre. Par conséquent, lorsque l'utilisateur ferme cette instance de formulaire, la boucle de message .NET Framework prend fin et tous les autres Windows Forms se ferment.

Pour créer une boucle de message partagée sur un nouveau thread à utiliser par tous les formulaires

  1. Créez un projet de bibliothèque de classes et nommez-le COMWinform.

  2. Supprimez le fichier Class1.vb par défaut.

  3. Dans le menu Projet, cliquez sur Ajouter une classe.

  4. Sélectionnez le modèle Classe COM.

  5. Dans la zone Nom, tapez COMForm.vb, puis cliquez sur Ajouter.

  6. 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
    
  7. 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
    
  8. Dans le menu Projet, cliquez sur Ajouter une classe, puis sélectionnez le modèle Classe.

  9. Dans la zone Nom, tapez FormManager.vb, puis cliquez sur Ajouter.

  10. 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
    
  11. Dans le menu Projet, cliquez sur Ajouter un formulaire Windows, puis cliquez sur Ajouter.

  12. Ajoutez des contrôles TextBox et un contrôle Button au formulaire.

  13. Double-cliquez sur Bouton1 pour ajouter un gestionnaire d'événements Click.

  14. 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
    
  15. 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

  1. Démarrez Microsoft Visual Basic 6.0.

  2. Créer un projet EXE standard.

  3. Dans le menu Projet, cliquez sur Références.

  4. 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).

  5. Ajoutez un bouton au formulaire.

  6. Dans le menu Affichage, cliquez sur Code, puis ajoutez le code suivant au module de formulaire.

Option Explicit

Private Sub Command1_Click()
    Dim frm As COMWinform.COMForm
    Set frm = New COMWinform.COMForm
    frm.ShowForm1
End Sub
  1. Dans le menu Fichier, cliquez sur Créer EXE pour compiler le projet.

  2. Exécutez le fichier exécutable Visual Basic 6.0 compilé.

  3. Cliquez sur le bouton pour afficher Windows Form à partir de la bibliothèque de classes que vous avez créée précédemment.

  4. 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

Procédure pas à pas : prise en charge de l'interopérabilité COM en affichant chaque Windows Form sur son propre thread

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