When a thread calls CoInitialize(NULL) or CoInitializeEx(NULL,COINIT_APARTMENTTHREADED), it creates a new STA apartment. The creating thread is said to be in the apartment. When the thread later instantiates a COM object, the COM object is said to be in the apartment(this is only valid when the COM dll has a value “ThreadingModel=Apartment” in the registry). The first STA is called main STA. The COM object without the value “ThreadingModel=Apartment” in the registry will be put into the main STA whichever thread created it. A process has only one main STA and may have multiple other STAs. A thread can only be in one apartment.
A thead calls CoInitializeEx(NULL, COINIT_MULTITHREADED) to create a MTA, and the thread is said to be in the MTA. A process can have at most one MTA. Other threads calling CoInitializeEx(NULL, COINIT_MULTITHREADED) join the MTA instead of creating additional MTAs. The COM objects with ThreadingModel=Free in registry will be put into the MTA no matter how the thread creating it initializes the COM lib. If no MTA is available when creating the COM object with ThreadingModel=Free in registry, the COM lib will create a host MTA to host the COM.
A COM object with ThreadingModel=Both in registry will be put in its creating thread’s apartment. So, if its creating thread is in a STA, the COM object is in that STA. If the creating thread is in the MTA, the COM object is in that MTA.
If a MTA thread instantiates a COM object with ThreadingModel=Apartment, the COM lib will create a new HOST STA (i.e., create a new thread which calls CoInitializeEx(NULL,COINIT_APARTMENTTHREADED)) and instantiate the COM object in that new thread.
The methods of a COM object in an apartment can be called directly by the thread(s) in the same apartment. The calls to the methods of COM objects in other apartments different than the apartment of the calling thread are marshaled.