Select the product you need help with
GetMessage ignores posted messages received during the execution of a WinEvent callbackArticle ID: 2682659 - View products that this article applies to. SYMPTOMSGetMessage appears not to receive messages that are posted while a WinEvent callback function is being executed. If another message enters the queue, both messages will be received and processed. CAUSEThere is a known issue with GetMessage and the use of WinEvent callbacks that themselves use Windows messages. GetMessage ignores a message that is received during the execution of the callback. Therefore, in particular, if the callback function calls PostThreadMessage, that message will not register until another message enters the queue (for example, due to a mouse movement); at that point, both the earlier posted message and the new message will register and be processed. RESOLUTIONTo work around this block, we recommend using MsgWaitForMultipleObjects and PeekMessage instead of GetMessage. It is also necessary to create a new event that can be sent from the WinEvent handler to wake up the message loop. MORE INFORMATIONHere is a code fragment that includes a generic message loop and a WinEvent handler: // Main message loop of thread that called SetWinEventHook while(GetMessage(&msg, NULL, 0, 0)) { ... process message here ... } void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD eventId, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { ... process winevent here ... } GetMessage can block in the above fragment after failing to register a message sent from WinEventProc. Instead, use MsgWaitForMultipleObjects and PeekMessage together with declaring and using a special wake-up event from the handler back to the message loop, as shown in this fragment: HANDLE ghMessageReadyEvent = NULL; // Event used to wake up the main thread ghMessageReadyEvent = CreateEvent(NULL, FALSE/*bManualReset*/, FALSE/*bIntialState*/, NULL); // Main message loop of thread that called SetWinEventHook // // We can't reliably use GetMessage here. If a posted message is received // while we're in a reentrant call to WinEventProc, when the WinEventProc // returns, GetMessage does not recognize that a message has been // received and just blocks. To avoid this we use // MsgWaitForMultipleObjects + PeekMessage. Code at the end of the // WinEventProc checks if a posted message was received during the // callback using PeekMessage; if so, it sets the event which causes / MsgWaitForMultipleObjects to wake up. // // Note that MsgWaitForMultipleObjects usually only wakes up if a message // is received during it. Even with QS_ALLPOSTMESSAGE, it only wakes up // if a message is received between it and the most recent PeekMessage, // so we have to call PeekMessage *before* calling it in case there are // multiple queued-up messages. for(;;) { BOOL fGot = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if(!fGot) { MsgWaitForMultipleObjects(1, &ghMessageReadyEvent, FALSE/*bWaitAll*/, INFINITE, QS_ALLEVENTS | QS_ALLPOSTMESSAGE); fGot = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); } if(!fGot) { continue; } ... process message here ... } void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD eventId, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { ... process winevent here ... // Before we return, check if posted messages were received during this // callback. If so, fire the event to ensure that we do process them. MSG msg; if(PeekMessage(&msg, (HWND)-1, WM_USER + 1, WM_USER + 2, PM_NOREMOVE | PM_QS_POSTMESSAGE)) { SetEvent(ghMessageReadyEvent); } } Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See Terms of Use
(http://go.microsoft.com/fwlink/?LinkId=151500)
for other considerations.PropertiesArticle ID: 2682659 - Last Review: June 4, 2012 - Revision: 1.0 APPLIES TO
|


Back to the top








