Introduction
When I was writing the GXTS screensaver for http://www.goheer.com, one of the problems I faced was support for multiple monitors. My goal was to display the same image on all monitors connected to the system regardless of their number.
There are many articles available online relating to multiple monitors, all of which provided no help to me. Somewhere someone is using ::GetSystemMetrics
, while another is registering self made classes just to make the multiple monitor thing work. That lead me to go and search for an easy solution as I was not using MFC or any other fancy library. In the end, I was very surprised to find an easy solution in MSDN library. Let's take a look at the solution.
Background
Basic knowledge of Win32 API.
Using the code
Normally, when you are handling the WM_PAINT
event, you do this... catch the WM_PAINT
and draw whatever you have to in that block.
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdcE = BeginPaint(hWnd, &ps );
EndPaint(hWnd, &ps);
}
break;
OK, now if we have 2+ monitors and you want to call the paint procedure for each one of it, just use the EnumDisplayMonitors
function and supply a callback function where you will be doing painting for each monitor. In this case, I am supplying the callback function MyPaintEnumProc
.
case WM_PAINT:
{
PAINTSTRUCT ps = {0};
HDC hdcE = BeginPaint(hWnd, &ps );
EnumDisplayMonitors(hdcE,NULL, MyPaintEnumProc, 0);
EndPaint(hWnd, &ps);
}
break;
Now, let's examine the callback function MyPaintEnumProc
. By supplying a HDC
as first param and NULL
as lprect
in second argument, the system will call our callback function for each monitor. Every time hMonitor
will be the handle to the monitor for which that function is called, hdcl
will be the HDC
to that monitor, and lprcMonitor
will be monitor intersection rectangle. Lastly, in our case, data will be null because we supplied 0 as last argument to EnumDisplayMonitors
.
BOOL CALLBACK MyPaintEnumProc(
HMONITOR hMonitor,
HDC hdc1,
LPRECT lprcMonitor,
LPARAM data
)
{
RECT rc = *lprcMonitor;
return 1;
}
Remember to return true in MyPaintEnumProc
to enumerate through all monitors. If you returned false, the enumeration will stop at that point.
Points of Interest
If you think the screenshot of the screensaver "GXTS" is cool then try it and let me know about your comments. It's available free on http://www.goheer.com.
History
First release of this code.