原文地址:https://blog.csdn.net/zxxSsdsd/article/details/45504383函數
在win32程序的消息循環函數中 while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }DispatchMessag()會調用WndProc()窗口過程函數,直到WndProc()處理完後DispatchMessag()才返回,繼續消息循環檢索下一條消息,在此以前while()消息循環會停頓掉在WndProc()函數處理過程當中若是又產生了另外一個消息B,則必須等這個消息B處理完後wndProc()函數纔會返回,而這個消息B也是要由WndProc()函數處理的,即在WndProc()調用的過程當中系統接受到消息B後嵌套調用了WndProc(),但此時while消息循環已經停頓了return msg.wParam;根據試驗,在WndProc()處理過程當中發出消息B後,系統經過某種方式跳過while()消息循環獲取了消息B,而且又調用了一個WndProc()來處理消息B,等消息B處理完後第二個WndProc()才返回,而後第一個WndProc()繼續執行,等第一個WndProc()執行完畢後DispatchMessage()纔會返回,而後繼續下一輪while()循環那麼,系統是怎樣接受到這個消息B的呢?系統是怎樣繞過while消息循環獲取消息B而且調用第二個WndProc()的,這中間具體發生了哪些事情?網上和書上都沒找到詳細的處理過程……我想應該仍是跟消息隊列有關,不知道系統在這種狀況下怎樣處理消息隊列中的消息的?MSG_B Over每一個窗口、線程都有本身的消息隊列,消息是投遞到消息隊列裏的while (GetMessage (&msg, NULL, 0, 0)) TranslateMessage (&msg) ; DispatchMessage (&msg) ; }GetMessage是從消息隊列裏獲取消息,所以,消息傳過來的時候,是不佔用這個循環的謝謝解答!但是在DispatchMessage (&msg)函數中調用wndproc()窗口過程時,while ()消息循環是停頓掉的,發出消息B後,這時系統是跳過while()消息循環直接到消息隊列裏取的消息嗎?是怎樣調用第二個wndproc()窗口過程的?用到了哪些函數呢?你用什麼消息測試的。有的消息是不放在消息隊列裏的。ShowWindow(hwnd, nCmdShow);
不是全部消息都會進消息隊列,系統會有額外處理,對於SendMessage,相似於直接調用WinProc來實現.謝謝了,我是擔憂SendMssage()可能會影響測試結果,因此用PostMessage()發送的消息PostMessage的話 消息進消息隊列下次取消息的時候纔會取到消息。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 不是,雖然PostMessage只是投遞消息,可是在WndProc窗口過程函數中必須處理完這個新消息後才繼續執行WndProc()函數是可重入的,就是說:WndProc()函數雖然沒結束,但一個API調用(SendMessage()、PostMessage等)會再次調用WndProc()因此我想知道系統這時是怎樣再次調用WndProc()窗口過程函數的SendMessage給本身發纔會先處理完這個新消息後才繼續執行SendMessageW->SendMessageWorkerSendMessageWorker判斷目標窗口的線程是否是當前線程,若是不是就進入內核調用NtUserMessageCall不然就在用戶模式調用窗口過程PostMessage的話只是把消息放到消息隊列中,下次GetMessage的時候才取到。SendMessage( hwnd , WM_MESS , w , l );內部調用WndProc( hwnd , WM_MESS , w , l );你能夠下個斷點看看調用棧。
謝謝!謝謝各位的解答,在此特別感謝 Lactoferrin qman007 等,感謝大家的解答因爲以前測試消息的選擇和測試方式的錯誤,致使我測試的結果不可信,我從新進行了測試,根據測試結果,對於WinProc消息循環的機制我是這樣理解的:SendMessage 的話至關於直接調用 WndProc
一、在win32程序的while消息循環中,DispatchMessag()會調用WndProc()窗口過程函數,直到WndProc()處理完後DispatchMessag()才返回,繼續消息循環檢索下一條消息,在這以前while()消息循環會停頓掉
二、在WndProc()函數處理過程當中又產生了另外一個消息B,若是消息B是由PostMessage()發送的,則消息B會發送到消息隊列中,而後WndProc()繼續執行,執行完畢後返回到DispatchMessag()函數,繼續消息循環檢索下一條消息,檢索到消息B後纔開始執行消息B,
三、在WndProc()函數處理過程當中又產生了另外一個消息B,若是消息B是由SendMessage()發送的,則必須等這個消息B處理完後wndProc()函數纔會返回,這時SendMessage()會調用 SendMessageWorker(),SendMessageWorker()判斷目標窗口的線程是否是當前線程,若是不是就進入內核調用NtUserMessageCall(),不然就在用戶模式調用窗口過程函數WndProc()