DirectX SDK |
This topic pertains only to application development in C and C++. See DirectDraw Visual Basic Samples.
This program demonstrates some of the techniques that can be used in writing an application that takes advantage of multiple monitors.
Source: (SDK root)\Samples\Multimedia\DDraw\Src\Multimon
Executable: (SDK root)\Samples\Multimedia\DDraw\Bin\Multimon.exe
The application does not require input. Click anywhere or press ESC to quit.
To use the multimonitor functions such as GetMonitorInfo and MonitorFromRect on Windows 95, you can include the file Multimon.h. In addition, in one of the C or C++ files, you need to define COMPILE_MULTIMON_STUBS before including Multimon.h. This allows the multimon functions to return reasonable values when running on Windows 95.
When enumerating DirectDraw devices, you can use either DirectDrawEnumerate or DirectDrawEnumerateEx. DirectDrawEnumerateEx is available on Windows 98 systems with DirectX 5.0 and later, and all other systems with DirectX 6.0 or later.
Because not all systems can be assumed to have DirectDrawEnumerateEx, DirectDraw was formerly set up so developers had to use LoadLibrary and GetProcAddress to check for its presence. In DirectX 7.0 this restriction has been removed, so you can call DirectDrawEnumerateEx directly, but you should note that this will prevent your program from running on a system which does not have DirectX 7.0 or later installed. This sample shows how to do the LoadLibrary/GetProcAddress technique, and how to fall back on DirectDrawEnumerate if DirectDrawEnumerateEx is not available.
Full-screen, multimonitor applications need to deal with focus and device windows. The focus window receives user input messages, and the device windows are used to cover each screen. This program shows how to call IDirectDraw7::SetCooperativeLevel to properly create and assign these windows.
Each screen gets its own DirectDraw interface, and DirectDrawSurfaces created on one DirectDraw interface cannot be used by any other DirectDraw interface. So creating graphics that span multiple monitors takes some extra work.
This sample demonstrates two techniques. For best performance, video memory surfaces should be used. A separate video memory DirectDrawSurface must be created on each screen. For the cases where a system memory surface is required or desired, one must still create separate DirectDrawSurfaces for each screen, but they can be configured to point to the same surface data memory. The IDirectDrawSurface7::SetSurfaceDesc method can be used to accomplish this. Doing this has no performance impact, but it avoids unnecessary consumption of system memory.
IDirectDrawSurface7::Blt calls usually fail when they would cause data to be written outside the borders of the destination surface. This failure can be avoided by attaching clipper objects to the destinations. This sample shows how to create a clipper for each screen and attach it to the front and back buffers so that the sprite surfaces can be blitted without being manually clipped by the application first.