How do you get CreateWindowEx() to create the window on a specific monitor?
I've determined that I can use GetSystemMetrics(SM_CMONITORS) to query the number of attached monitors, but is their any way to control what monitor CreateWindowEx() uses for the window?
Yes, by the "x" and "y" arguments. Use EnumDisplayMonitors (pass two nulls) to enumerate the monitors. Your MonitorEnumProc callback gets a RECT* to the monitor's display rectangle. You'd get a negative RECT.right if a monitor is located at the left of your main one.
Each monitor simply displays some part of the desktop, so showing the window on a particular monitor is a matter of moving the window to the part of the desktop displayed by that monitor. When you call CreateWindowEx (or CreateWindow) you can specify x and y coordinates for the window, so displaying it on a particular monitor simply means specifying coordinates that fall within the area displayed by that monitor.
You can find the work areas for the monitors on a system with GetMonitorInfo.
The x and y parameters specify the location of the new window. This point can be anywhere on the virtual screen (all the monitor rectangles combined).
Either way, once you have a HMONITOR handle you must then call GetMonitorInfo. Your x and y parameters should be a value inside the bounds of the rcWork member in the monitor info struct. You would normally choose values that puts your window in the center of this rectangle.
It is important to use the workarea rectangle and not the full monitor rectangle because you don't want your window to appear underneath the Taskbar and other always-on-top appbars.