Question

Dans une demande de C Win32, nous commençons une boucle de message qui va chercher les messages d'une file d'attente, les traduit, puis les envoie. Finalement, chaque message atteint notre WndProc où peut être géré l'événement associé.

Je comprends cette partie. Ce que je ne comprends pas est entre allées et venues. Plus précisément:

  1. Différents types de systèmes d'exploitation des gestionnaires d'interruption doivent être placer des messages dans ladite file d'attente de message ", mais où dans l'espace d'adressage du processus ne réside cette file d'attente? Comment est-il exposé au code de gestionnaire d'interruption?
  2. Qu'est-ce que cela signifie pour « traduire » le message? Qu'est-ce que l'appel à TranslateMessage() vraiment faire?
  3. Une fois envoyé par DispatchMessage(), ce que tous les lieux ne le message balancer par avant d'atteindre mon WndProc (à savoir qu'est-ce que le système d'exploitation faire avec elle)?

Si quelqu'un connaît les réponses à ce qui précède, de bien vouloir satisfaire ma curiosité. Merci.

Était-ce utile?

La solution

Le système d'exploitation maintient une file d'attente de message, où il met les événements (par exemple d'interruptions ou d'autres sources). Il envoie ensuite les messages de cette file d'attente à toutes les fenêtres, en fonction du message (par exemple, il ne sera pas envoyer des messages clés à une fenêtre qui ne possède pas le focus).

Les applications peuvent avoir leur propre file d'attente pour traiter les messages. Ces files d'attente sont créés sur demande (uniquement en cas de besoin ).

Traduire un message est utilisé pour créer des messages qui ne sont pas des événements « réels ». Par exemple, le message WM_CONTEXTMENU est « traduit » soit d'une souris clic droit, ou sur la touche de menu contextuel ou Maj-F10. Le WM_CHAR est traduit de messages WM_KEYDOWN. Et bien sûr, beaucoup d'autres messages sont « traduits » de cette façon.

Un message est affiché à chaque fenêtre qui devrait le recevoir. Le système d'exploitation décide en fonction du type de message si une fenêtre doit recevoir ce message ou non. La plupart des messages sont attendus par le système, à savoir, le message ne sera pas affiché à une autre fenêtre jusqu'à ce qu'il soit traité par la fenêtre. Cela a un grand impact pour les messages de diffusion: si une fenêtre ne retourne pas lors de la manipulation de ce message, la file d'attente est bloqué et d'autres fenêtres ne le message plus.

Autres conseils

Cela dépend de la façon dont votre message est envoyé et la façon dont il est géré.

Lorsque vous appelez SendMessage, si la fenêtre cible est la propriété du thread courant, l'appel contourne la file d'attente de messages pour la fenêtre et le gestionnaire de fenêtres appelle directement la WindowProc sur la fenêtre cible. Si la fenêtre cible appartient à un autre thread, le gestionnaire de fenêtres appelle efficacement PostMessage et pompes messages de fenêtre jusqu'à ce que la fenêtre retourne cible de la fenêtre proc.

Lorsque vous appelez PostMessage, les maréchaux de gestionnaire de fenêtre les paramètres de message et insère l'objet correspondant sur la file d'attente de messages pour la fenêtre cible. Quand il appelle GetMessage le message est supprimé de la file d'attente de messages.

Le gestionnaire de fenêtres enregistre également pour les événements d'entrée brutes à partir des périphériques d'entrée (clavier et / ou souris) et il génère des messages pour les événements d'entrée. Il insère ensuite ces messages dans la file d'attente, selon le cas (le traitement des événements d'entrée est compliquée, car il dépend de ce que les messages sont déjà dans la file d'attente de messages pour la fenêtre).

Comme indiqué Stefan, TranslateMessage traduit simplement les touches de raccourci -. Par exemple, il convertit les séquences de touches à WM_COMMAND messages

  

Différents types de systèmes d'exploitation des gestionnaires d'interruption doivent être placer des messages dans ladite file d'attente de message ", mais où dans l'espace d'adressage du processus ne réside cette file d'attente? Comment est-il exposé au code de gestionnaire d'interruption?

Les fenêtres sont associés à des fils. Chaque fil avec une fenêtre a une file d'attente du fil dans l'espace d'adresse du processus. Le système d'exploitation a une file d'attente interne dans son propre espace d'adressage pour les événements générés par le matériel. Utilisation détails de l'événement et d'autres informations d'état (par exemple, la fenêtre qui a le focus), le système d'exploitation se traduit par les événements matériels dans des messages qui sont ensuite placés dans la file d'attente de fil appropriée.

Les messages qui sont affichés sont placés directement dans la file d'attente de message pour la fenêtre cible.

Les messages envoyés sont habituellement traitées directement (sans passer par la file d'attente).

Les détails se poilue. Par exemple, les files d'attente de fil sont plus de listes de messages - ils conservent également des informations d'état. Certains messages (comme WM_PAINT) ne sont pas vraiment mis en attente, mais synthétisés à partir des informations d'état supplémentaires lorsque vous interrogez la file d'attente et il est vide. Les messages envoyés aux fenêtres appartenant à d'autres sujets sont affichés en fait à plutôt que la file d'attente du récepteur en cours de traitement directement, mais le système fait apparaître comme un blocage régulier envoyer du point de vue de l'appelant. L'hilarité est si cela peut provoquer une impasse (à cause de la circulaire renvoie au fil d'origine).

Les livres Jeffrey Richter ont beaucoup (tout?) Des détails sordides. Mon édition est ancien (Advanced Windows). L'édition actuelle semble être appelé Windows via C / C ++ .

Le système d'exploitation fait beaucoup de travail pour rendre le flux de messages semble rationnel (et relativement simple) à l'appelant.

  

Qu'est-ce que cela signifie pour « traduire » le message? Qu'est-ce que l'appel à TranslateMessage () vraiment faire?

Il surveille les messages clés pour virtuels et, lorsqu'il reconnaît une clé appuyée / combinaison de touches-up, il ajoute des messages de caractère. Si vous ne l'appelez pas TranslateMessage , vous ne recevrez pas de messages de caractère comme WM_CHAR.

Je pense qu'il envoie le message de caractère directement avant de retourner (par opposition à les afficher). Je ne l'ai jamais vérifié, mais je crois me rappeler que les messages arrivent WM_CHAR juste avant le WM_KEYUP.

  

Une fois envoyé par DispatchMessage (), ce que tous les lieux ne le swing de message en avant d'atteindre mon WndProc (à savoir qu'est-ce que le système d'exploitation faire avec elle)?

DispatchMessage transmet le message à l'WndProc pour la fenêtre cible. En cours de route, il quelques crochets peut avoir une chance de voir le message (et éventuellement interférer avec elle).

Pour répondre à la dernière subquestion, un message envoyé sera à votre WindowProc après qu'il a été par tous les crochets canalisé (WH_CALLWNDPROC)

Pas tout à fait positif à ce sujet, mais ma meilleure estimation dit:

  1. La file d'attente est un objet système que vous accédez à des appels API Win32. Il est pas dans l'espace d'adressage de processus du tout. Ainsi, les gestionnaires d'interruption peuvent y accéder (probablement à travers la HAL (Hardware Abstraction Layer) du noyau).

  2. Dans Win16, cet appel a pris les différentes sous-parties d'un plus grand message et les écrasa dans son ensemble. Alors TranslateMessage ajouterait l'WM_KEYPRESS quand il a trouvé la séquence correspondante WM_KEYDOWN WM_KEYUP. Il tournerait également divers messages Cliquez sur le bouton dans les messages Doubleclick en fonction de réglage interne et les horodatages des messages. Que ce soit le fait encore dans Win32, je ne sais pas.

  3. DispatchMessage est probablement où des crochets de message de fenêtre se traiter. Donc, s'il y a un crochet sur la fenêtre, il est appelé soit ici ou lorsque le GetMessage est appelé. Je ne suis pas sûr. A part cela, DispatchMessage regarde juste l'adresse WndProc associée à la fenêtre et l'appelle. Il n'y a pas beaucoup d'autre pour ce faire.

L'espoir qui aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top