Condivisione dei cicli di messaggi tra Win32 e WPFSharing Message Loops Between Win32 and WPF

In questo argomento viene descritto come implementare un ciclo di messaggi per l'interoperabilità con Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF), tramite l'utilizzo esistente messaggio esposizione del ciclo in Dispatcher oppure creando un ciclo di messaggi separati sul Win32Win32 lato del codice di interoperabilità.This topic describes how to implement a message loop for interoperation with Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF), either by using existing message loop exposure in Dispatcher or by creating a separate message loop on the Win32Win32 side of your interoperation code.

ComponentDispatcher e il ciclo di messaggiComponentDispatcher and the Message Loop

Uno scenario comune di supporto degli eventi di interoperabilità e la tastiera consiste nell'implementare IKeyboardInputSink, o di sottoclassi da classi che implementano già IKeyboardInputSink, ad esempio HwndSource o HwndHost.A normal scenario for interoperation and keyboard event support is to implement IKeyboardInputSink, or to subclass from classes that already implement IKeyboardInputSink, such as HwndSource or HwndHost. Tuttavia, il supporto del sink di tastiera non soddisfare tutte le esigenze ciclo possibile messaggio che potrebbe essere durante l'invio e ricezione di messaggi tra i limiti di interoperabilità.However, keyboard sink support does not address all possible message loop needs you might have when sending and receiving messages across your interoperation boundaries. Per formalizzare un'architettura di ciclo di messaggi dell'applicazione, Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) fornisce il ComponentDispatcher (classe), che definisce un protocollo semplice per un ciclo di messaggi da seguire.To help formalize an application message loop architecture, Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) provides the ComponentDispatcher class, which defines a simple protocol for a message loop to follow.

ComponentDispatcher è una classe statica che espone molti membri.ComponentDispatcher is a static class that exposes several members. L'ambito di ogni metodo in modo implicito è associato al thread chiamante.The scope of each method is implicitly tied to the calling thread. Un ciclo di messaggi è necessario chiamare alcune APIAPIs nei momenti critici (come definito nella sezione successiva).A message loop must call some of those APIAPIs at critical times (as defined in the next section).

ComponentDispatcher fornisce gli eventi che altri componenti (ad esempio il sink di tastiera) possono restare in attesa.ComponentDispatcher provides events that other components (such as the keyboard sink) can listen for. Il Dispatcher classe chiamate tutti i ComponentDispatcher metodi in una sequenza appropriata.The Dispatcher class calls all the appropriate ComponentDispatcher methods in an appropriate sequence. Se si implementa un ciclo di messaggi, il codice è responsabile della chiamata ComponentDispatcher metodi in modo simile.If you are implementing your own message loop, your code is responsible for calling ComponentDispatcher methods in a similar fashion.

La chiamata ComponentDispatcher metodi su un thread solo richiama i gestori eventi registrati su tale thread.Calling ComponentDispatcher methods on a thread will only invoke event handlers that were registered on that thread.

Cicli di messaggi di scritturaWriting Message Loops

Di seguito è riportato un elenco di controllo ComponentDispatcher membri che è necessario utilizzare scrivere un ciclo di messaggi:The following is a checklist of ComponentDispatcher members you will use if you write your own message loop:

  • PushModal: il ciclo di messaggi deve chiamare questo metodo per indicare che il thread è modale.PushModal: your message loop should call this to indicate that the thread is modal.

  • PopModal: il ciclo di messaggi deve chiamare questo metodo per indicare che il thread è stato ripristinato allo stato non modale.PopModal:your message loop should call this to indicate that the thread has reverted to nonmodal.

  • RaiseIdle: il ciclo di messaggi deve chiamare questo metodo per indicare che ComponentDispatcher deve generare il ThreadIdle evento.RaiseIdle: your message loop should call this to indicate that ComponentDispatcher should raise the ThreadIdle event. ComponentDispatcher non genererà ThreadIdle se IsThreadModal viene true, ma i cicli di messaggi possono scegliere di chiamare RaiseIdle anche se ComponentDispatcher non può rispondere ai si trova nello stato modale.ComponentDispatcher will not raise ThreadIdle if IsThreadModal is true, but message loops may choose to call RaiseIdle even if ComponentDispatcher cannot respond to it while in modal state.

  • RaiseThreadMessage: il ciclo di messaggi deve chiamare questo metodo per indicare che è disponibile un nuovo messaggio.RaiseThreadMessage: your message loop should call this to indicate that a new message is available. Il valore restituito indica se un listener per un ComponentDispatcher evento gestito il messaggio.The return value indicates whether a listener to a ComponentDispatcher event handled the message. Se RaiseThreadMessage restituisce true (gestito), il dispatcher non deve eseguire altre operazioni con il messaggio.If RaiseThreadMessage returns true (handled), the dispatcher should do nothing further with the message. Se il valore restituito è false, il dispatcher chiami il Win32Win32 funzione TranslateMessage, quindi chiamare DispatchMessage.If the return value is false, the dispatcher is expected to call the Win32Win32 function TranslateMessage, then call DispatchMessage.

Utilizzo di ComponentDispatcher e gestione del messaggio esistenteUsing ComponentDispatcher and Existing Message Handling

Di seguito è riportato un elenco di controllo ComponentDispatcher membri che è necessario utilizzare inerente il WPFWPF ciclo di messaggi.The following is a checklist of ComponentDispatcher members you will use if you rely on the inherent WPFWPF message loop.

  • IsThreadModal: indica se l'applicazione è modale (ad esempio, un ciclo di messaggi modale è stato inserito).IsThreadModal: returns whether the application has gone modal (e.g., a modal message loop has been pushed). ComponentDispatcher possibile rilevare questo stato perché la classe gestisce un conteggio dei PushModal e PopModal chiamate dal ciclo di messaggi.ComponentDispatcher can track this state because the class maintains a count of PushModal and PopModal calls from the message loop.

  • ThreadFilterMessage e ThreadPreprocessMessage eventi conformi alle regole standard per le chiamate del delegato.ThreadFilterMessage and ThreadPreprocessMessage events follow the standard rules for delegate invocations. I delegati vengono richiamati nell'ordine specificato e tutti i delegati richiamati anche se il primo messaggio viene contrassegnato come gestito.Delegates are invoked in an unspecified order, and all delegates are invoked even if the first one marks the message as handled.

  • ThreadIdle: indica un tempo appropriato ed efficiente per periodi di inattività elaborazione (non sono presenti altri messaggi in sospeso per il thread).ThreadIdle: indicates an appropriate and efficient time to do idle processing (there are no other pending messages for the thread). ThreadIdle non essere generato se il thread è modale.ThreadIdle will not be raised if the thread is modal.

  • ThreadFilterMessage: generato per tutti i messaggi che elabora il message pump.ThreadFilterMessage: raised for all messages that the message pump processes.

  • ThreadPreprocessMessage: generato per tutti i messaggi che non sono stati gestiti durante ThreadFilterMessage.ThreadPreprocessMessage: raised for all messages that were not handled during ThreadFilterMessage.

Un messaggio viene considerato gestito se dopo il ThreadFilterMessage evento o ThreadPreprocessMessage evento, il handled parametro passato per riferimento nei dati dell'evento è true.A message is considered handled if after the ThreadFilterMessage event or ThreadPreprocessMessage event, the handled parameter passed by reference in event data is true. I gestori eventi devono ignorare il messaggio se handled è true, perché ciò significa che il messaggio è stato gestito prima da altro handler.Event handlers should ignore the message if handled is true, because that means the different handler handled the message first. Gestori eventi per entrambi gli eventi possono modificare il messaggio.Event handlers to both events may modify the message. Il dispatcher deve inviare il messaggio modificato e non subisce Modifica messaggio originale.The dispatcher should dispatch the modified message and not the original unchanged message. ThreadPreprocessMessage viene recapitato a tutti i listener, ma l'intenzione dell'architettura solo la finestra di primo livello contenente l'HWND in corrispondenza del quale i messaggi destinati devono richiamare il codice in risposta al messaggio.ThreadPreprocessMessage is delivered to all listeners, but the architectural intention is that only the top-level window containing the HWND at which the messages targeted should invoke code in response to the message.

Eventi ComponentDispatcher di HwndSourceHow HwndSource Treats ComponentDispatcher Events

Se il HwndSource è una finestra di primo livello (nessun HWND padre), verrà registrato con ComponentDispatcher.If the HwndSource is a top-level window (no parent HWND), it will register with ComponentDispatcher. Se ThreadPreprocessMessage viene generato, e se il messaggio è destinato il HwndSource o finestre figlio, HwndSource chiamate relativo IKeyboardInputSink.TranslateAccelerator, TranslateChar, OnMnemonic sequenza sink di tastiera.If ThreadPreprocessMessage is raised, and if the message is intended for the HwndSource or child windows, HwndSource calls its IKeyboardInputSink.TranslateAccelerator, TranslateChar, OnMnemonic keyboard sink sequence.

Se il HwndSource non è una finestra di primo livello (dispone di un HWND padre), non sarà presente alcuna gestione.If the HwndSource is not a top-level window (has a parent HWND), there will be no handling. Solo la finestra di primo livello deve eseguire la gestione e si deve essere una finestra di primo livello con il supporto del sink di tastiera come parte di qualsiasi scenario di interoperabilità.Only the top level window is expected to do the handling, and there is expected to be a top level window with keyboard sink support as part of any interoperation scenario.

Se WndProc su un HwndSource viene chiamato senza un metodo del sink di tastiera appropriato, l'applicazione riceverà gli eventi di tastiera di livello superiore, ad esempio KeyDown.If WndProc on an HwndSource is called without an appropriate keyboard sink method being called first, your application will receive the higher level keyboard events such as KeyDown. Tuttavia, nessun metodo sink di tastiera viene chiamato, che consente di evitare un'utile keyboard features: modello di input, ad esempio il supporto di chiave di accesso.However, no keyboard sink methods will be called, which circumvents desirable keyboard input model features such as access key support. Questa situazione può verificarsi perché il ciclo di messaggi non ha notificato correttamente il thread pertinente sul ComponentDispatcher, oppure perché l'HWND padre non ha richiamato le risposte del sink di tastiera corrette.This might happen because the message loop did not properly notify the relevant thread on the ComponentDispatcher, or because the parent HWND did not invoke the proper keyboard sink responses.

Un messaggio che passa al sink di tastiera potrebbe non essere inviato all'HWND se sono state aggiunte hook per tale messaggio tramite il AddHook metodo.A message that goes to the keyboard sink might not be sent to the HWND if you added hooks for that message by using the AddHook method. Il messaggio potrebbe essere gestito in e non inviato a livello del message pump di DispatchMessage (funzione).The message might have been handled at the message pump level directly and not submitted to the DispatchMessage function.

Vedere ancheSee Also

ComponentDispatcher
IKeyboardInputSink
Interoperatività di WPF e Win32WPF and Win32 Interoperation
Modello di threadingThreading Model
Cenni preliminari sull'inputInput Overview