Condividi tramite


Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di Windows Form in un thread condiviso

È possibile risolvere i problemi di interoperabilità COM visualizzando il form in un ciclo di messaggi .NET Framework, creato utilizzando il metodo Application.Run.

Perché un Windows Form funzioni correttamente da un'applicazione client COM, è necessario eseguirlo in un ciclo di messaggi Windows Form. Per eseguire questa operazione, adottare uno degli approcci seguenti:

Nella procedura descritta di seguito viene illustrato come visualizzare un Windows Form in un nuovo thread con un ciclo di messaggi condiviso.

Per copiare il codice nell'argomento corrente come un elenco singolo, vedere Procedura: supportare l'interoperabilità COM mediante la visualizzazione di Windows Form in un thread condiviso.

Procedura

Questo approccio è simile a quello illustrato in Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread. Invece di visualizzare ciascun form nel proprio thread utilizzando un proprio ciclo di messaggi, verrà creato un ciclo di messaggi condiviso che sarà eseguito solo in un unico nuovo thread nel componente .NET Framework.

In questo approccio viene rappresentato in modo molto accurato il comportamento di un'applicazione Windows Form standard, inoltre viene facilitata la condivisione di risorse tra più form, perché tutti i form vengono eseguiti nello stesso thread. Con la soluzione descritta in Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread viene creato un nuovo thread per ciascun form. Tale soluzione richiede codice di sincronizzazione dei thread aggiuntivo per condividere le risorse tra form diversi.

Poiché questo approccio è molto simile al comportamento di un'applicazione Windows Form, si potrà osservare che il Windows Form .NET Framework aperto dall'applicazione client verrà chiuso al termine del ciclo di messaggi .NET Framework. Questo comportamento si verifica quando l'utente chiude il form designato come form principale della classe ApplicationContext. La classe ApplicationContext è utilizzata per avviare il ciclo di messaggi.

Negli esempi di codice riportati di seguito il form principale della classe ApplicationContext è impostato sul primo form aperto dall'applicazione client. Di conseguenza, quando l'utente chiude l'istanza di tale form, il ciclo di messaggi .NET Framework verrà terminato e tutti gli altri Windows Form verranno chiusi.

Per creare un ciclo di messaggi condiviso in un nuovo thread utilizzabile da tutti i form

  1. Creare un nuovo progetto Libreria di classi e denominarlo COMWinform.

  2. Eliminare il file Class1.vb predefinito.

  3. Scegliere Aggiungi classe dal menu Progetto.

  4. Selezionare il modello Classe COM.

  5. Digitare COMForm.vb nella casella Nome, quindi fare clic su Aggiungi.

  6. Inserire le dichiarazioni di codice riportate di seguito all'inizio del file COMForm, prima della definizione della classe.

    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    
  7. Nella definizione della classe COMForm, inserire il codice riportato di seguito dopo la definizione del costruttore.

    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. Scegliere Aggiungi classe dal menu Progetto e selezionare il modello Classe.

  9. Digitare FormManager.vb nella casella Nome, quindi fare clic su Aggiungi.

  10. Sostituire il contenuto del file FormManager con il codice riportato di seguito.

    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. Scegliere Aggiungi Windows Form dal menu Progetto, quindi fare clic su Aggiungi.

  12. Aggiungere al form alcuni controlli TextBox e un controllo Button.

  13. Fare doppio clic su Button1 per aggiungere un gestore eventi Click.

  14. Aggiungere il codice seguente al gestore eventi 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. Compilare la soluzione.

    Con questo passaggio, il progetto viene anche registrato per l'interoperabilità COM sul computer.

Per creare un file eseguibile che dimostri l'interoperabilità COM

  1. Avviare Microsoft Visual Basic 6.0.

  2. Creare un nuovo progetto EXE standard.

  3. Scegliere Riferimenti dal menu Progetto.

  4. Aggiungere un riferimento alla libreria dei tipi COMWinform generata durante la compilazione della soluzione Visual Basic 2005.

    -oppure-

    Se non è presente in elenco, fare clic su Sfoglia per individuare manualmente il file della libreria dei tipi (TLB).

  5. Aggiungere un pulsante al form.

  6. Scegliere Codice dal menu Visualizza e aggiungere il codice seguente al modulo del form.

Option Explicit

Private Sub Command1_Click()
    Dim frm As COMWinform.COMForm
    Set frm = New COMWinform.COMForm
    frm.ShowForm1
End Sub
  1. Scegliere Make.EXE dal menu File per compilare il progetto.

  2. Eseguire il file eseguibile di Visual Basic 6.0 compilato.

  3. Fare clic sul pulsante per visualizzare Windows Form dalla libreria di classi creata precedentemente.

  4. Impostare lo stato attivo su uno dei controlli TextBox in Windows Form, quindi premere il tasto TAB per spostarsi tra i controlli.

    Notare che il tasto TAB sposta lo stato attivo da un controllo all'altro. Inoltre l'evento Click del pulsante viene generato quando si preme INVIO.

Vedere anche

Attività

Procedura: supportare l'interoperabilità COM visualizzando un Windows Form con il metodo ShowDialog

Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread

Concetti

Esposizione di componenti .NET Framework a COM

Preparazione di un assembly per COM

Registrazione di assembly presso COM

Cenni preliminari su Windows Form e applicazioni non gestite