2013-08-12 10 views
6

Per un'applicazione WPF, esiste internamente un classico loop di messaggi (nel senso di Windows GetMessage/DispatchMessage) all'interno di Application.Run? È possibile rilevare un messaggio pubblicato da un'altra applicazione Win32 con PostThreadMessage in un thread UI WPF (un messaggio senza handle HWND). Grazie.WPF application loop e PostThreadMessage

+2

Potrebbe essere possibile guardare un messaggio specifico con l'evento [ComponentDispatcher.ThreadFilterMessage] (http://msdn.microsoft.com/en-us/library/system.windows.interop.componentdispatcher.threadfiltermessage.aspx), anche se i documenti dicono che è inteso per i messaggi della tastiera. Ecco una domanda correlata [risposta] (http://stackoverflow.com/questions/476084/c-sharp-twain-interaction). – Noseratio

risposta

3

Ho utilizzato .NET Reflector per tracciare l'implementazione Applicaton.Run fino a Dispatcher.PushFrameImpl. È anche possibile ottenere le stesse informazioni da .NET Framework reference sources. V'è infatti un ciclo di messaggi classico:

private void PushFrameImpl(DispatcherFrame frame) 
{ 
    SynchronizationContext syncContext = null; 
    SynchronizationContext current = null; 
    MSG msg = new MSG(); 
    this._frameDepth++; 
    try 
    { 
     current = SynchronizationContext.Current; 
     syncContext = new DispatcherSynchronizationContext(this); 
     SynchronizationContext.SetSynchronizationContext(syncContext); 
     try 
     { 
      while (frame.Continue) 
      { 
       if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0)) 
       { 
        break; 
       } 
       this.TranslateAndDispatchMessage(ref msg); 
      } 
      if ((this._frameDepth == 1) && this._hasShutdownStarted) 
      { 
       this.ShutdownImpl(); 
      } 
     } 
     finally 
     { 
      SynchronizationContext.SetSynchronizationContext(current); 
     } 
    } 
    finally 
    { 
     this._frameDepth--; 
     if (this._frameDepth == 0) 
     { 
      this._exitAllFrames = false; 
     } 
    } 
} 

Inoltre, ecco l'implementazione di TranslateAndDispatchMessage, che spara davvero ComponentDispatcher.ThreadFilterMessage evento lungo il suo corso di esecuzione all'interno RaiseThreadMessage:

private void TranslateAndDispatchMessage(ref MSG msg) 
{ 
    if (!ComponentDispatcher.RaiseThreadMessage(ref msg)) 
    { 
     UnsafeNativeMethods.TranslateMessage(ref msg); 
     UnsafeNativeMethods.DispatchMessage(ref msg); 
    } 
} 

A quanto pare, funziona per qualsiasi postato messaggio, non solo quelli di tastiera. Dovresti essere in grado di iscriverti allo ComponentDispatcher.ThreadFilterMessage e guardare il tuo messaggio di interesse.