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:
Utilizzare il metodo Form.ShowDialog per visualizzare il Windows Form. Per ulteriori informazioni, vedere Procedura: supportare l'interoperabilità COM visualizzando un Windows Form con il metodo ShowDialog.
Visualizzare ogni Windows Form in un thread separato. Per ulteriori informazioni, vedere Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread.
Creare un ciclo di messaggi condiviso in un nuovo thread nel componente .NET Framework.
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
Creare un nuovo progetto Libreria di classi e denominarlo COMWinform.
Eliminare il file Class1.vb predefinito.
Scegliere Aggiungi classe dal menu Progetto.
Selezionare il modello Classe COM.
Digitare COMForm.vb nella casella Nome, quindi fare clic su Aggiungi.
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
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
Scegliere Aggiungi classe dal menu Progetto e selezionare il modello Classe.
Digitare FormManager.vb nella casella Nome, quindi fare clic su Aggiungi.
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
Scegliere Aggiungi Windows Form dal menu Progetto, quindi fare clic su Aggiungi.
Aggiungere al form alcuni controlli TextBox e un controllo Button.
Fare doppio clic su Button1 per aggiungere un gestore eventi Click.
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
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
Avviare Microsoft Visual Basic 6.0.
Creare un nuovo progetto EXE standard.
Scegliere Riferimenti dal menu Progetto.
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).
Aggiungere un pulsante al form.
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
Scegliere Make.EXE dal menu File per compilare il progetto.
Eseguire il file eseguibile di Visual Basic 6.0 compilato.
Fare clic sul pulsante per visualizzare Windows Form dalla libreria di classi creata precedentemente.
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
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