Peekmessage (creating window loop) - c++

Igot this error and I don't know why, I just follow correctly what he do, and he doesn't get this error. Here is the code.
//Main application loop
MSG msg = {0};
while(WM_QUIT != msg.message())
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_Remove))
{
//Translate message
TranslateMessage(&msg);
//Dispatch message
DispatchMessage(&msg);
}
}
And here are the error:
error C2064: term does not evaluate to a function taking 0 arguments
fatal error C1903: unable to recover from previous error(s); stopping compilation
And when I clicked it, they all pointing to the while loop.

The message member of the MSG structure is a field, not a method. You should access it instead of calling it:
while (WM_QUIT != msg.message) {
// ...
}
There are other issues in your code snippet. First, C++ is a case-sensitive language, so the last argument to PeekMessage() should be PM_REMOVE instead of PM_Remove.
In addition, PeekMessage() does not block if the message queue is empty, so your code will end up consuming 100% of the CPU core it runs on. You can use GetMessage() instead, which blocks if no message is available and would allow you to remove the explicit test for WM_QUIT:
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Related

DoEvent() in Windows and Linux errors

I want to write a function like DoEvents() in C++.
I found DoEvents equivalent for C++? and In C/C++, which function is like DoEvents( ).
Here is the code:
void DoEvents()
{
MSG msg; // Error 1
while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE ) ) //Error 2
{
if ( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
break;
}
}
I have two questions:
Q1. What is the equivalent of DoEvent() in Linux?
Q2. I got errors when I try to use it on windows using Qt creator.
Error1 : unknown type name 'MSG'
Error2 : use of undeclared identifier'PM_NOREMOVE'
Any Help, please?

WinAPI - GetRawInputBuffer

I have problem with GetRawInputBuffer. Code returns no error, but there are no data present in retrieved response.
I have written code according to this Using GetRawInputBuffer correctly
UINT RawInputSize;
UINT Result;
Result = GetRawInputBuffer(NULL, &(RawInputSize), sizeof(RAWINPUTHEADER));
if (Result == -1)
{
DWORD ErrorCode = GetLastError();
return;
}
UINT AllocatedBufferByteCount = RawInputSize * 16;
RAWINPUT* RawInputBuffer = reinterpret_cast<RAWINPUT*>(malloc(AllocatedBufferByteCount));
UINT AllocatedBufferByteCountTwo = AllocatedBufferByteCount;
Result = GetRawInputBuffer(RawInputBuffer, &(AllocatedBufferByteCountTwo), sizeof(RAWINPUTHEADER));
if (Result == -1)
{
DWORD ErrorCode = GetLastError();
return;
}
UINT RawInputCount = Result;
RAWINPUT* RawInput = RawInputBuffer;
for (unsigned int i = 0; i < RawInputCount; ++i)
{
switch (RawInput->header.dwType)
{
case RIM_TYPEMOUSE:
{
this->UpdateMouse(RawInput->data.mouse);
break;
}
case RIM_TYPEKEYBOARD:
{
this->UpdateKeyboard(RawInput->data.keyboard);
break;
}
}
RawInput = NEXTRAWINPUTBLOCK(RawInput);
}
DefRawInputProc(&(RawInputBuffer), RawInputCount, sizeof(RAWINPUTHEADER));
This code is called outside case WM_INPUT. RawInputCount is always zero. If I use GetRawInputData inside case WM_INPUT, I am recieving data correctly.
What is wrong with this code and why are my results empty?
The answer comes a bit late, but since I had the same problem recently, I'll answer it anyways:
GetRawInputBuffer uses the WM_INPUT message to get and buffer the messages. However, you propably uses something like while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) to process your window messages, which removes all messages after sent to your application. That way, input messages won't be send to the GetRawInputBuffer method and the method will allways return an size of 0. To solve this problem, you need to use something like this as your main loop:
//Process and remove all messages before WM_INPUT
while(PeekMessage(&Message, NULL, 0, WM_INPUT - 1, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
//Process and remove all messages after WM_INPUT
while(PeekMessage(&Message, NULL, WM_INPUT + 1, (UINT)-1, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
This way, WM_INPUT messages are neither processed nor removed by your application, and therefor send to GetRawInputBuffer. Obviusly you could also exchange the PM_REMOVE flag with PM_NOREMOVE, however this could cause other problems, so I would recommend the above method to process and remove all but the WM_INPUT message.

Windows: PeekMessage loop anomaly

Here's a code snippet from a project I am currently working on:
MSG msg;
bool msgAvail = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
while(msgAvail)
{
TranslateMessage(&msg);
...
...
msgAvail = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
}
While analyzing a customer crash dump, I found that the call to TranslateMessage() has the parameter as NULL. I am confused as to how could &msg become NULL in the above scenario. Could someone explain what could be happening in the above code due to which the address of msg is becoming NULL?

C++ thread termination with waiting window

So, the code goes somehow like this:
MAIN(){
/*waiting window class declaration*/
threadinfo* oThread=new threadinfo(); //An object that will help me know when to finish the thread
QueueUserWorkItem((LPTHREAD_START_ROUTINE)waitingWindow, (void*)mThread, WT_EXECUTELONGFUNCTION);
function_that_takes_time();
oThread->setTerminated(); //set member terminated to bool true
/*continue with other things*/
}
and waitingWindow function that will run on that thread
MSG msg;
hwndWaiting=CreateWindow(...) // here the window is created
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, null, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(oThread->isTerminated()) // isTerminated returns bool true if terminated
{
delete oThread;
ExitThread(0);
}
}
}
ExitThread(0);
Is ExitThread a good way to remove the waiting window, and safely remove the thread? (at least I'm 100% sure this way when to end it).
I'm asking this because this works nice in Windows XP, but will crash with "the application has stopped working" on Windows 7.
Thanks for the help.
The best way to end threads in general, is to let them "gracefully" finish up by themselves. You could tell the thread to end by setting an event, for example:
HANDLE hevent_die = CreateEvent(...);
HANDLE hthread_something = CreateThread(...); // or _beginthread()
...
DWORD WINAPI thread_func (LPVOID param)
{
while(working && WaitForSingleObject(hevent_die, 0)!=WAIT_OBJECT_0)
{
...
}
return 0;
}
while (msg.message != WM_QUIT)
{
...
if(WaitForSingleObject(hthread_something, 0) == WAIT_OBJECT_0)
{
// do things if needed
}
}
SetEvent(hevent_die);
WaitForSingleObject(hthread_something, INFINITE);
CloseHandle(hthread_something);
CloseHandle(hevent_die);
hthread_something = 0;
hevent_die = 0;
If you are using nested loops inside the thread function, they too will have to end if they receive the event.
You should exit your loop and thread cleanly so that any destructors are called correctly. Don't use ExitThread(), just use a flag to indicate when to exit the loop and then just exit your waitingWindow function at the end.

The PeekMessage function in C++ and named pipes

Regarding:
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
If hWnd is NULL, PeekMessage retrieves
messages for any window that belongs
to the current thread, and any
messages on the current thread's
message queue whose hwnd value is NULL
(see the MSG structure). Therefore if
hWnd is NULL, both window messages and
thread messages are processed.
Are messages received via a named pipe included in window messages and thread messages?
Definitely not. Named pipes do not send window messages.
The thread messages in this context are special and have nothing to do with named pipes.
Use MsgWaitForMultipleObjects instead.
CODE SAMPLE:
void MessageLoop(HANDLE hNamedPipe)
{
do {
DWORD res = MsgWaitForMultipleObjects(1, &hNamedPipe, INFINITE, QS_ALLEVENTS, MWMO_INPUTAVAILABLE);
if (res == WAIT_OBJECT_0) {
/* Handle named pipe -- at this point ReadFile will not block */
} else if (res == WAIT_OBJECT_0 + 1) {
MSG msg;
if (!GetMessage(&msg, NULL, 0, 0))
break; /* WM_QUIT */
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} while (1);
}
No, Windows messages and named pipes are completely unrelated. You would need to use the MsgWaitForMultipleObjectsEx function to wait for either an incoming message or a message on the named pipe.
Note that MsgWaitForMultipleObjectsEx doesn't actually retrieve the message; check its return value to see if there's a Windows message or data on the named pipe, then use GetMessage or ReadFile as appropriate.