I am creating application with win32 GUI and I tried blocking and ignoring some window messages of the message queue in my message loop. For it, I tried this following code:
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
if (msg.message != WM_... /*to complete with messages to block*/) DispatchMessage(&msg);
}
But it does not work and I can not understand why. Normally, except some particular messages, all messages pass by the message loop, so the messages that I block should be ignored! What is not wrong with my code? Mayby I shoud try to rethink my message loop?
Thanks for reading and your help.
Related
Is there limitations – in which threads) must be (1) created window (RegisterClassEx, CreateWindowExW) and (2) performed messages processing loop ?:
MSG msg = { 0 };
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
In my implementation (1) is called from the main thread, (2) is called from the new thread, specially created to get window messages.
This is console application, so I need to manually create the new window to get window messages of certain type (messages from DirectShow; not for GUI) (Win10, VS 2022).
So I'm using messages window for process inter-communication.
Multiple processes will send the same message to the message window when a certain event occur.
I've observed that non queued messages wait for the previous message to be returned until they get processed.
Now my question is there a way to dismiss all incoming(waiting) messages at once?
One way to dismiss all waiting message is that you could get out all messages from the message queue.
case Repeated_Message:
PostMessage(hWnd, Custom_Flag, 0, 0);
while (true)
{
GetMessage(&msg, nullptr, 0, 0);
if (msg.message == Custom_Flag)
break;
}
//To Do.
break;
When using D3D11 encountered a problem with an empty call context-> Present (0,0); OK. And if it goes before the draw, drawindexed ..., reezes windows completely.
Errors and warnings are missing in the assembly and execution.
GContext->VSSetShader(mVS->GetVertexShader(), NULL, 0);
GContext->PSSetShader(mPS->GetPixelShader(), NULL, 0);
GContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, 0);
GContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); GContext->Draw(3, 0);
mSwapChain->Present(0, 0);
Enable the debug device and look for messages in your debug window, and ensure you are checking every HRESULT for SUCCEEDED or FAILED.
Are you doing this in a 'tight loop'? Where are you processing your windows messages?
You should take a look at this Windows desktop VS template for a good minimal rendering loop.
// Main message loop
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_game->Tick();
}
}
Here Tick is the Update loop and Render loop. See StepTimer for a robust way to do the update timing.
Your problem is some ignorance of init D3D code, GContext->Draw(3, 0);, you only want to draw a triangle.
So your can try mSwapChain->Present(1, 0); which will follow the Vsync like 60Hz and present(0,0) work as fast as it can, often 1000-5000Hz depend on computer. What is freeze you mean, you can not interact with window? That you can follow #Chuck Walbourn advice in main loop, like add the code after mSwapChain->Present(0 or 1, 0);.
As you know, you problem amostly an apearance of a bug, so don't worry.
What is the differences between
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
and
case WM_DESTROY:
PostQuitMessage(0);
break;
?
When you call PostQuitMessage, you pass an exit code, not a message ID. PostQuitMessage will in turn generate (and post) the WM_QUIT message for you.
So technically, the difference is that with PostQuitMessage(WM_QUIT), the exit code will be 0x0012 (or 18 in decimal). Whereas PostQuitMessage(0) will provide an exit code of 0.
When either GetMessage and PeekMessage see a WM_QUIT message, they will return zero, and you can check for the exit code in the WPARAM part of the LPMSG parameter.
To return the exit code (the value you pass to PostQuitMessage) the message pump for your application could be something like this:
MSG msg;
while (0 != GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
We can find code, on which the message loop is discontinued on an "error" of -1 from
GetMessage(). So if the application in this case suddenly disappears, no shocked user
will find out what the reason for this was. The better way is to keep the app running.
And also a "bad" message does not damage the DefWindowProc() function.
I spent some time trying to research a definitive answer for this and couldn't find a reliable source.
My scenario is fairly straightforward. I have a thread with a message pump setup that is processing a recurring event from a timer. Here is the message pump source:
// create timer that goes off every 500 ms
UINT_PTR myTimerID = SetTimer(NULL, 0, 500, TimerCallback);
// message structure
MSG msg;
// process and handle messages for this thread
BOOL getMessageStatus;
while((getMessageStatus = GetMessage(&msg, NULL, 0, 0)) != 0)
{
// failed get message
if(getMessageStatus == -1)
{
printf("GetMessage FAILED!\n");
}
// process timer message
else if(msg.message == WM_TIMER)
{
// invoke callback
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
If TimerCallback takes longer than 500 ms, the timer will have fired its event again. Since, the callback is being executed on the same thread as the message pump, I assume that the callback must complete before the next timer message is processed by the message pump.
Is that correct?
SetTimer() is a message-based timer. When the timer elapses, it sets a special flag inside the message queue. When you pump the queue for new messages, a WM_TIMER message will be created if that flag has been set and other higher-priority messages are not waiting in the queue. While your code is busy dispatching a generated WM_TIMER message, the timer can elapse in the background and set the flag again, generating a new WM_TIMER message the next time you pump the queue for messages. So be careful about pumping messages while inside the callback, either directly or via modal dialogs, as that can potentially lead to recursive calls of your timer callback and thus may cause a stack overflow over time. But if your message pumping is only in your main thread loop then you will be fine.
So long as there is only one entry point for processing messages, only one message can be processed at a time. You can screw things up by processing more messages in an already-running event handler, but just don't do that and you should be fine.