That's what I was thinking, but I found an article from 1994 claiming that ole would be shortly moving to the DCE RPC protocol instead of using window messages (and so they did).
I guess they didn't purge window messages entirely.
Actually, it looks like they didn't: http://www.microsoft.com/msj/0596/activex0596.aspx
so it seems window messages are still used for RPC when no networking is involved.
This looks like the part that should be most interesting to us... (below) I didn't see anything to indicate that RPC uses messages (If i'm reading your comments correctly, it sounds like you think it does?). However, in order to avoid the blocking RPC system call, the thread enters a message loop and makes the RPC system call on another worker thread (when a call is made within the channel implementation). If this pool of threads and worker-made-call functionality is not currently implemented in the standard IRpcChannelBuffer implementation in WINELIB, then we probably need to implement it somehow.
As shown in Figure 4, the Apartment model uses additional threads to achieve the reentrancy requirements for OLE. In the Apartment model, when the client thread makes a method call on an object in a different thread, process, or host, the client is actually making a method call on a proxy. The proxy marshals the appropriate parameters into the request PDU and dispatches the call to the object by calling the channel's SendReceive method, which does not return until the response PDU is received from the object. For those of you new to standard marshaling, a channel is just a COM-based wrapper around the RPC run-time layer. Once inside the implementation of the channel, the client thread does not call the low-level RPC run-time routine directly. Instead, the client thread spawns a worker thread to perform the blocking call and then waits in a modal message loop so external method requests can be serviced as well. (An application can install a message filter inside this modal loop to allow or disallow incoming method requests and non-OLE window messages. See CoRegisterMessageFilter for details.) This modal loop continues until the worker thread notifies the client thread that the response PDU was returned by the RPC run time. When the modal loop exits, the channel's SendReceive method returns the response PDU to the proxy for unmarshaling to the client. Because all of this happens behind the channel's IRpcChannelBuffer interface, the client and proxy are blissfully unaware that anything other than a blocking call took place. To avoid excessive thread creation, COM maintains a pool of worker threads that perform blocking RPC calls. The number of threads in the pool grows and shrinks based on the number of outstanding calls.
Kelly