Compartilhar via


Demonstra Passo a passo: Exibindo cada Windows Form em seu próprio segmento de suporte COM Interop

Você pode resolver problemas de interoperabilidade COM exibindo o formulário em um loop de mensagens .NET Framework, que você pode criar usando o método Application.Run.

Para fazer um Formuláriodo do Windows funcionar corretamente de um aplicativo cliente COM, você deve executá-lo em um loop de mensagem dos Formulários do Windows. Para fazer isso, use uma das seguintes abordagens:

O procedimento a seguir demonstra como exibir um Windows Form em um segmento separado.

Para copiar o código deste tópico como uma única lista, consulte Como: Suporte para interoperabilidade COM, exibindo cada Windows Form em seu próprio segmento.

Procedimento

Colocar o formulário em um segmento separado e chamar o método Application.Run Para iniciar uma bomba de mensagem Formulários do Windows em que o segmento. Para usar essa abordagem, você deverá empacotar as chamadas para o formulário do aplicativo não gerenciado usando o método Invoke.

Essa abordagem requer que cada instância de um formulário seja executada em seu próprio segmento usando seu próprio loop de mensagens. Você não pode ter mais de um loop de mensagens em execução por thread. Portanto, não é possível alterar o loop de mensagens do aplicativo cliente. No entanto, você pode modificar o componente .NET Framework para iniciar um novo segmento que usa seu próprio loop de mensagem.

Para criar cada instância de uma Windows Form em um novo segmento

  1. Crie um novo projeto de biblioteca de classes e nomeie-o COMWinform.

  2. Exclua o Class1.vb padrão do arquivo.

  3. No menu Project clique em Add Class.

  4. Selecione o modelo Classe COM.

  5. Na caixa Nome, digite COMForm.vb e em seguida, clique em Adicionar.

  6. Cole as instruções de código a seguir na parte superior do arquivo COMForm, antes da definição de classe.

    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    
  7. Em definição da classe COMForm, cole o seguinte código sob a definição do construtor.

    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. No menu Projeto, clique em Adicionar Classe e selecione o modelo Classe.

  9. Na caixa Nome, digite FormManager.vb e em seguida, clique em Adicionar .

  10. Substitua o conteúdo do arquivo FormManager pelo código a seguir.

    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. No menu Projeto,clique em Adicionar Formulário do Windows e em seguida, clique em Adicionar.

  12. Adicione alguns controles TextBox e um controle Button ao formulário.

  13. Clique duas vezes em Button1 para adicionar um manipulador de eventos Click.

  14. Adicione o seguinte código para o manipulador de eventos 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. Crie a solução.

    Esta etapa também registra o projeto para interoperabilidade COM neste computador.

Para criar um arquivo executável que demonstra interoperabilidade COM

  1. Inicie Microsoft Visual Basic 6.0.

  2. Crie um novo projeto EXE padrão.

  3. No menu Projeto, clique em Propriedades..

  4. Adicione uma referência para a biblioteca de tipos COMWinform que foi gerado quando você criou a solução Visual Basic 2005.

    - ou -

    Se não você a viu na lista, clique em Pesquisar para localizar o arquivo biblioteca de tipos (.tlb) manualmente.

  5. Adicione um botão ao formulário.

  6. No menu Visualizar, clique em Código e, em seguida, adicione o código a seguir ao módulo do formulário.

[Visual Basic]

Option Explicit

Private Sub Command1_Click()
    Dim frm As COMWinform.COMForm
    Set frm = New COMWinform.COMForm
    frm.ShowForm1
End Sub
  1. Sobre o arquivo menu, clique em EXE fazer para compilar o projeto.

  2. Execute o arquivo executável compilado do Visual Basic 6.0.

  3. Clique no botão para exibir o formulário do Windows da biblioteca de classe que você criou anteriormente.

  4. Definir o foco em um do TextBox controles no formulário do Windows e em seguida, pressione a tecla TAB para mover entre controles.

    Observe que a tecla TAB move o foco de controle para controle. Além disso, observe que o botão Click evento é gerado quando você pressiona a tecla ENTER.

Consulte também

Tarefas

Como: Suporte para interoperabilidade COM, exibindo um formulário do Windows com o método ShowDialog

Conceitos

Expondo.NET Framework para COM

Empacotamento de um Assembly para COM

Registrar Assemblies com

Visão Geral de Aplicativos de Formulários do Windows e Aplicativos Não Gerenciados