As a general rule, a thread can access only MFC objects that it created. This is because temporary and permanent Windows handle maps are kept in thread local storage to help maintain protection from simultaneous access from multiple threads. For example, a worker thread cannot perform a calculation and then call a document's UpdateAllViews member function to have the windows that contain views on the new data modified. This has no effect at all, because the map from CWnd objects to HWNDs is local to the primary thread. This means that one thread might have a mapping from a Windows handle to a C++ object, but another thread might map that same handle to a different C++ object. Changes made in one thread would not be reflected in the other.
There are several ways around this problem. The first is to pass individual handles (such as an HWND) rather than C++ objects to the worker thread. The worker thread then adds these objects to its temporary map by calling the appropriate FromHandle member function. You could also add the object to the thread's permanent map by calling Attach, but this should be done only if you are guaranteed that the object will exist longer than the thread.
Another method is to create new user-defined messages corresponding to the different tasks your worker threads will be performing and post these messages to the application's main window using ::PostMessage. This method of communication is similar to two different applications conversing except that both threads are executing in the same address space.
TN003: Mapping of Windows Handles to Objects