SendMessage和PostMessage區別以及WPARAM 和 LPARAM區別


WPARAM 和 LPARAM

  wParam和lParam 這兩個是Win16系統遺留下來的產物,在Win16API中WndProc有兩個參數:一個是WORD類型的16位整型變量;另一個是LONG類型的32位整型變量。

因此根據匈牙利命名法,16位的變量就被命名為wParam, 32位的變量就被命名為lParam。

  而到了Win32API中,原來的16位變量也被擴展為32位,因此此時wParam和lParam的大小完全相同

  區別及習慣用法:

  MS在使用時兩種參數分別代表不同的含義和內容,WPARAM常常代表一些控件的ID或者高位低位組合起來分別表示鼠標的位置,如果消息的發送者需要將某種結構的指針或者是某種類型的句柄時,習慣上用LPARAM來傳遞。除此之外,一般我們使用LPARAM傳遞地址,而WPARAM傳遞其他參數。

  在自定義消息中調用SendMessage()函數時,第二個參數是WPARAM,第三個參數是這個消息的LPARAM,但是你在程序中某個類中寫下ON_MESSAGE()宏來處理這個消息時,處理函數SomeHandler(WPARAM,LPRAM(默認是0))中解釋這兩個參數時必須按照SendMessage調用中的意義來進行。

 

SendMessage和PostMessage:

  SendMessage:調用系統的消息處理函數對發送的消息進行處理,等待消息處理完成,該函數返回。

  PostMessage:將需要處理的消息發送到系統消息處理隊列中,然后返回。系統會將插入的消息當一般消息來處理。

  詳情:SendMessage、PostMessage原理

 

  SendMessage缺點:

  如果在線程中使用了SendMessage,在對話框主線程中發出了結束該線程的消息(比如SetEvent),然后WaitForSingleObject等待該線程退出。這時對話框線程已被阻塞在這里等待線程退出。同時,線程內由於使用了SendMessage也在等待主線程接收消息后返回。這時,兩邊都在等待,程序就“死鎖”了,永遠也退出不了了。

  PostMessage缺點:

  PostMessage中傳遞字符串指針時要注意,一般在SendMessage中不出錯,換到PostMessage中就出現內存錯誤了,那是因為SendMessage會等待消息返回,也就是目標線程收到消息時,該字符串仍存在。但是PostMessage就不一定了,可能目標線程收到消息時,字符串已經被銷毀了。 

引用:線程中慎用SendMessage和PostMessage

 

  SendMessageTimeout:

  向窗口發送一條消息。如窗口位於不同的線程中,則利用這個函數可以指定一個超時值,以便在另一個進程掛起的時候防止調用進程也永遠掛起。該函數將指定的消息發送到一個或多個窗口。此函數為指定的窗口調用窗口程序,並且,如果指定的窗口屬於不同的線程,直到窗口程序處理完消息或指定的超時周期結束函數才返回。如果接收消息的窗口和當前線程屬於同一個隊列,窗口程序立即調用,超時值無用。

  針對以上兩個函數的缺點,使用SendMessageTimeout是一個相對折中的辦法。但是具體情況是還是看需求是偏重與哪一方面而具體選擇。

  函數原型:

LRESULT SendMessageTimeout(HWND hwnd,UINT Msg,WPARAM wParam,LPARAM IParam,UINTfuFlags,UIUT uTimeout,LPDWORD lpdwResultult)

  參數 類型及說明:

hwnd Long,要接收消息的一個窗口的句柄 
msg Long,消息的標識符 
wParam Long,由消息決定 
lParam Long,由消息決定 
fuFlags Long,下述常數的一個或多個 
  SMTO_ABORTIFHUNG 如目標進程掛起,則函數立即返回 
  SMTO_BLOCK 除非函數返回,否則調用線程不能處理消息 
  SMTO_NORMAL 允許調用線程處理消息,同時保持函數繼續執行 
uTimeout Long,超時值,采用毫秒為單位 
lpdwResult Long,用於裝載函數結果的一個變量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM