Hello everyone.

As the title suggests i need to implement a type of timer based function inside a UI Thread in MFC.
Although CWinThread is a UI Thread and has a message pump it does not have a Timer function as CWnd::OnTimer

Is there any way i can implement a timer based function inside a CWinThread, being also able of course to accept messages coming from other threads?

I tried using a while loop (with or without a Sleep() call) inside CWinThread::Run function but it appears that this technique is preventing the messages to be received. (I've overriden PreTranslateMessage and it's never being called)

I also tried to utilize the CWinThread::OnIdle but the results are kind of the same.

In conclusion there is no way to implement a timer based check inside a CWinThread and be able to receive messages from other threads at the same time.
Or is it?

You could ask me why i do not use a worker thread instead (since i don't actually create any graphical content inside my CWinThread), but i would like to send messages to the thread, and avoid using shared/global variables for communication.

So is there anyway to handle this?
I would like any suggestions.

I hope my description is clear enough.
:D

Thanks in advance!

Dani AI

Generated

Short expert summary tied to the thread: the symptom described by (PreTranslateMessage never called while a Sleep/while loop runs) is almost always the message pump being blocked or replaced. Messages and WM_TIMER deliveries depend on a running message loop and on the thread having an actual message queue. As noted, messages are thread-specific; a thread must therefore run a proper pump to receive them. 's suggestion of timer APIs is a valid alternative when the pump approach is not desired.

Two practical, robust patterns:

  • Let MFC handle timers and messages: keep the normal CWinThread run/pump, install a message map and an OnTimer handler, and create the timer after the pump is running. Avoid long blocking calls inside the pump.
  • Implement a combined wait+dispatch loop when the thread must also do periodic work: wait on a waitable timer (or use MsgWaitForMultipleObjects) so the thread wakes either for messages or for the timer. On wake, peel off messages with PeekMessage/DispatchMessage; on timeout perform the periodic task.

Example skeleton (for illustration):

MSG msg;
while(running) {
  DWORD r = MsgWaitForMultipleObjects(1, &hTimer, FALSE, timeout, QS_ALLINPUT);
  if (r == WAIT_OBJECT_0) { /* timer signaled — do periodic work */ }
  while (PeekMessage(&msg, NULL,0,0,PM_REMOVE)) {
    if (!PreTranslateMessage(&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); }
  }
}

Troubleshooting and cautions: ensure the thread creates its message queue (call PeekMessage/GetMessage early) before relying on PostThreadMessage; WM_TIMER-based timers are low-resolution and only fired when the pump runs; CreateTimerQueue callbacks may run on pool threads (different context); avoid posting raw pointers without ownership guarantees; offload heavy processing to other threads to keep the pump responsive.

Recommended Answers

All 5 Replies

it does not have a Timer function as CWnd::OnTimer

Not to worry, SetTimer() is a global win32 api function, so just call that in CWinThread.

Is there any way i can implement a timer based function inside a CWinThread, being also able of course to accept messages coming from other threads?

Messages are thread specific, one thread can not get another thread's messages. See Remarks here

would like to send messages to the thread

CWinThread is not going to help you with that. Just create a worker thread and call PostThreadMessage()

CreateTimerQueue

Perhaps CreateTimerQueue, CreateTimerQueueTimer, DeleteTimerQueueTimer would do what you want. Plus it's easy to wrap them into a class.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682483%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687003%28v=vs.85%29.aspx

Thanks i will try that.

Not to worry, SetTimer() is a global win32 api function, so just call that in CWinThread.

Did try it but no WM_TIMER messages ever arived in the PreTranslateMessage.

Messages are thread specific, one thread can not get another thread's messages. See Remarks here

I don't want to get another thread's message. I want my CWinThread to be able to accept messages through PostThreadMessage.

CWinThread is not going to help you with that. Just create a worker thread and call PostThreadMessage()

I think not. Worker threads have no message queue as far as i understand.

I don't want to get another thread's message.

My misunderstanding. In that case yes, CWinThread will probably work. As for worker threads, you can put a message pump into them so that they can receive messages. Not usually done though.

As for worker threads, you can put a message pump into them so that they can receive messages. Not usually done though.

Nice to know that.

Anyway i found this:
http://forums.codeguru.com/showthread.php?393149.html
and it seems to work. SetTimer actually works on a CWinThread, i just had to override it and declare a message map. I thought since it was not a class member it wouldn't work but it does!

I just hope it doesn't blow up in my hands eventually!
:)

Thanks for the insight!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.