2013-08-12 55 views
6

對於WPF應用程序,是否有內部經典消息循環(在Windows的GetMessage/DispatchMessage意義上),在Application.Run裏面?是否有可能捕獲從PostThreadMessage到另一個Win32應用程序發佈到WPF UI線程(沒有HWND句柄的消息)的消息。謝謝。WPF應用程序消息循環和PostThreadMessage

+2

使用[ComponentDispatcher.ThreadFilterMessage](http://msdn.microsoft.com/zh-cn/library/system.windows.interop.component library).threadfiltermessage.aspx)事件可能會注意到特定的消息,儘管文檔說它是用於鍵盤消息的。這是一個相關的問題[回答](http://stackoverflow.com/questions/476084/c-sharp-twain-interaction)。 – Noseratio

回答

3

我使用了.NET Reflector來跟蹤Applicaton.Run的實現,直至Dispatcher.PushFrameImpl。也可以從.NET Framework reference sources獲取相同的信息。有確實是一個經典的消息循環:

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; 
     } 
    } 
} 

此外,這裏的TranslateAndDispatchMessage實施,這的確激發內部RaiseThreadMessage沿着它的執行過程中ComponentDispatcher.ThreadFilterMessage事件:

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

顯然,它適用於所有已發佈消息,而不僅僅是鍵盤。您應該可以訂閱ComponentDispatcher.ThreadFilterMessage並觀看您感興趣的消息。