Question: I'm just curious as to to how to implement multi-threading without using a Windows API WaitFor\* function that stops the program until the thread has returned. What's the point of using threads if they stop the main application from being resized or moved etc.?

Is there any form of windows messaging with threading, which will allow me to call my thread function and then return, and handle the return values of the thread when it finishes running?

Answer: 
If you want your UI thread to know when a task thread has finished it's task then you could have your task thread post a (custom - WM\_USER and above) message to your main window (along with thread id plus the handle). And the window proc of the main window can know that a particular task thread has finished it's task. This way the UI thread does not have to wait actively (using WaitFor\*) on the thread(s) object.
[`WaitForSingleObject`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx) can be non-blocking, just pass zero timeout as second parameter:

```
// Check is thread has been finished
if(::WaitForSingleObject(threadHandle, 0) == WAIT_OBJECT_0)
{
   // Process results
   ...
}

```

You will need to periodically check this condition, e.g. on timer or after processing any message in message loop.

Or you can use [`MsgWaitForMultipleObjectsEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms684245%28v=vs.85%29.aspx). It will unblock and return when some message/input event occured in calling thread message queue.

As other answers mentioned there is another way - using Windows asynchronously posted message to signal that thread has done its work. This way has disadvantage - the working thread must know target window or thread to post message to. This dependency complicates design and raises issues about checking thread/window lifetime. To avoid it message broadcasting (`PostMessage(HWND_BROADCAST,...)`)
can be used, but this is overkill for your case, I don't recommend it.