![]() |
| Home | Introduction | Table of Contents | Updates | New Stuff | Links | About the Authors | Ordering | ||
|
Enumerating the Display
Monitors New in Windows 98,
ME, and 2000 is the ability to attach more than one monitor to a
single computer. These
platforms provide support for a virtual desktop that spans
multiple display monitors, each with its own unique resolution
and color-depth. From a
programming perspective, there is little that you need to do for
multiple monitor support—the systems manages most of the
details. In some
situations, however, you might want to take advantage of the
system’s support for mutiple monitors to increase the
functionality of your application. For example, if you’re
creating an application that occupies a large portion of the
screen, you might want to implement a feature that allows your
application to conform to the dimensions of a particular
monitor.
const int num_monitors = GetSystemMetrics(SM_CMONITORS);
To enumerate the available display monitors on systems running Windows 98, Me, or 2000, you use the EnumDisplayMonitors function:
BOOL EnumDisplayMonitors ( IN HDC hdc, // handle to a display device context IN LPCRECT lprcClip, // pointer to a clipping RECT IN MONITORENUMPROC lpfnEnum, // pointer to a callback function IN LPARAM dwData // application-defined data that will be // passed to the callback function );
The hdc parameter identifies the
display device context whose visible area is used as a filter
during the enumeration process. This parameter is useful when
you’re interested in enumerating only those monitors that
intersect a particular region. This region is formed by the
intersection of the visible area of the device context
(identified by the hdc parameter) and the
clipping rectangle identified by the lprcClip parameter. For the purpose of enumerating all
display monitors, you can simply set both of these parameters to
NULL. The lpfnEnum parameter is a pointer
to an application-defined callback function; if you need to
supply extra information to this function, you can use the
32-bits available via the dwData parameter.
typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
The first parameter is of type HMONITOR, a handle to a display monitor. From within the callback function, you can pass this value to the GetMonitorInfo function to retrieve monitor-specific information. For example, the code in Listing 1.6 enumerates all of the display monitors, retreiving the color-depth of each monitor. Listing 1.6 Enumerating the available monitors under Windows 98, Me, or 2000. // ------------------------------------------------------------------ // Windows 2000 Graphics API Black Book // Chapter 1 - Listing 1.6 (EnumDisplayMonitors Demo) // ------------------------------------------------------------------
#define WINVER 0x0500 #include <windows.h>
HWND hListBox; const int ID_BUTTON = 101;
HINSTANCE hInst; LPCSTR WndClassName = TEXT("GMainWnd"); LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, LPARAM LParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { hInst = hInstance;
WNDCLASS wc; memset(&wc, 0, sizeof(WNDCLASS));
wc.lpfnWndProc = MainWndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1); wc.lpszClassName = WndClassName;
if (RegisterClass(&wc)) { HWND hWnd = CreateWindow(WndClassName, TEXT("'EnumDisplayMonitors' Demo"), WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_VISIBLE | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 320, 225, NULL, NULL, hInst, NULL);
if (hWnd) { ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } return 0; }
// // this is the application-defined callback function // BOOL CALLBACK EnumMonitorsProc(HMONITOR hMonitor, HDC hdc, LPRECT lpRMonitor, LPARAM dwData) { MONITORINFOEX mix; memset(&mix, 0, sizeof(MONITORINFOEX)); mix.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, &mix)) { HDC hMonitorDC = CreateDC("DISPLAY", mix.szDevice, NULL, NULL); // for Win98: // CreateDC(NULL, mix.szDevice, NULL, NULL);
if (hMonitorDC) { const int color_depth = GetDeviceCaps(hMonitorDC, BITSPIXEL) * GetDeviceCaps(hMonitorDC, PLANES); DeleteDC(hMonitorDC);
char szColorDepth[2]; wsprintf(szColorDepth, "%d", color_depth);
HWND hListBox = reinterpret_cast<HWND>(dwData); SNDMSG(hListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(mix.szDevice)); SNDMSG(hListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(szColorDepth)); SNDMSG(hListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("")); } } return true; }
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { // create a push button CreateWindow(TEXT("BUTTON"), TEXT( "Enumerate"), BS_FLAT | WS_CHILD | WS_VISIBLE, 200, 5, 100, 25, hWnd, reinterpret_cast<HMENU>(ID_BUTTON), hInst, NULL);
// create a list box hListBox = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT( "LISTBOX"), "", WS_CHILD | WS_VISIBLE | WS_VSCROLL, 10, 5, 175, 190, hWnd, NULL, hInst, NULL); break; } case WM_COMMAND: { // when the button is clicked... if (wParam == MAKEWPARAM(ID_BUTTON, BN_CLICKED)) { // fill the list box with monitor info EnumDisplayMonitors( NULL, NULL, EnumMonitorsProc, reinterpret_cast<LPARAM>(hListBox) ); } break; } case WM_DESTROY: { PostQuitMessage(0); break; } } return DefWindowProc(hWnd, msg, wParam, lParam); |
||
|
|
||
|
Copyright
© 2001 Damon Chandler and Michael Fötsch
|
||