A secondary thread with an object window should be terminated by the window procedure in the primary thread that initially created the secondary thread. This is achieved simply by posting a WM_QUIT message to the object window, which will cause the message processing loop for the secondary thread to terminate.
The thread's main routine then issues WinDestroyWindow() calls for its object windows. These calls cause WM_DESTROY messages to be posted to the object windows, which will process these messages in order to close data objects, release any resources, etc., in accordance with established conventions.
Once all data objects and other resources have been released or destroyed, the thread should terminate itself using the _endthread() function. The use of this function will ensure that the semaphores and control structures used by the _beginthread() function are correctly reset.