Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Quando você abre uma instância de um formulário do Microsoft Windows de um aplicativo de cliente COM, como um aplicativo do Microsoft Visual Basic 6.0 ou um aplicativo MFC (Microsoft Foundation Classes), o formulário .NET do Windows podem se comportar inesperadamente. Por exemplo, quando você pressiona TAB, o foco não altera de um controle para um outro controle. Ou, quando você pressiona ENTER enquanto um botão de comando tem o foco, o evento Click do botão não dispara. Você também pode enfrentar um comportamento inesperado para pressionamentos de teclas ou para atividade de mouse.
Esses sintomas ocorrem porque o aplicativo anterior não implementa o suporte de loop de mensagem que deve ter um formulário do Windows .NET Framework para funcionar corretamente.
Este artigo descreve como resolver esses problemas, exibindo o formulário em um loop de mensagem do .NET Framework que você criar usando o método Application.Run .
Quando você cria uma instância de um formulário do Microsoft Windows de um aplicativo de cliente COM, o formulário pode comportar-se inesperadamente. Por exemplo, quando você cria uma instância do formulário de um aplicativo do Microsoft Visual Basic 6.0 ou de um aplicativo MFC (Microsoft Foundation Classes), o foco não é alterado de um controle para um outro controle quando você pressiona TAB. Ou, se você pressionar ENTER enquanto um botão de comando tem o foco, o evento Click do botão não será acionado. Você também pode enfrentar um comportamento inesperado para pressionamentos de teclas ou para atividade de mouse.
Esse problema ocorre porque o loop de mensagem que usa o formulário do Windows e o loop de mensagem que o aplicativo de cliente COM fornece são diferentes.
A Microsoft fez uma alteração para resolver esse problema de design. Para obter mais informações, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
885446
(http://support.microsoft.com/kb/885446/
)
CORRECÇÃO: Você pode enfrentar um comportamento inesperado ao pressionar TAB ou ENTER em um Windows Form em um computador que esteja executando o .NET Framework 1.1 S
Este artigo descreve como resolver esse problema, exibindo o formulário em um loop de mensagem do .NET Framework que você criar usando o método Application.Run .
Use o método ShowDialog para exibir o formulário do Windows
Isso é a solução mais fácil para exibir o formulário em um loop de mensagem do .NET Framework. Para fazer isso, substitua as chamadas para o método Show chamadas para o método ShowDialog em seu componente .NET Framework.
O método ShowDialog suspende o loop de mensagem do aplicativo anterior e exibe o formulário como uma caixa de diálogo. Como o loop de mensagem do aplicativo host tiver sido suspenso, o método ShowDialog cria um loop de mensagem novo .NET Framework para processar mensagens do formulário. Isso é a solução mais fácil porque requer o menos código para implementar. No entanto, a desvantagem dessa abordagem é que o formulário será aberto restrito. Esse comportamento bloqueia qualquer interface de usuário (UI) do aplicativo chamada enquanto o formulário do Windows está aberto. Quando o usuário fecha o formulário do Windows, o .NET Framework sai do loop de mensagem e mensagem do aplicativo anterior loop continua sendo executado.
Modificar componente .NET Framework para exibir cada instância de um formulário em seu próprio thread usando seu próprio loop de mensagem. Você não pode ter mais de um loop de mensagem em execução por thread. Portanto, você não pode alterar o loop de mensagem do aplicativo cliente. No entanto, você pode modificar o componente .NET Framework para iniciar um novo thread que usa seu próprio loop de mensagem.
Observação Programação multissegmentada é um conceito avançado que requer atenção antes da implementação. Isso é especialmente verdadeiro se vários segmentos devem acessar um recurso compartilhado. Se vários segmentos devem acessar um recurso compartilhado ao mesmo tempo, certifique-se que você criar os componentes do .NET Framework para segurança do thread.Para obter informações adicionais, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
316136
(http://support.microsoft.com/kb/316136/
)
Como sincronizar o acesso a um recurso compartilhado em um ambiente multithread com o Visual Basic .NET
Para criar cada instância de um formulário do Windows em um novo thread, execute essas etapas:
Inicie o Microsoft Visual Studio .NET 2003.
Crie uma biblioteca de classe. Para fazer isso, execute as seguintes etapas:
Use o Visual Basic .NET 2003 para criar um novo projeto Class Library. Nomeie o projeto COMWinform.
Exclua o arquivo Class1.vb de padrão.
No menu Project , clique em Add Class .
Selecione o modelo COM Class .
Na caixa nome , digite COMForm.vb e, em seguida, clique em Abrir .
Cole as seguintes instruções de código na parte superior do arquivo COMForm.vb, antes da definição de classe.
Na definição de classe COMForm, cole o código a seguir no código que foi inserido quando você criou class.
Private 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 form As Form)
' This procedure is used to show all forms
' that the client application requests.
' Later forms will appear on a new message loop.
If IsNothing(frmManager) Then
frmManager = New FormManager
End If
frmManager.ShowForm(form)
End Sub
Protected Overrides Sub Finalize()
frmManager = Nothing
MyBase.Finalize()
End Sub
No menu Project , clique em Add Class .
Clique em Class .
Na caixa nome , digite FormManager.vb e, em seguida, clique em OK .
Replace the contents of the FormManager.vb file with the following code.
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Windows.Forms
<ComVisible(False)> _
Friend Class FormManager
Public Sub ShowForm(ByVal form As Form)
Dim thrd As Thread
Dim wrapper As FormWrapper
wrapper = New FormWrapper(form)
thrd = New Thread(AddressOf wrapper.ShowFormOnNewThread)
thrd.IsBackground = True
thrd.ApartmentState = ApartmentState.STA
thrd.Start()
End Sub
Private Class FormWrapper
Private WithEvents appContext As ApplicationContext
Public Sub New(ByVal form As Form)
MyBase.New()
appContext = New ApplicationContext(form)
End Sub
Public Sub ShowFormOnNewThread()
Application.Run(appContext)
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
End Sub
End Class
End Class
No menu Project , clique em Add Windows Form e, em seguida, clique em Abrir .
Adicione alguns controles TextBox e um botão de comando ao formulário.
Adicione o seguinte código ao manipulador de evento Click do comando botão.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show("Clicked button")
End Sub
Crie a solução. Esta etapa também registra o projeto para interoperabilidade COM neste computador.
Crie um arquivo executável. Para fazer isso, execute as seguintes etapas:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projeto EXE padrão.
No menu Project , clique em referências .
Adicione uma referência à biblioteca de tipos COMWinform foi gerada quando você criou a solução do Visual Basic. NET. Se você não vi-lo na lista, clique em Procurar para localizar o arquivo de biblioteca (.tlb) do tipo manualmente.
Adicione um botão de comando ao formulário.
No menu Exibir , clique em código e, em seguida, adicione o seguinte código para o módulo de formulário.
Option Explicit
Private Sub Command1_Click()
Dim frm As COMWinform.COMForm
Set frm = New COMWinform.COMForm
frm.ShowForm1
End Sub
No menu arquivo , clique em Make EXE para compilar o projeto.
Execute o arquivo executável de Visual Basic 6.0 compilado.
Clique no botão. O Windows Form da biblioteca de classe que você criou anteriormente será exibido.
Definir o foco em um dos controles TextBox no Windows Form e, em seguida, pressione TAB para mover entre os controles.
Observe que a tecla TAB funciona com êxito para mover entre controles. Observe também que o evento Click do botão de comando é acionado quando você pressiona ENTER.
Criar um loop de mensagem compartilhada em um novo segmento no componente do .NET Framework
Esse método é semelhante na seção "Exibir cada Windows Form em um novo thread". No entanto, em vez de exibir cada formulário em seu próprio thread usando seu próprio loop de mensagem, esse método cria um loop de mensagem compartilhada que é executado em apenas um novo segmento no componente do .NET Framework.
Esse método com mais precisão representa o comportamento que teria se estivesse executando um aplicativo Windows Forms padrão. Esse design torna mais fácil compartilhar recursos entre vários formulários, porque todos os formulários são executados no mesmo thread. A solução na seção "Exibir cada Windows Form em um novo thread" cria um novo thread para cada formulário. Essa solução requer código de sincronização do segmento adicionais para compartilhar recursos entre formulários diferentes.
Como esse método é mais semelhante que os outros métodos para o comportamento de um aplicativo Windows Forms, observe que todos os formulários .NET Framework que abre o aplicativo cliente serão fechado quando o loop de mensagem do .NET Framework pára. Esse comportamento ocorre quando o usuário fecha o formulário que é designado como o formulário principal para ApplicationContext . ApplicationContext é usado para iniciar o loop de mensagem.
No exemplo de código a seguir, o formulário principal de ApplicationContext é definido como o primeiro formulário que abre o aplicativo cliente. Portanto, quando o usuário fecha essa instância do formulário, a sai do loop de mensagem .NET Framework e todos os outros formulários do Windows será fechado.
Para criar um loop de mensagem compartilhada em um novo segmento para todos os formulários usar, execute essas etapas:
Inicie o Microsoft Visual Studio .NET 2003.
Crie uma biblioteca de classe. Para fazer isso, execute as seguintes etapas:
Use o Visual Basic .NET 2003 para criar um novo projeto Class Library chamado COMWinform.
Exclua o arquivo Class1.vb de padrão.
No menu Project , clique em Add Class .
Selecione o modelo COM Class .
Na caixa nome , digite COMForm.vb e, em seguida, clique em Abrir .
Cole as seguintes instruções de código na parte superior do arquivo COMForm.vb, antes da definição de classe.
Na definição de classe de COMForm, cole o código a seguir no código que foi inserido quando você criou class.
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
No menu Project , clique em Add Class .
Clique em Class .
Na caixa nome , digite FormManager.vb e, em seguida, clique em OK .
Substituir o conteúdo do arquivo FormManager.vb com o seguinte código.
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.ApartmentState = 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
End Class
No menu Project , clique em Add Windows Form e, em seguida, clique em Abrir .
Adicione alguns controles TextBox e um botão de comando ao formulário.
Adicione o seguinte código ao manipulador de evento Click do comando botão.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show("Clicked button")
End Sub
Crie a solução. Esta etapa também registra o projeto para interoperabilidade COM neste computador.
Crie um arquivo executável. Para fazer isso, execute as seguintes etapas:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projeto EXE padrão.
No menu Project , clique em referências .
Adicione uma referência à biblioteca de tipos COMWinform foi gerada quando você criou a solução do Visual Basic. NET. Se você não vi-lo na lista, clique em Procurar para localizar o arquivo de biblioteca (.tlb) do tipo manualmente.
Adicione um botão de comando ao formulário.
No menu Exibir , clique em código e, em seguida, adicione o seguinte código para o módulo de formulário.
Option Explicit
Private Sub Command1_Click()
Dim frm As COMWinform.COMForm
Set frm = New COMWinform.COMForm
frm.ShowForm1
End Sub
No menu arquivo , clique em Make EXE para compilar o projeto.
Execute o arquivo executável de Visual Basic 6.0 compilado.
Clique no botão. O Windows Form da biblioteca de classe que você criou anteriormente será exibido.
Definir o foco em um dos controles TextBox no Windows Form e, em seguida, pressione TAB para mover entre os controles.
Observe que a tecla TAB funciona com êxito para mover entre os controles. Observe também que o evento Click do botão de comando é acionado quando você pressiona ENTER.
Mensagem de um aplicativo loop é um loop de programa interno que recupera mensagens da fila de mensagens do thread, converte e envia-los para o aplicativo para ser manipulado. O loop de mensagem para um formulário do Windows não tem a mesma arquitetura como loops de mensagem que os aplicativos anteriores, como aplicativos Visual Basic 6.0 e aplicativos MFC, fornecer. As mensagens de janela lançadas para o loop de mensagem podem ser manipuladas diferente que espera que o formulário do Windows. Portanto, pode ocorrer um comportamento inesperado. Algumas combinações de pressionamento de tecla podem não funcionar, alguma atividade de mouse pode não funcionar ou alguns eventos podem não ser disparados conforme o esperado.
Observação Um loop de mensagem do .NET Framework é a arquitetura para os quais há suporte somente para exibição e para usar um Windows Form. As soluções que estão descritas na seção "Resolução" se aplicam apenas a exibir um formulário do Windows. O recipiente para os quais há suporte somente para hospedar um controle do .NET Framework por meio de um COM callable wrapper (CCW) é Microsoft Internet Explorer. Como um controle deve estar em um recipiente, esse controle deve usar o loop de mensagem que fornece o recipiente. Portanto, você não pode usar as soluções que são descritas na seção "Resolução" para um controle do .NET Framework.
Para obter informações adicionais, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
311334
(http://support.microsoft.com/kb/311334/
)
Recipientes de controle ActiveX que oferecem suporte a controles .NET
317346
(http://support.microsoft.com/kb/317346/
)
Controla nativo versus COM-callable .NET no Internet Explorer
Na definição de classe de COMForm, cole o código a seguir no código que foi inserido quando você criou o class.
Public Sub ShowForm1()
' Create an instance of the .NET Windows Form (Form1),
' and then display it
Dim frm As Form1
frm = New Form1
frm.Show
End Sub
End Class
No menu Project , clique em Add Windows Form e, em seguida, clique em Abrir .
Adicione alguns controles TextBox e um botão de comando ao formulário.
Adicione o seguinte código ao manipulador de evento Click do comando botão.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show("Clicked button")
End Sub
Crie a solução. Esta etapa também registra o projeto para interoperabilidade COM neste computador.
Crie um arquivo executável. Para fazer isso, execute as seguintes etapas:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projeto Standard EXE.
No menu Project , clique em referências .
Adicione uma referência à biblioteca de tipos COMWinform foi gerada quando você criou a solução do Visual Basic. NET. Se você não vi-lo na lista, clique em Procurar para localizar o arquivo de biblioteca (.tlb) do tipo manualmente.
Adicione um botão de comando ao formulário.
No menu Exibir , clique em código e, em seguida, adicione o seguinte código para o módulo de formulário.
Option Explicit
Private Sub Command1_Click()
Dim frm As COMWinform.COMForm
Set frm = New COMWinform.COMForm
frm.ShowForm1
End Sub
No menu arquivo , clique em Make EXE para compilar o projeto.
Execute o arquivo executável de Visual Basic 6.0 compilado.
Clique no botão. O Windows Form da biblioteca de classe que você criou anteriormente será exibido.
Definir o foco em um dos controles TextBox no Windows Form e, em seguida, pressione TAB para mover entre os controles. Observe que a tecla TAB não move foco entre os controles conforme o esperado.
Definir o foco no botão de comando no Windows Form e, em seguida, pressione ENTER. Observe que o botão não responde e o evento Click não é disparado.
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 839076
(http://support.microsoft.com/kb/839076/en-us/
)
Quanto esforço foi necessário para seguir os procedimentos deste artigo?
Muito baixo
Baixo
Moderado
Alto
Muito alto
Diga-nos o porque e o que podemos fazer para melhorar esta informação
Obrigado! Seus comentários são usados para nos ajudar a aperfeiçoar o conteúdo de suporte. Para obter mais opções de ajuda, visite a Home Page de Ajuda e Suporte.