SendMessage 在跨線程調用時是同步阻塞的:發送線程會阻塞,直到接收線程的消息隊列取出並處理完該消息。這與同線程調用(直接同步調用窗口過程)行為不同。
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine.
If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.
發送線程 (Thread A) 接收線程 (Thread B)
│ │
├─ SendMessage(hwnd, msg, ...) ──────► │ (消息進入 Thread B 隊列)
│ (阻塞等待) │
│ ├─ GetMessage / PeekMessage
│ ├─ DispatchMessage
│ │ └─ WindowProc 處理消息
│ │ (執行用戶代碼)
│ │
│ ◄──── 返回結果 (LRESULT) ───────────┤ (處理完成,喚醒 Thread A)
│ │
▼ ▼
SendMessage 到 Thread B,而 Thread B 需要同一把鎖 → 死鎖。SendMessage 回調發送線程,需防重入。PostMessage(異步,非阻塞),配合消息 ID 和 WPARAM/LPARAM 傳遞數據。GetMessage/DispatchMessage),且處理邏輯極快(無鎖、無耗時操作)。WPARAM/LPARAM 僅能傳整數/指針,指針指向的內存必須雙方可訪問(堆內存、共享內存),且注意生命周期與同步。SendMessageTimeout 設置超時,避免無限阻塞。CSDN 討論帖:跨線程 SendMessage 行為分析