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 abre uma instância de um formulário de Windows da Microsoft a partir de uma aplicação de cliente COM, tal como uma aplicação do Microsoft Visual Basic 6.0 ou uma aplicação Microsoft Foundation Classes (MFC), o formulário de Windows .NET poderão ter um comportamento inesperado. Por exemplo, quando prime TAB, o foco não muda de um controlo a outro controlo. Ou quando prime ENTER enquanto um botão de comando tiver o foco, o evento Click do botão não é despoletado. Poderá também detectar um comportamento inesperado para batimentos de teclas ou para a actividade do rato.
Estes sintomas ocorrem porque a aplicação anterior não implementa o suporte de ciclo de mensagem de um formulário do .NET Framework Windows necessita para funcionar correctamente.
Este artigo descreve como resolver estes problemas, apresentando o formulário num ciclo de mensagem do .NET Framework que criar utilizando o método Application.Run .
Quando cria uma instância de um formulário de Windows da Microsoft de uma aplicação de cliente COM, o formulário poderá apresentar um comportamento inesperado. Por exemplo, quando cria uma instância do formulário a partir de uma aplicação do Microsoft Visual Basic 6.0 ou a partir de uma aplicação Microsoft Foundation Classes (MFC), o foco não muda de um controlo a outro controlo quando prime TAB. Ou, se premir ENTER enquanto um botão de comando tiver o foco, o evento Click do botão não é despoletado. Poderá também detectar um comportamento inesperado para batimentos de teclas ou para a actividade do rato.
Este problema ocorre porque o ciclo de mensagem que utiliza o formulário de Windows e o ciclo de mensagem que fornece a aplicação de cliente COM são diferentes.
A Microsoft tomou uma alteração para resolver este problema de estrutura. Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
885446
(http://support.microsoft.com/kb/885446/
)
CORRECÇÃO: Poderá detectar um comportamento inesperado quando prime TAB ou ENTER no formulário de Windows num computador que esteja a executar o S do .NET Framework 1.1
Este artigo descreve como resolver este problema, apresentando o formulário num ciclo de mensagem do .NET Framework que criar utilizando o método Application.Run .
Utilize o método ShowDialog para apresentar o formulário do Windows
Esta é a solução mais fácil para apresentar o formulário num ciclo de mensagem do .NET Framework. Para o fazer, substitua as chamadas para o método Mostrar chamadas para o método ShowDialog seu componente .NET Framework.
O método ShowDialog suspende o ciclo de mensagens da aplicação anterior e apresenta o formulário como uma caixa de diálogo. Uma vez que ciclo de mensagem a aplicação inicial foi suspenso, o método ShowDialog cria um novo ciclo de mensagem .NET Framework para processar mensagens do formulário. Esta é a solução mais fácil porque requer o código de mínimo para implementar. No entanto, a desvantagem desta abordagem é que o formulário será aberto de forma modal. Este comportamento bloqueia qualquer interface de utilizador (UI) da aplicação chamada enquanto o formulário do Windows estiver aberto. Quando o utilizador fecha o formulário do Windows, o .NET Framework sai do ciclo de mensagem e mensagem a aplicação anterior repetir currículos em execução.
Apresentar cada formulário do Windows num novo thread
Modificar o componente do .NET Framework para apresentar cada instância de um formulário no seu próprio thread utilizando o respectivo ciclo de mensagem. Não pode ter mais do que um ciclo de mensagem por thread a ser executado. Por conseguinte, não pode alterar ciclo de mensagem a aplicação cliente. No entanto, pode modificar o componente do .NET Framework para iniciar um novo thread que utiliza o respectivo ciclo de mensagem.
Nota Programação multithread é um conceito avançado que requer cuidadosa consideração antes de implementação. Isto é particularmente verdade se vários threads tem de aceder um recurso partilhado. Se vários threads tem aceder um recurso partilhado ao mesmo tempo, certifique-se de que criar os componentes do .NET Framework para segurança de thread.Para obter informações adicionais, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
316136
(http://support.microsoft.com/kb/316136/
)
Como sincronizar o acesso a um recurso partilhado num ambiente multithreading com Visual Basic .NET
Para criar cada instância de um formulário de Windows num novo thread, siga estes passos:
Inicie o Microsoft Visual Studio .NET 2003.
Crie uma biblioteca de classe. Para o fazer, siga estes passos:
Utilize Visual Basic .NET 2003 para criar um novo projecto de biblioteca de classes. Nome do projecto COMWinform.
Elimine o ficheiro de Class1.vb predefinido.
No menu projecto , clique em Adicionar classe .
Seleccione o modelo COM classe .
Na caixa nome , escreva COMForm.vb e, em seguida, clique em Abrir .
Cole as seguintes instruções de código na parte superior do ficheiro COMForm.vb, antes da definição de classe.
Na definição de classe COMForm, cole o código seguinte em código que foi inserido quando criou o 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 projecto , clique em Adicionar classe .
Clique em classe .
Na caixa nome , escreva 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 projecto , clique em Adicionar formulário de Windows e, em seguida, clique em Abrir .
Adicione alguns controlos de caixa de texto e um botão de comando ao formulário.
Adicione o seguinte código ao processador de evento clicar o botão de comando.
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. Este passo também regista o projecto para interoperabilidade COM neste computador.
Crie um ficheiro executável. Para o fazer, siga estes passos:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projecto EXE padrão.
No menu projecto , clique em References .
Adicione uma referência à biblioteca de tipos COMWinform que foi gerada quando é criado a solução do Visual Basic. NET. Se não visualizá-lo na lista, clique em Procurar para localizar o ficheiro de biblioteca de (tipos.tlb) do tipo manualmente.
Adicionar um botão de comando ao formulário.
No menu Ver , clique em código e 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 ficheiro , clique em Criar EXE para compilar o projecto.
Execute o ficheiro executável de Visual Basic 6.0 compilado.
Clique no botão. Aparece o formulário de Windows da biblioteca de classe que criou anteriormente.
Definir o foco dos controlos de caixa de texto no formulário do Windows e, em seguida, prima TAB para se deslocar entre os controlos.
Repare que a tecla TAB funciona com êxito para percorrer os controlos. Para além disso, repare que clique evento o botão de comando é accionado quando prime ENTER.
Criar um ciclo de mensagens partilhada num novo thread no componente do .NET Framework
Este método é semelhante na secção "Mostrar cada forma de Windows num novo thread". No entanto, em vez de apresentar cada formulário no seu próprio thread utilizando o respectivo ciclo de mensagem, este método cria um ciclo de mensagens partilhada compatível com apenas um novo thread no componente do .NET Framework.
Este método com mais precisão representa o comportamento que teria se estivesse a executar uma aplicação Windows Forms padrão. Esta estrutura também facilita a partilhar recursos entre vários formulários, uma vez que todos os formulários são executados no mesmo thread. A solução na secção "Mostrar cada forma de Windows num novo thread" cria um novo thread para cada formulário. Essa solução requer código de sincronização de thread adicionais para partilhar recursos entre diferentes formatos.
Uma vez que este método é mais semelhante de outros métodos ao comportamento de uma aplicação Windows Forms, repare que todos os formulários do .NET Framework que abre a aplicação cliente fechará quando pára o ciclo de mensagem do .NET Framework. Este comportamento ocorre quando o utilizador fecha o formulário é designado como o formulário principal para ApplicationContext . ApplicationContext é utilizado para iniciar o ciclo de mensagem.
No seguinte exemplo de código, a forma principal de ApplicationContext está definida para o primeiro formulário que abre a aplicação cliente. Por conseguinte, quando o utilizador fecha essa instância de formulário, sai de ciclo de mensagem o .NET Framework e todos os formulários do Windows será encerrada.
Para criar um ciclo de mensagens partilhada num novo thread para todos os formulários utilizar, siga estes passos:
Inicie o Microsoft Visual Studio .NET 2003.
Crie uma biblioteca de classe. Para o fazer, siga estes passos:
Utilize Visual Basic .NET 2003 para criar um novo projecto de biblioteca de classes com o nome COMWinform.
Elimine o ficheiro de Class1.vb predefinido.
No menu projecto , clique em Adicionar classe .
Seleccione o modelo COM classe .
Na caixa nome , escreva COMForm.vb e, em seguida, clique em Abrir .
Cole as seguintes instruções de código na parte superior do ficheiro COMForm.vb, antes da definição de classe.
Na definição de classe COMForm, cole o seguinte código em código que foi inserido quando criou o 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 projecto , clique em Adicionar classe .
Clique em classe .
Na caixa nome , escreva FormManager.vb e, em seguida, clique em OK .
Substituir o conteúdo do ficheiro 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 projecto , clique em Adicionar formulário de Windows e, em seguida, clique em Abrir .
Adicione alguns controlos de caixa de texto e um botão de comando ao formulário.
Adicione o seguinte código ao processador de evento clicar o botão de comando.
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. Este passo também regista o projecto para interoperabilidade neste computador.
Crie um ficheiro executável. Para o fazer, siga estes passos:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projecto EXE padrão.
No menu projecto , clique em References .
Adicione uma referência à biblioteca de tipos COMWinform que foi gerada quando é criado a solução do Visual Basic. NET. Se não visualizá-lo na lista, clique em Procurar para localizar o ficheiro de biblioteca de (tipos.tlb) do tipo manualmente.
Adicionar um botão de comando ao formulário.
No menu Ver , clique em código e 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 ficheiro , clique em Criar EXE para compilar o projecto.
Execute o ficheiro executável de Visual Basic 6.0 compilado.
Clique no botão. Aparece o formulário de Windows da biblioteca de classe que criou anteriormente.
Definir o foco dos controlos de caixa de texto no formulário do Windows e, em seguida, prima TAB para se deslocar entre os controlos.
Repare que a tecla TAB funciona com êxito para mover entre os controlos. Para além disso, repare que clique evento o botão de comando é accionado quando prime ENTER.
Mensagem de uma aplicação ciclo é um ciclo de programa interno que obtém mensagens da fila de mensagem de um thread, converte-os e, em seguida, envia-os para a aplicação a ser processado. O ciclo de mensagem para um formulário do Windows não tem a mesma arquitectura como ciclos de mensagem que aplicações anteriores, tais como aplicações do Visual Basic 6.0 e aplicações de MFC, fornecem. As mensagens de janela que são enviadas para o ciclo de mensagem podem ser processadas diferente do que o formulário de Windows espera. Assim, poderá ocorrer um comportamento inesperado. Algumas combinações de teclas poderão não funcionar, algumas actividades do rato poderão não funcionar ou alguns eventos não podem lançar conforme esperado.
Nota Um ciclo de mensagem do .NET Framework é a arquitectura suportada apenas para apresentar e para utilizar um formulário do Windows. As soluções que são descritas na secção "Resolução" só se aplicam apresentar um formulário do Windows. O contentor de suportadas apenas para hospedar um controlo de .NET Framework através de um wrapper de chamada de COM (CCW) é o Microsoft Internet Explorer. Uma vez que um controlo tem de ser um contentor, esse controlo tem de utilizar o ciclo de mensagem que fornece o contentor. Assim, não poderá utilizar as soluções que são descritas na secção "Resolução" para um controlo de .NET Framework.
Para obter informações adicionais, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
311334
(http://support.microsoft.com/kb/311334/
)
Contentores de controlo ActiveX que suportem controlos .NET
317346
(http://support.microsoft.com/kb/317346/
)
Controla o nativo versus .NET COM chamada no Internet Explorer
Na definição de classe COMForm, cole o seguinte código em código que foi inserido quando 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 projecto , clique em Adicionar formulário de Windows e, em seguida, clique em Abrir .
Adicione alguns controlos de caixa de texto e um botão de comando ao formulário.
Adicione o seguinte código ao processador de evento clicar o botão de comando.
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. Este passo também regista o projecto para interoperabilidade neste computador.
Crie um ficheiro executável. Para o fazer, siga estes passos:
Inicie o Microsoft Visual Basic 6.0.
Crie um novo projecto EXE padrão.
No menu projecto , clique em References .
Adicione uma referência à biblioteca de tipos COMWinform que foi gerada quando é criado a solução do Visual Basic. NET. Se não visualizá-lo na lista, clique em Procurar para localizar o ficheiro de biblioteca de (tipos.tlb) do tipo manualmente.
Adicionar um botão de comando ao formulário.
No menu Ver , clique em código e 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 ficheiro , clique em Criar EXE para compilar o projecto.
Execute o ficheiro executável de Visual Basic 6.0 compilado.
Clique no botão. Aparece o formulário de Windows da biblioteca de classe que criou anteriormente.
Definir o foco dos controlos de caixa de texto no formulário do Windows e, em seguida, prima TAB para se deslocar entre os controlos. Repare que a tecla TAB não move foco entre os controlos como previsto.
Definir o foco no botão de comando no formulário Windows e, em seguida, prima ENTER. Repare que o botão não está a responder e o evento clicar não é despoletado.
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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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/
)
Qual foi o esforço que despendeu pessoalmente para utilizar este artigo?
Muito baixo
Baixo
Moderado
Elevado
Muito elevado
Diga-nos porquê e o que podemos fazer para melhorar estas informações
Obrigado! Os seus comentários são utilizados para ajudar-nos a melhorar o conteúdo do nosso suporte. Para obter mais opções de assistência, visite a Home Page de Ajuda e Suporte.