Procedura dettagliata: supporto dell'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread
È 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.
Nella procedura riportata di seguito viene descritto come visualizzare un Windows Form in un thread separato.
Per copiare il codice nell'argomento corrente come un elenco singolo, vedere Procedura: supportare l'interoperabilità COM mediante la visualizzazione di ogni Windows Form nel relativo thread.
Procedura
Inserire il form in un thread separato e chiamare il metodo Application.Run per avviare un message pump di Windows Form su tale thread. Per utilizzare questo approccio, è necessario effettuare il marshalling di tutte le chiamate al form dall'applicazione non gestita utilizzando il metodo Invoke.
Per questo approccio è necessario che ciascuna istanza di un form venga eseguita nel proprio thread tramite un proprio ciclo di messaggi. Non è possibile eseguire più di un ciclo di messaggi per thread. Di conseguenza, non è possibile modificare il ciclo di messaggi dell'applicazione client. È tuttavia possibile modificare il componente .NET Framework per l'avvio di un nuovo thread che utilizza il corrispondente ciclo di messaggi.
Per creare ciascuna istanza di un Windows Form in un nuovo thread
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.
[Visual Basic]
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