The normal way of doing it or more accuartely the way I do it is.

I start a thread in the Message Loop and then return so that the Message Loop is not blocked and use the MsgWaitForSingleObject for the completion of the thread.

Now in the body of the thread there is a check for a variable which just stops the running thread and sets the event so that the wait is over and the job is cancelled.