2011-05-31 59 views

回答

1

AFAIK沒有內置的能力來做到這一點。

但我們先來調查一下這個問題。你想知道誰是消息的發件人。但是你應該知道,窗口消息處理可以通過以下指標分析可分爲:

  1. 發佈VS發郵件(PostMessage VS SendMessage)。
  2. 發送到屬於另一個線程vs發送者線程的窗口的消息。
  3. 發佈到某個線程(未綁定到特定窗口,因此未被窗口過程處理)的消息。

可在跟蹤直接僅當該消息是發送(未貼)發送到一個窗口,而該呼叫到SendMessage(或類似的)中,以該窗口所屬的線程發出。在這樣的情況下,您會在調用堆棧中看到發件人。

如果消息是從另一個線程發送的 - 您將而不是在調用堆棧中看到它。只是因爲調用堆棧只顯示屬於當前線程的調用鏈。當從另一個線程發送消息時,系統執行以下操作:

  1. 暫停調用者線程。
  2. 將此消息放入擁有該窗口的線程隊列中。
  3. 當該線程調用GetMessage(或類似的) - 消息被分派到窗口。
  4. 最後操作系統恢復調用者線程。 SendMessage返回窗口過程返回的結果。

在這種情況下,您可能會嘗試間接識別來電者。用斷點中斷程序,並嘗試搜索掛起的線程,這些線程在致電SendMessage或類似程序時被阻止。

最後,發佈的消息不可能通過上述方法進行跟蹤。您可以嘗試在對PostMessage的呼叫中添加條件斷點,但如果呼叫者屬於另一個問題 - 這將更加複雜。

0

valdo是正確的。調用SendMessage直接調用你的應用程序wndproc。對PostMessage的調用將消息發送到消息隊列,然後您的應用程序通過消息泵(循環,getmessage,translatemessage,dispatchmessage)來接收消息。所以,就像他所說的,如果消息是通過SendMessage發送的,那麼函數的被調用者將顯示在調用堆棧中。如果它是通過PostMessage發送的,它不會。

+0

那麼沒有辦法讓PostMessage的行爲像SendMessage?如果是這樣,我看到的唯一方法是暫時用SendMessage替換所有PostMessage調用。 – ks1322 2011-05-31 09:31:23

+0

不,沒有辦法使Postmessage像sendmessage一樣行事,post消息是異步的,並且將消息發送給消息隊列,正如我所說的,發送消息直接繞過消息隊列並直接調用應用程序wndproc。當你調用PostMessage時,它會立即返回,但在調用線程上發送消息塊,因爲它通過調用傳遞給它的hwnd的wndproc來訪問wndproc。 – johnathon 2011-05-31 09:39:46

+0

對於單線程的情況,這個答案是正確的。 'SendMessage'在不同的線程中工作方式不同,因爲您必須在其線程上調用窗口的WindowProc,而不是您自己的。由於每個線程都有自己的調用堆棧,因此您的SendMessage調用將不會與WndProc調用位於同一個堆棧中。 – MSalters 2011-05-31 12:03:40

相關問題