I've spent a huge amount of time working with POSIX on lots of platforms, and with WIN32 in the areas of I/O, events and threads to a lesser extent.
WaitForMultipleEvents is not a strong point of WIN32 because it has so many limitations, and because you need to deal with the windows message queue and Winsock differently, and async I/O has lots of ways to report status, each with different performance characteristics and working with different versions of Windows. Apart from waiting for events and objects, there's APCs and Completion Ports and Vista's GetQueuedCompletionStatusEx, and you can wait on I/O handles or OVERLAPPED objects. For some things you need to create a "window" to receive events, though it's not really a "GUI window" as another post suggests, just a Windows object for demultiplexing the message queue.
POSIX is equally ugly when it comes to waiting for different things at the same time: select, aio_suspend, semop. With POSIX and WIN32 both, you have to use threads to wait for different classes of thing together. Like WIN32, POSIX select() has a fixed limit on the number of handles you can wait for: FD_SETSIZE, typically 256. Like WIN32, there are methods and alternate APIs to overcome the limits.
WIN32 I/O API is quite sensible. Basically equivalent to POSIX with a few extra options, and longer names for things. It's always had async I/O, and the I/O event dispatch is versatile (too versatile: no less than 4 ways to wait for async I/O), though awkwardly the different options aren't orthogonal. However, in practice you can't use all the options on all versions of Windows in every combination; it's not as orthogonal as it looks. The async I/O doesn't work on every version, and lacks important functionality prior to Vista.
It's all much the same as Linux really. WIN32 API is better documented and makes sense, but has a bunch of limitations and version-specificity, which isn't very well documented. Linux is similar when you use the non-POSIX APIs like epoll and eventfd.
WIN32's DLLs are a mess compared with ELF. Especially dynamically loading - enjoy the crashes, lockups (prior to Vista) and lack of load-time initialisation. People have to stick to certain patterns of DLL use to avoid the obscure problems which are quite nasty.
WIN32's threading primitives: mutexes, condition variables and so on were poor compared with POSIX threads, until Vista. Vista copies some of the good stuff and is comparable with Linux NPTL, that is to say, quite good. Vista's async I/O is better than Linux's and POSIX generally. But who wants to write Vista-specific code?