Windows C++ 32-bit DLL Strange Behavior in Timer Thread - c++

I am just learning how to right a DLL. This project will ultimately be a plugin for music players and is based on Winamp 5.X.
I want to create a window to show information about the playing song that updates periodically, but it's not a "visualization" plugin which is by definition called back repeatedly by the main program. I need a timer, and another source suggested to use CreateTimerQueueTimer() which starts a separate thread to receive the timeout event instead of infinite looping and checking window messages for stop condition. I have no knowledge of multithreading architecture (if any) in the main program so I similarly don't want to just loop through a "sleep" interval then refreshing output.
The approach seems to work. It is based on a callback function:
char message[12] = "Hallo World";
VOID CALLBACK TimerCallback(PVOID lpParameter, BOOLEAN reserved)
{
message[1] += 1;
MessageBoxA(NULL, message, "Dummy", MB_OK);
}
The 1st popup shows "Hallo World", the 2nd "Hbllo World" on so on.
The mystery is that when I switch the two lines of code in the CALLBACK, all the popups (which are created every 10 seconds) show "Hallo World". I don't understand why that is happening, and I don't think I should try to move on to more complex tasks until I get what's going on here.
As always, any help is greatly appreciated.

Okay, I kind of figured this out. Thought it might help someone else to leave the post up.
In previous testing, I was not closing the popup MessageBox before a new one was generated. On further testing, when I close the boxes as they appear, both behaviors increment as expected.
Still, if anyone wants to comment I'm not completely at ease with my understanding of whats happening.

Related

C++ function Sleep() executes before piece of code

I work in Visual Studio with C++, Windows Form App. I try to paint the button red, wait 3 seconds and then paint it blue.
button1->BackColor = System::Drawing::Color::DarkRed;
Sleep(3000);
button1->BackColor = System::Drawing::Color::CornflowerBlue;
However, Sleep() functions executes before first line (painting red). Program starts from waiting 3 seconds and after time it paints the button blue. It seems like painting red piece of code doesn't have time to execute. Individually, painting red works fine.
I've tried other delay solutions also. Example:
int wait = clock() + 2 * CLOCKS_PER_SEC;
while (clock() < wait) {}
It seems to be an issue in Visual Studio C++, because the Sleep() function have worked perfectly in Code::Blocks console script. Do you have any ideas of solution?
Since Button is also a Window you can Invalidate it before calling Sleep().
what is invalidate,update methods do in VC++
Setting component properties, eg 'button1->BackColor = System::Drawing::Color::DarkRed;' are not trivial assignments. The setter methods generate messages, or sequences of messages, that are posted to the Windows/thread that implement the GUI. Those messages must be handled before the requested property set actions can be considered completed.
If you set a window visual property in an event-handler, and then remove all execution from the thread that manages the window before leaving the event-handler, the messages will not get processed.
Do not wait in a GUI event handler. It's a state-machine for handling messages. Don't stop it.
Thank you for your contribution guys!
Advice about threads was helpful. I've solved this problem with the Refresh() function. It seems like parts of code are handled with different threads which work asynchronous. Refresh() function probably implements waiting for the threads to by synchronised.

look for keypress only if window is in focus

I am writing a program which interfaces with some testing equipment. I want the user to be able to press a button to stop the test, but only if the program is in focus. This is because they can be using their pc for other work at the same time. This is what I have now.
if ((GetAsyncKeyState(VK_ESCAPE) & 0x8000)&&(GetFocus() == FindWindow(NULL,TEXT("Window name")))){
break;
}
The problem is, the keypress is still determined even when the user is working on other programs. I also want this to happen without waiting for user input so the program can continue running(i realize I could probably use threading but I think that seems a little overkill in this case). If anybody knows a statement I can use in the second half of the IF statement that would be great, or even a different method altogether.
Thank you.
Wild guess this one. Maybe you could use the GetForegroundWindow function and check the handle against your test window handle. Possibly a better method is for your test window to handle the WM_KEYDOWN message. My understanding is that this message is only posted if the window has focus.

Mouse jiggling / message processing loop

I have written a multithreaded program which does some thinking and prints out some diagnostics along the way. I have noticed that if I jiggle the mouse while the program is running then the program runs quicker. Now I could go in to detail here about how exactly I'm printing... but I will hold off just for now because I've noticed that in many other programs, things happen faster if the mouse is jiggled, I wonder if there is some classic error that many people have made in which the message loop is somehow slowed down by a non-moving mouse.
EDIT: My method of "printing" is as follows... I have a rich edit control window to display text. When I want to print something, I append the new text on to the existing text within the window and then redraw the window with SendMessage(,WM_PAINT,0,0).
Actually its a bit more complicated, I have multiple rich edit control windows, one for each thread (4 threads on my 4-core PC). A rough outline of my "my_printf()" is as follows:
void _cdecl my_printf(char *the_text_to_add)
{
EnterCriticalSection(&my_printf_critsec);
GetWindowText(...); // get the existing text
SetWindowText(...); // append the_text_to_add
SendMessage(...WM_PAINT...);
LeaveCriticalSection(&my_printf_critsec);
}
I should point out that I have been using this method of printing for years in a non-multithreaded program without even noticing any interaction with mouse-jiggling.
EDIT: Ok, here's my entire messageloop that runs on the root thread while the child threads do their work. The child threads call my_printf() to report on their progress.
for(;;)
{
DWORD dwWake;
MSG msg;
dwWake = MsgWaitForMultipleObjects(
current_size_of_handle_list,
hThrd,
FALSE,
INFINITE,
QS_ALLEVENTS);
if (dwWake >= WAIT_OBJECT_0 && dwWake < (WAIT_OBJECT_0 + current_size_of_handle_list))
{
int index;
index = dwWake - WAIT_OBJECT_0;
int j;
for (j = index+1;j < current_size_of_handle_list;j++)
{
hThrd[j-1] = hThrd[j];
}
current_size_of_handle_list--;
if (current_size_of_handle_list == 0)
{
break;
}
}
else if (dwWake == (WAIT_OBJECT_0 + current_size_of_handle_list))
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if (dwWake == WAIT_TIMEOUT)
{
printmessage("TIMEOUT!");
}
else
{
printmessage("Goof!");
}
}
EDIT: Solved!
This may be an ugly solution - but I just changed the timeout from infinite to 20ms, then in the if (dwWake == WAIT_TIMEOUT) section I swapped printmessage("TIMEOUT!"); for:
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
I'm not closing this question yet because I'd still like to know why the original code did not work all by itself.
i can see 3 problems here:
the documentation for WM_PAINT says: The WM_PAINT message is generated by the system and should not be sent by an application. unfortunately i don't know any workaround, but i think SetWindowText() will take care of repainting the window, so this call may be useless.
SendMessage() is a blocking call and does not return until the message has been processed by the application. since painting may take a while to be processed, your program is likely to get hanged in your critical section, especially when considering my 3rd point. PostMessage() would be much better here, since you have no reason to need your window to be repainted "right now".
you are using QS_ALLEVENTS in MsgWaitForMultipleObjects(), but this mask DOES NOT include the QS_SENDMESSAGE flag. thus your SendMessage() call is likely ignored and does not wake your thread. you should be using QS_ALLINPUT.
can you check the behavior of your application with an INFINITE timeout and the above 3 modifications included ?
If I remember correctly, WM_PAINT is a very low priority message, and will only get relayed when the message queue is otherwise empty. Also, Windows will coalesce multiple WM_PAINT messages into one. I could see the mouse movement resulting in fewer redraw events, each handling a larger update, thus improving performance.
Well I can't totally help you because we don't have enough info but I had a similar problem where my application would not refresh unless I moved the mouse or after some (not unsignificant) delay.
When investigating the problem I found that basically, the GUI thread will sleep if there is no more messages to process. Jiggling the mouse will create new windows messages to be sent to the windows, waking the thread from sleep.
My problem was that I was doing my processing in the OnIdle (MFC, not sure about you) function, and that, after doing the processing one time, the thread would go to sleep.
I don't think that is your problem since you seems to post a windows message (WM_PAINT) from your thread, what I wasn't doing in my case (which should wake up the gui thread) but maybe this can help you get in the right direction to solve your problem?
Edit: I though about it a little, maybe there is a special case for WM_PAINT (like you forget to call Invalidate or something, I'm not an expert in windows programming) so maybe try to post another message like WM_USER to your application and see if it fix your problem (this should be sure to wake up the gui thread I think). Also posting the full call to the SendMessage function could help.
Edit2: Well, after seeing your comment to Kelly French above you seems to have exactly the same symptoms I had so I would guess that, for whatever reason, your call to PostMessage do not seems to wake up the gui thread or something similar. What are you passing for first argument to PostMessage? What I did in my case was to call PostMessage with argument WM_USER, 0, 0 to my app. You can also try the PostThreadMessage variant while keeping the current threadID of the main thread in a variable (see GetCurrentThreadId).
Also you could try to call Invalidate on your object. Windows keeps memory of if an object need to be repainted and will not do it if it is not needed. I do not know if a direct call to WM_PAINT override this or not.
Well that's all I can think of. At least you found a fix even if it is not the most elegant.
Are you completely sure that the program really runs faster? Or is it output that is refreshed more frequently?
Are you using SendMessage or PostMessage? I'm curious if perhaps switching to the other will make things work "better" in this particular environment.
Taken from developerfusion:
There’s another similar API which
works exactly like SendMessage and
that is PostMessage API. Both require
same parameters but there’s a slight
difference. When a message is sent to
a window with SendMessage, the window
procedure is called and the calling
program (or thread) waits for the
message to be processed and replied
back, and until then the calling
program does not resume its
processing. One thing is wrong with
this approach however, that is if the
program that is busy carrying out long
instructions or a program that has
been hung and hence no time to respond
to the message will in turn hang your
program too because your program will
be waiting for a reply that may never
arrive. The solution to this is to use
PostMessage instead of SendMessage.
PostMessage on the otherhand returns
to the calling program immediately
without waiting for the thread to
process the message, hence saving your
program from hanging. Which of them
you have to use depends on your
requirement.
Is your GUI window maximized? Does it happen whether the mouse movement happens over your app window or over some other window like another app or the desktop? When the mouse moves over your app, the mouse_move messages get sent to your message queue. This may wake up the thread or be forcing a WM_PAINT message.
I doubt that the printing is actually going faster. I suspect that the increased number of messages caused by the mouse movement is forcing more window invalidation events so the text updates are happening on a more granular basis. When the mouse isn't being moved does the printing happen in larger blocks, say blocks of 20 characters vs 5 characters at a time?
Could you clarify what you mean by faster printing? Is it absolute, like 100 characters per minute vs 20 characters per minute? Or is it more like 100 characters per minute either way but they show up in blocks when the mouse is still?
One possibility is that you are seeing the effect of the OS doing thread priority boosting / retarding for certain GUI messages.
I am assuming you have one ”GUI & Other Stuff” thread, and multiple worker threads. When there is no GUI activity, the “Other Stuff” thread goes to a lower priority. When you wiggle the mouse or timeout, the “Other Stuff” thread goes to a higher priority.
Changing the worker threads to a lower priority and then wiggling the mouse, would confirm or refute this.
I think it has to do with processing in foreground and background. If the operating system thinks your window is not top priority it shifts your job to background. If you are forcing the window to be on top, it will put all its resources to work on your window and drops the other items it is working on. Its real and its been here since DOS. http://en.wikipedia.org/wiki/Foreground-background You might try calling the following at critical times in your code.
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Avoiding "(Not Responding)" label in windows while processing lots of data in one lump

I occasionally need to process a large amount of data from one package off the network, which takes sufficiently long that when the user tries to interact with the application windows adds the "(Not Responding)" string to the window title. I am aware this is because the processing is being done within a call to handle a message (some way up the stack) and therefore is blocking the message pump. I'm also aware the ideal way to deal with this is to process the data asynchronously in a separate thread so the pump can continue running, however this is a LARGE desktop application which is single threaded from top to toe and safely spinning this processing off is not feasible in our time frame.
So with that in mind, is there by any chance a way I can at least avoid the "not responding" moniker (which to most users reads as "has crashed") by telling windows my application is about to be busy before I begin the work? I believe there is something along these lines when responding to a request to close, one can keep asking windows for more time to avoid it proclaiming that your not "closing in a timely fashion"
I should add this is a C++ MFC application.
I don't think the Windows API can help you here.
Alternatively, how about showing a dialog box with a progress bar and make it run in a separate thread?
A text like "This operation may take half an hour" on the dialog box may be appropriate too.
Ok, firstly I upvoted Frederick's post because like it or not, the second thread is probably the best way to go.
However, if you really don't want to go down this road, you could manually pump the message queue within your apps inner loop. Something like this;
int Refresh()
{
MSG msg;
if (PeekMessage (&msg, NULL, 0, 0,PM_NOREMOVE))
if ((msg.message == WM_QUIT)
||(msg.message == WM_CLOSE)
||(msg.message == WM_DESTROY)
||(msg.message == WM_NCDESTROY)
||(msg.message == WM_HSCROLL)
||(msg.message == WM_VSCROLL)
)
return(1);
if (PeekMessage (&msg, NULL, 0, 0,PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return(0);
}
This is actually a piece of code I used prior to rewriting something similar as a seperate thread. Basically I have a look at the queue, filter out unwanted messages, and post on the rest. It works to an extent, but caused some occasional nasty side effects, hence the rewrite.
You don't have to actually do anything with the messages from PeekMessage. Just call PeekMessage, you don't even have to remove anything from the queue or process it. As long as it is called every 5 seconds or so, it will cause windows to think the process is still responsive.
An alternative idea is to have a separate process/thread that will appear in the notification tray and inform the user that the process is busy waiting for an internal operation to complete. You'll see these in the later versions of Visual Studio, SQL Server Management Studio, etc.
Win32 has a method for this in user32.dll.
DisableProcessWindowsGhosting()
Disables the window ghosting feature for the calling GUI process. Window ghosting is a Windows Manager feature that lets the user minimize, move, or close the main window of an application that is not responding.
In addition to the above documented behavior, I also verified here (in a C# application) that this Win32 call also prevents the Not Responding label from appearing on the window as desired.
I found this via the C# answer to similar question here: https://stackoverflow.com/a/15380821/29152.
If you fork off a thread you're most likely worried about some other user action happening which may depend on the result of the long running operation (yeah, concurrency). So expanding on what Fredrick said, if you do spin off a new thread and put up a progress bar, you could lock the focus onto the progress bar to stop a user from interacting with the rest of the application. That should be enough to implement a really simple second thread without really having to worry about concurrency because you're essentially locking out the rest of the app by disabling user interation.
You'll need to interleave the processing with message handling somehow. If threads are out of the question, you might want to look at splitting the processing into multiple phases. One way to do this is to do some processing when you first receive the packet, then post a message to the application saying "continue processing here". When the application receives the "continue processing here" message, it will do some more processing, and either send another "continue processing here" message or finish up.
There are a couple of considerations though:
You need to make sure that the state of the application is consistent every time you post a message to yourself and defer to the message loop, as other message handling might happen in the mean-time. This can be done e.g. by only changing the state in the final processing phase.
Another packet might arrive while you are still processing the first packet. If changing the order of processing would be bad for the application, you could handle this by e.g. posting a "remind me to process this packet later" message when this happens.
I don't know whether this would be feasible within the design of your application, but it would be one way to solve the problem.
If you are unwilling to spawn a worker thread, but you can break the long-running task down into smaller parts, you can do the processing in MFC's CWinApp::OnIdle. This function gets called from within the message pump loop whenever there are no Windows messages waiting. As long as the work you do in each OnIdle call is sufficiently short, you keep your app responsive.
Assuming that it is the processing of the data that is taking up all the time and not the receiving (and you're serious about avoiding a thread - which is fine IMOHO) of the data you could:
In the function that you are currently handling the message, create a modal dialog that shows a "please wait" message (or make it hidden, small, whatever...). Copy (or send a pointer, etc...) the data you're processing to a member variable of that dialog.
In the modal dialog post a user-defined message to yourself to process the data.
In the dialog's message handler, handle one "unit" of work. Keep track what the next "unit" of work is. Post the same message again.
Repeat this post-message "loop" until done. Close your dialog.
The nature of the modal dialog will keep you're application "responsive", with minimal interruption or change to how the application worked previously. Reentrancy can be a problem with modal loops, especially if any of this is involved with a WM_PAINT message. (anyone ever assert inside painting code? good times, good times...)
The dialog could even have a cancel button if you'd like.
I encountered the exact same problem.
Since I dont consider the other answers appealing/straightforward I decided to post this.
Short description and some context:
I am saving data from a grid into a database, and this process can take a while. So I changed the saving method to an asynchronous method and had the same problem.
Then I came up with a simple solution:
//__ENABLE OR DISABLE MAIN DIALOG
void CMFCApplication1Dlg::enableMainDlg(bool enable)
{
this->EnableWindow(enable);
}
When starting the asynchronous method, I disable the main dialog.
This prevents the user from interacting with the main dialog (like starting another saving process which could result in thousands of SQL error messages if I wouldn't check if the saving process is already running...)
When the saving process is finished, I re-enable the main dialog.
Works like a charm, I hope this helps
One way to overcome your application from becoming unresponsive you need to tell the application to process messages from windows. When you are in your loop you can call
Application->ProcessMessages();
I had a similar issue with a win32 app that was waiting on a response from webservice using cpprest (Casablanca) api. My solution was to create a event and thread that does nothing but wait for the cpprest api and then release the thread once it recieves the signal:
DWORD WINAPI WaitForCasablanca(LPVOID n)
{
// Get the handler to the event for which we need to wait in
// this thread.
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, false, "MyEvent");
if (!hEvent) { return -1; }
// Loop through and wait for an event to occur
// Wait for the Event
WaitForSingleObject(hEvent, INFINITE);
// No need to Reset the event as its become non signaled as soon as
// some thread catches the event.
CloseHandle(hEvent);
return 0;}
BOOL WINAPI DlgProc(HWND hDlg, UINT message, WPARAM,wParam, LPARAM lParam) ...
HANDLE hEvent = CreateEvent(NULL, false, false, "MyEvent");//create an event that will wait for casablanca ro authenticate
if (!hEvent) return -1;
// Create a Thread Which will wait for the events to occur
DWORD Id;
HANDLE hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WaitForCasablanca, 0, 0, &Id);
if (!hThrd) { CloseHandle(hEvent); return -1; }
makeCasablancaRequest(...);
SetEvent(hEvent); //casablanca has finished signal the event to terminate
WaitForSingleObject(hThrd, INFINITE); //wait for thread to die
CloseHandle(hThrd);
CloseHandle(hEvent);
...}
That got rid of the "program not responding" message for me. I believe the problem is the code that is getting the data is running in a thread too- only the main program doesn't know this- so as far as the system is concerned the main program is idling. You need an event and a thread that waits for the event to tell the system the program is waiting on data. I got the code from this tutorial: How to use WIN32 Event Kernel Object

KeyboardProc returning TRUE causes performance drops

I'm developing an interface for an add-on to a game. I can't use the game API (for several reasons including the fact that the code must be game-agnostic) and I need to get keyboard input from the user so I've decided to use a keyboard hook (WH_KEYBOARD) to process user input when certain conditions are met.
The problem is that while I can receive and process the input correctly, when my hook returns TRUE instead of CallNextHookEx the system seems to take up a lot of time (well over 800ms) before letting things go on as expected and that's not acceptable because it doesn't even allow for a fluid typing experience.
What I have to achieve is preventing the key press message to reach the WndProc, so the question is: what can I do to achieve my target without hurting the game performance so much that the result will be unacceptable?
EDIT: due to specific requirements (games using anticheats which might create problems with my code despite it's not cheating-related) subclassing the active wndproc is not an option.
First you need your DLL to be injected into the target process, either by hooks, or by any other way.
Find the window handle of interest.
Obtain the current window procedure of that window, by calling GetWindowLongPtr(wnd, GWLP_WNDPROC), and save it.
Sub-class the window, by calling SetWindowLongPtr( wnd, GWLP_WNDPROC, &NewWndProc ) where NewWndProc is your DLL-implemented message procedure.
Inside NewWndProc you'll want to process keyboard messages (there're a dozen of them, type "keyboard input" in MSDN index, I can't post more then 1 link). For the rest of windows messages call the original window procedure you've saved during (3), and return the value it returned. Don't call it directly, use CallWindowProc instead.
This way is not very reliable, some antivirus and anti-bot (e.g. "warden client") software might not like it, and debugging may be challenging.
However it should work.
A keyboard hook should not make things that slow. There's probably something else going on that causes the 800ms delay. Is it still slow if your hook does nothing and simply returns TRUE?
If you want to prevent from message to arrive to the WndProc then you need to subclass using SetWindowLong, this way you will be able to catch all messages and decide if to continue their route.
As much as I don't like answering my own question I've found the cause of the delay. The message pump of the games I've tested my code against was implemented with a while(PeekMessage) { GetMessage... } and removing the keyboard input message somehow caused GetMessage to block for sometime. Using PostMessage and WM_NULL helped preventing GetMessage from blocking.