Now the thread takes about 5 seconds to execute, which is a problem because the WaitForSingleObject function pauses the program for a few seconds.

Now if i dont call the WaitForSingleObject() function, is there any kind of function i can call to check if the thread is still active? Specifically code within WM_TIMER can only be executed if the thread has finished execution.

Set a global flag just before you start the thread. The WM_TIMER code tests that flag and only executes the critical code if it's not set. Just before the thread functions ends, the last action it performs is to reset the flag.
You don't even need thread synchronization for that.

All the buzzt! CornedBee

"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law