We had an issue recently where DDE broadcasts were being blocked on a system. The customer noticed that the problem happened after they called MAPIInitialize on their worker thread. Our investigation gives us a chance to add a 5th rule to the MAPI Multithreading Rules I wrote about a few years ago:
5. The first thread to initialize MAPI must pump messages.
To understand this, first we need to know a bit about DDE. Turns out, Raymond wrote about it a couple times already, so I don’t need to rehash that. The second thing to know is that MAPI uses a hidden window for idle processing. If you dig around a bit, you might even find the window, named “WMS Idle”. MAPI only needs one of these per process, so it’s created on the first thread to initialize MAPI. And as we know, any thread with a window on it must pump messages.
In the customer’s case, they were pumping on the main thread, but not on the MAPI worker thread. Once they inserted message pumping into the MAPI worker thread, DDE was no longer blocked. Alternatively, they could have called HrDispatchNotifications, which is a simple way to pump messages, or called MAPIInitialize on the main thread.