Domanda

In applicazione di Win32 C ++, iniziamo un ciclo di messaggi che recupera i messaggi da una coda, li traduce e poi li invia. Alla fine, ogni messaggio raggiunge il nostro WndProc in cui l'evento associato può essere gestito.

Capisco che parte. Quello che non capisco è il tra viavai. In particolare:

  1. I vari tipi di gestori di interrupt del sistema operativo deve essere trasmettere i messaggi in detto 'coda di messaggi', ma dove nello spazio di indirizzi del processo questa coda fa risiedere? Come è esposto al codice di gestore di interrupt?
  2. Che cosa significa a 'tradurre' il messaggio? Che cosa significa la chiamata a TranslateMessage() davvero fare?
  3. Una volta inviato da DispatchMessage(), quello che tutti i luoghi significa il messaggio swing prima di raggiungere il mio WndProc (vale a dire che cosa fa il sistema operativo fare con esso)?

Se qualcuno conosce le risposte a quanto sopra, gentilmente soddisfare la mia curiosità. Grazie.

È stato utile?

Soluzione

Il sistema operativo mantiene una coda di messaggi, dove mette gli eventi (ad esempio, da interruzioni o da altre fonti). Quindi invia i messaggi da quella coda a tutte le finestre, a seconda del messaggio (ad esempio, sarà di non inviare messaggi chiave ad una finestra che non ha messa a fuoco).

Le applicazioni possono avere la propria coda per elaborare i messaggi. Queste code vengono creati su richiesta (solo se necessario ).

La traduzione di un messaggio viene utilizzato per creare messaggi che non sono gli eventi 'reali'. Ad esempio, il messaggio WM_CONTEXTMENU è il tasto del menu contestuale 'tradotto' sia da un clic destro del mouse, o, o SHIFT-F10. Il WM_CHAR è tradotto da messaggi WM_KEYDOWN. E, naturalmente, molti altri messaggi vengono 'tradotti' in quel modo.

Un messaggio viene inviato a ogni finestra che dovrebbe riceverlo. Il sistema operativo decide a seconda del tipo di messaggio se una finestra deve ricevere quel messaggio o meno. La maggior parte dei messaggi sono aspettato dal sistema, vale a dire, il messaggio non verrà inviato a un'altra finestra fino a quando non è stato elaborato dalla finestra. Questo ha un grande impatto per i messaggi broadcast: se una finestra non restituisce durante la manipolazione che il messaggio, la coda è bloccato e altre finestre non riceveranno più il messaggio.

Altri suggerimenti

Dipende da come viene inviato il messaggio e come è gestita.

Quando si chiama SendMessage, se la finestra di destinazione è di proprietà del thread corrente, la chiamata bypassa la coda di messaggi per la finestra ed il window manager chiama direttamente il WindowProc sulla finestra di destinazione. Se la finestra di destinazione è di proprietà di un altro thread, il window manager chiama efficacemente PostMessage e pompe di messaggi di finestra fino a quando la finestra di destinazione ritorna dalla finestra proc.

Quando si chiama PostMessage, i window manager marescialli i parametri del messaggio e inserisce l'oggetto corrispondente sulla coda di messaggi per la finestra di destinazione. Quando si chiama il prossimo GetMessage il messaggio viene rimosso dalla coda dei messaggi.

Il window manager registra anche per eventi prime in ingresso dai dispositivi di input (tastiera e / o mouse) e genera messaggi per quegli eventi di input. E poi inserisce i messaggi in coda a seconda dei casi (l'elaborazione degli eventi di input è complicato perché dipende da quali messaggi sono già in coda di messaggi per la finestra).

Come indicato Stefan, TranslateMessage solo traduce tasti di scelta rapida -. Per esempio converte sequenze di tasti per i messaggi WM_COMMAND

  

I vari tipi di gestori di interrupt del sistema operativo deve essere trasmettere i messaggi in detto 'coda di messaggi', ma dove nello spazio di indirizzi del processo questa coda fa risiedere? Come è esposto al codice di gestore di interrupt?

di Windows sono associati con i thread. Ogni thread con una finestra ha una coda di filo nello spazio degli indirizzi del processo. Il sistema operativo ha una coda interna nel proprio spazio di indirizzi per gli eventi hardware-generated. Utilizzando i dettagli della manifestazione e altre informazioni di stato (ad esempio, quale finestra ha il focus), il sistema operativo si traduce gli eventi hardware in messaggi che vengono poi inseriti nella coda filo appropriata.

I messaggi che vengono pubblicati sono collocati direttamente nella coda filo per la finestra di destinazione.

I messaggi inviati vengono solitamente gestiti direttamente (bypassando la coda).

I dettagli diventano pelose. Ad esempio, le code di thread sono più di elenchi di messaggi - mantengono anche alcune informazioni di stato. Alcuni messaggi (come WM_PAINT) non sono realmente in coda, ma sintetizzati dalle informazioni di stato supplementare quando si esegue una query la coda ed è vuota. I messaggi inviati a finestre di proprietà di altri thread sono in realtà inviati alla coda del ricevitore anziché essere elaborati direttamente, ma il sistema fa sembrare come un blocco normale inviare dal punto di vista del chiamante. Ilarità consegue se questo può causare deadlock (a causa della circolare rimanda al thread originale).

I libri di Jeffrey Richter hanno molti (tutti?) I dettagli cruenti. La mia edizione è vecchio (Advanced Windows). L'edizione attuale sembra essere chiamato Windows tramite C / C ++ .

Il sistema operativo fa un sacco di lavoro per rendere il flusso di messaggi appare razionale (e relativamente semplice) al chiamante.

  

Che cosa significa a 'tradurre' il messaggio? Che cosa significa la chiamata a TranslateMessage () davvero fare?

E orologi per messaggi chiave virtuali e, quando riconosce un / combinazione di tasti-up chiave-down, aggiunge i messaggi di carattere. Se non si chiama TranslateMessage , non sarà possibile ricevere messaggi di carattere come WM_CHAR.

Ho il sospetto che invia il messaggio di carattere direttamente prima di tornare (al contrario di loro distacco). Non ho mai controllato, ma mi sembra di ricordare che i messaggi WM_CHAR arrivano poco prima della WM_KEYUP.

  

Una volta inviato da DispatchMessage (), che tutti i luoghi fa il messaggio swing prima di raggiungere il mio WndProc (vale a dire che cosa fa il sistema operativo fare con esso)?

DispatchMessage passa il messaggio al WndProc per la finestra di destinazione. Lungo il percorso, che alcuni ganci può avere la possibilità di vedere il messaggio (e possibilmente interferire con esso).

Per affrontare l'ultima subquestion, un messaggio inviato andrà al tuo WindowProc dopo che è stato convogliato attraverso tutti i ganci (WH_CALLWNDPROC)

Non assolutamente positivo su questo ma la mia ipotesi migliore, dice:

  1. La coda è un oggetto di sistema a cui si accede con le chiamate API Win32. Non è nel vostro processo di spazio di indirizzamento a tutti. Così i gestori di interrupt possono accedervi (probabilmente attraverso l'HAL (Hardware Abstraction Layer) del kernel).

  2. In Win16, che chiamata ha avuto i vari sotto parti di un messaggio più grande e li schiacciato in un tutto. Così TranslateMessage aggiungerebbe il WM_KEYPRESS quando si trovò la corrispondente sequenza di WM_KEYDOWN WM_KEYUP. Sarebbe anche girare vari messaggi fare clic sul pulsante in messaggi di DoubleClick basate su ambiente interno e il timestamp dei messaggi. Sia che si fa ancora presente in Win32, non lo so.

  3. DispatchMessage è probabilmente dove ganci dei messaggi finestra Ottieni elaborati. Quindi, se c'è un gancio sulla vostra finestra, si sia chiamato qui o quando la si chiama GetMessage. Non ne sono sicuro. Oltre a questo, DispatchMessage appena cerca l'indirizzo WndProc associato alla finestra e lo chiama. Non c'è molto altro da fare da fare.

La speranza che aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top