BOOL CMemeDlg::PreTranslateMessage(MSG* pMsg)
{
CString csMessage;
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_HOME)
{
KillTimer(TIMER_ID_FIELD);
SetTimer(TIMER_ID_FIELD, 500, NULL);
return true;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
In this code snippit will the timer lock up a thread, assuming that there's no other KillTimer somewhere else in the code flow?
If there is no KillTimer() at all, SetTimer() will simply reset an existing timer if it already exists. So you are not going to be over-burdening the thread with multiple timers.
The WM_TIMER message is a synthesized message. When message retrieval is performed via (Get|Peek)Message() and there are no actual messages available in the queue (or if message retrieval is filtering for WM_(SYS)TIMER specifically), then the timer is checked and an actual WM_TIMER message is generated in the message queue only if the timer has elapsed.
So, as long as you are processing those WM_TIMER messages properly, you won't over-burden your thread with unnecessary timer processing.
Just be careful that you don't perform a lot of message retrievals that ignore WM_TIMER, otherwise you can fill up your message queue (see Even though mouse-move, paint, and timer messages are generated on demand, it’s still possible for one to end up in your queue and Why is my message queue full of WM_TIMER messages?.
No. Just every 500msec the WM_TIMER message will be sent.
If the handler is lightweight you will not even see any activity in the task manager.
Related
I have issue with thread-safe callbacks.
void draw_something() { /* draws something */ }
And the question is, how to call draw_something in main application thread every specify amount of time irrespective of other code(so it would act like C# Timer and fire function in main thread)? Earlier I was using CreateWindow to create(in main thread) auxiliary window which handles messages from SendMessage(which was sent from another timer-thread):
void MainThreadFunction(){
CreateThread(0, NULL, GoProc, NULL, NULL, NULL);
}
DWORD WINAPI GoProc(LPVOID lpParam){
while(1){
SendMessage(auxiliary_window_hWnd, ADDINATIONAL_MESSAGE, 0, 0);
Sleep(30);
}
return 0;
}
So window's MessageQueue deals safethread calls, but I don't think if it's very efficient and elegant way to do it. I know there is better way(maybe boost?) but I don't know it.
You can use the Windows SetTimer call to get a periodic WM_TIMER message and skip the second thread altogether.
You can't just magically "interrupt" the running thread and "inject" your own code, not in the userspace anyway.
The solution you already have, which is essentially a form of message passing, is fine if you don't have particularly strict temporal requirements.
If time is important to you, i.e. you have to guarantee certain latency between event (passage of time in your case) and processing of that event, you'll have to do the processing in the thread that "detected" the event or maintain a pool of worker threads ready to wake-up and do the processing on moment's notice. But I'm guessing draw_something() must be done on UI thread, so this solution is probably out.
I have a situation where I want to SendMessage to a window that was created on another thread than the one that is calling SendMessage.
The default behaviour seems to be block forever and not work.
So I changed the call to PostMessage, which didn't block the sending thread, but the message never appears to arrive at the intended window.
So how do I SendMessage to a window created on a separate thread, or is this impossible?
The PostThreadMessage function posts a message to the message queue of the specified thread. you can specified Identifier of the thread to which the message is to be posted. is that you want?
What is the thread that owns the target window doing? It needs to be pumping messages in order to be able to receive messages that are either sent or posted to it. Typically this is done by having a GetMessage/TranslateMessage/DispatchMessage loop. If the thread is doing something else - such as blocking waiting for an event or mutex or IO to complete, or is busy in some other loop carrying out a calculation, it won't receive messages: SendMessage to the thread will block, and PostMessage will post but not get delivered.
If that target thread needs to both manage events or similar, and it also owns a window, you may need to use MsgWaitForMultipleObjects in that thread's message loop.
You are running into a deadlock. An example, if you SendMessage to another thread, then the windowProc in that thread does SendMessage back to your window, they will lock waiting each other forever.
You need to either fix PostMessage (it does deliver messages, there's just error in your code somewhere), or be very careful about who calls who and when.
To protect against threads that are busy or hung, there is SendMessageTimeout.
Each control you create belongs to the thread that created it, which means that the WndProc for that control will be running in the thread that created the control. You send messages with SendMessage and PostMessage freely to any control.
The issue with CWnd::PostMessage and CWnd::SendMessage is the same. The message is being pushed out, and not being received by anything. SendMessage is blocking by design; it's job is to block the thread until the message is received.
MSDN says this about SendMessage:
"The SendMessage function calls the window procedure for the specified
window and does not return until the window procedure has processed
the message."
It is possible to send a message to window on another thread using CWnd::PostThreadMessage or winapi PostMessage. When you create the window you can use GetSafeHwnd() to get the handle or you can use a thread ID when the thread is created.
Theres some reason for this code not reach the first else?
I got it exactly the same from vairous sources. Than I did my own encapsulation. Everything goes fine. Window is created, messages are treated, events are generated to keyborad input in the client area, the gl canvas works fine (when I force it to draw).
The only problem is that message loop never leaves the first if. :/
I'm really stuck.
while (!done)
{
if (::PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
done = TRUE;
}
else
{
::TranslateMessage (&msg);
::DispatchMessage (&msg);
}
}
else
{
// Code is never reaching this!
draw ();
::SwapBuffers(hDC);
idle ();
}
}
return msg.wParam;
In your case the message queue must never be empty - why? Well it depends on what the rest of your program is doing. Some possibilities:
Your code is posting new messages to the queue in a manner such that the queue doesn't get empty. I'd suggest logging out the message ids as they are handled.
You aren't handling paint messages - from msdn:
"The PeekMessage function normally does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed. However, if a WM_PAINT message has a NULL update region, PeekMessage does remove it from the queue."
Hope this helps.
[Edit]
To handle WM_PAINT either call BeginPaint and EndPaint or forward to DefWindowProc
Make sure you are processing the WM_PAINT correctly.
By this I mean make sure you are calling BeginPaint and EndPaint from inside the WM_PAINT message, otherwise you will be confusing Windows into thinking your application still needs to be painted.
May be there is always a message waiting ?
PeekMessage will return 0 only if there are no messages in the message queue. Since there are messages to be dispatched in the message queue, it is returning a non-zero value and your else condition is never executed.
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
Can someone please point me to the easiest way to have a timer in a Win32 service?
I suppose I could create a dummy window for this purpose or have a second thread do tick counts, but what's best? Is there a more elegant way?
Thanks in advance.
You can use Timer Queues (http://msdn.microsoft.com/en-us/library/ms686796.aspx). They don't require an HWND.
Instead of using UI timers (even though you can use the NULL window handle as shown by Mr. 1800-INFO) you can use kernel waitable timer objects. See CreateWaitableTimer in the API docs. These can then be waited-on using WaitForSingleObject or WaitForMultipleObjects, etc, which is especially useful if that's already how your service waits for external events.
If it's not clear from that first link, the SetWaitableTimer function can associate a completion routine (user callback) with the timer. Remember to use the ...Ex versions of WaitForMultipleObjects (etc.) so that the thread is in an "alertable" state.
You can send your main thread WM_TIMER messages. The lParam for the message is the address of a callback function, or you can leave it NULL and handle it yourself in your message pump.
In this example, we are sending the timer to the thread message pump, there is no requirement to have a window associated with the timer.
UINT timer;
VOID CALLBACK Timer(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
KillTimer(0, timer);
}
timer=SetTimer(0, // window handle
0, // id of the timer message, leave 0 in this case
10000, // millis
Timer // callback
);
// pump messages
while (GetMessage) etc...
The Timer callback will be called by DispatchMessage. This question reminded me of the recent ONT.
You can use SetTimer to set the timer, then catch the WM_TIMER message in your message loop.
Example:
// Set a timer to expire in 10 seconds
SetTimer(hwnd,IDT_TIMER1, 10000,(TIMERPROC) NULL);
... then in message loop:
switch (wParam)
{
case IDT_TIMER1:
// Boom goes the dynamite
You can also decleare a function of type TIMERPROC and have that be called when the timer expires, if you don't want to do the message loop handling.
In one of your comments you said that "...the service is processing stuff in other threads, I just need to check the status of a few files every second."
Polling is not an optimal way of checking file status, and will adversely affect system performance. While there are (sometimes) problems doing this over networks, you should check out http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx or http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx for how to do it and http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx for why you should.
Are you just trying to "wake up" every now and then to do some work? You can always use Sleep().
Additionally, I typically have a thread that is in a while(1 == 1) loop with a sleep inside. There I can check for the shutdown request and other misc housekeeping. You could use that system to tickle an event or mutex for the worker thread in the app.