Pergunta

Na aplicação de um Win32 C ++, começamos um loop de mensagem que obtém mensagens de uma fila, traduz-los e, em seguida, envia-los. Eventualmente, cada mensagem atinge nosso WndProc onde o evento associado podem ser manipulados.

Eu entendo essa parte. O que eu não entendo é o entre vir-nos. Especificamente:

  1. Diferentes tipos de OS manipuladores de interrupção deve ser mensagens colocando no referido 'fila de mensagens', mas onde no espaço de endereço de processo faz isso reside fila? Como é exposto ao código de manipulador de interrupção?
  2. O que significa 'traduzir' a mensagem? O que faz a chamada para TranslateMessage() realmente fazer?
  3. Uma vez despachado pelo DispatchMessage(), o que todos lugares faz o balanço mensagem, antes de chegar a minha WndProc (ou seja, o que os OS fazer com ele)?

Se alguém souber as respostas para os itens acima, gentilmente satisfazer a minha curiosidade. Obrigado.

Foi útil?

Solução

O sistema operacional mantém uma fila de mensagens, onde ele coloca os eventos (por exemplo, a partir de interrupções ou outras fontes). Em seguida, envia as mensagens dessa fila para todas as janelas, dependendo da mensagem (por exemplo, ele não enviará mensagens-chave para uma janela que não tem foco).

Os aplicativos podem ter sua própria fila para processar mensagens. Essas filas são criadas a pedido (apenas se necessário ).

Traduzindo uma mensagem é usada para criar mensagens que não são eventos 'reais'. Por exemplo, a mensagem WM_CONTEXTMENU é 'traduzido' a partir de um clique do mouse direito do mouse ou a tecla de menu de contexto, ou shift-F10. O WM_CHAR é traduzido a partir de mensagens WM_KEYDOWN. E, claro, muitas outras mensagens são 'traduzidos' dessa forma.

Uma mensagem é enviada para todas as janelas que deve recebê-lo. O sistema operacional decide dependendo do tipo de mensagem se uma janela deve receber a mensagem ou não. A maioria das mensagens são esperou pelo sistema, ou seja, a mensagem não será postado para outra janela, até que foi processado pela janela. Isto tem um grande impacto para mensagens de transmissão: se uma janela não retornar ao manusear essa mensagem, a fila é bloqueada e outras janelas não receberá a mensagem mais.

Outras dicas

Depende de como sua mensagem é enviada e como ele é tratado.

Quando você chama SendMessage, se a janela de destino é de propriedade do thread atual, a chamada ignora a fila de mensagens para a janela e o gerenciador de janelas chama diretamente o WindowProc na janela de destino. Se a janela de destino é propriedade de outro segmento, o gerenciador de janelas efetivamente chama PostMessage e bombas mensagens de janela até que a janela de destino retornos do proc janela.

Quando você chamar PostMessage, os marechais gerenciador de janelas os parâmetros de mensagem e insere o objeto correspondente na fila de mensagens para a janela de destino. Quando próxima chama GetMessage a mensagem é removida da fila de mensagens.

O gerenciador de janelas também registra para eventos brutos de entrada dos dispositivos de entrada (teclado e / ou mouse) e gera mensagens para esses eventos de entrada. Em seguida, insere essas mensagens na fila, conforme apropriado (o processamento de eventos de entrada é complicada porque depende do que mensagens já estão na fila de mensagens para a janela).

Como Stefan indicado, TranslateMessage apenas traduz teclas de atalho -., Por exemplo, ele converte seqüências de teclas para WM_COMMAND mensagens

Diferentes tipos de OS manipuladores de interrupção deve ser mensagens colocando no referido 'fila de mensagens', mas onde no espaço de endereço de processo faz isso reside fila? Como é exposto ao código de manipulador de interrupção?

Windows estão associados com threads. Cada segmento com uma janela tem uma fila segmento em espaço de endereço do processo. A OS tem uma fila interna em seu próprio espaço de endereço para os eventos gerados pelo hardware. Usando detalhes das informações do evento e outro estado (por exemplo, que a janela tem o foco), o sistema operacional traduz os eventos de hardware em mensagens que são então colocados na fila de linha apropriada.

As mensagens que são destacados são colocados directamente na fila de rosca para a janela de destino.

mensagens que são enviadas são normalmente processados ??directamente (ignorando a fila).

Os detalhes se complicar. Por exemplo, as filas de rosca são mais do que listas de mensagens - eles também mantêm algumas informações do estado. Algumas mensagens (como WM_PAINT) não são realmente na fila, mas sintetizado a partir da informação estado adicional quando você consulta a fila e ele está vazio. As mensagens enviadas para janelas pertencentes a outros tópicos são realmente enviados para a fila do receptor ao invés de serem processados ??diretamente, mas o sistema faz com que pareça como um envio de bloqueio normal do ponto de vista do autor da chamada. ensues hilaridade se isso pode causar impasse (por causa de circular envia de volta para o segmento original).

Os livros Jeffrey Richter ter um monte (todos?) Dos detalhes sórdidos. Minha edição é velho (Advanced Windows). A edição atual parece ser chamado Windows via C / C ++ .

O sistema operacional faz um monte de trabalho para fazer o fluxo de mensagem aparecer racional (e relativamente simples) para o chamador.

O que significa 'traduzir' a mensagem? O que faz a chamada para TranslateMessage () realmente fazer?

relógios para as principais mensagens virtuais e, quando reconhece uma combinação de teclas para baixo / key-up, ele adiciona mensagens de caráter. Se você não chamar TranslateMessage , você não receberá mensagens de caráter como WM_CHAR.

Eu suspeito que ele envia a mensagem de caracteres diretamente antes de retornar (ao contrário de publicá-las). Eu nunca marcada, mas eu me lembro que as mensagens WM_CHAR chegar um pouco antes da WM_KEYUP.

Uma vez despachado pelo DispatchMessage (), o que todos os lugares faz o balanço mensagem, antes de chegar a minha WndProc (ou seja, o que os OS fazer com ele)?

DispatchMessage passa a mensagem para o WndProc para a janela de destino. Ao longo do caminho, ele alguns ganchos podem ter a chance de ver a mensagem (e possivelmente interferir com ele).

Para abordar o último subquestão, uma mensagem vai para o seu WindowProc despachado depois de ter sido canalizada através de todos os ganchos (WH_CALLWNDPROC)

Não absolutamente positivo sobre isso, mas meu melhor palpite diz:

  1. A fila é um objecto de sistema que você acessa com chamadas de API Win32. Não está no seu espaço de endereços do processo em tudo. Assim, os manipuladores de interrupção pode acessá-lo (provavelmente através do HAL (Hardware Abstraction Layer) do kernel).

  2. Em Win16, essa chamada tomou as várias sub-partes de uma mensagem maior e purê-los em um todo. Então TranslateMessage acrescentaria o WM_KEYPRESS quando encontrou a seqüência WM_KEYDOWN WM_KEYUP correspondente. Ele também iria transformar várias mensagens botão de clique em mensagens da DoubleClick com base na configuração interna e a data e hora das mensagens. Se ele ainda faz isso em Win32, eu não sei.

  3. DispatchMessage é provavelmente onde ganchos mensagem da janela são processadas. Portanto, se há um gancho na sua janela, ou é chamado aqui ou quando o GetMessage é chamado. Não tenho certeza. Fora isso, DispatchMessage apenas procura o endereço WndProc associado com a janela e chama. Não há muito mais para fazer.

Espero que ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top