Here is a program that shows the problem. It will try to display something on the second monitor, if it is on the left of the primary and supports 1024x768 (use q to exit). It is based on the wgl sample animate.
</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”> /* An example of an OpenGL animation loop using the Win32 API. Also
demonstrates palette management for RGB and color index modes and
general strategies for message handling. */
#include <windows.h> /* must include this before GL/gl.h /
#include <GL/gl.h> / OpenGL header file */
#include <stdio.h>
#include <multimon.h>
HDC hDC; /* device context /
HPALETTE hPalette = 0; / custom palette (if needed) /
GLboolean animate = GL_TRUE; / animation flag */
void
display()
{
/* rotate a triangle around /
glClear(GL_COLOR_BUFFER_BIT);
if (animate)
glRotatef(1.0f, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glIndexi(1);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2i(0, 1);
glIndexi(2);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2i(-1, -1);
glIndexi(3);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2i(1, -1);
glEnd();
glFlush();
SwapBuffers(hDC); / nop if singlebuffered */
}
LONG WINAPI
WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
switch(uMsg) {
case WM_PAINT:
display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_SIZE:
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam) {
case 27: /* ESC key */
case 'q':
PostQuitMessage(0);
break;
case ' ':
animate = !animate;
break;
case 'm':
{
RECT wclr, wcr;
GetClientRect(hWnd,&wclr);
ClientToScreen(hWnd,&wclr.left);
ClientToScreen(hWnd,&wclr.right);
GetWindowRect(hWnd, &wcr);
wclr.left-=wcr.left;
wclr.top-=wcr.top;
wclr.right-=wcr.right;
wclr.bottom-=wcr.bottom;
SetWindowPos(hWnd, HWND_TOPMOST, -1024-wclr.left, -wclr.top, 1024+wclr.left-wclr.right, 768+wclr.top-wclr.bottom, 0);
}
break;
}
break;
case WM_ACTIVATE:
if (IsIconic(hWnd))
animate = GL_FALSE;
else
animate = GL_TRUE;
return 0;
case WM_PALETTECHANGED:
if (hWnd == (HWND)wParam)
break;
/* fall through to WM_QUERYNEWPALETTE */
case WM_QUERYNEWPALETTE:
if (hPalette) {
UnrealizeObject(hPalette);
SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
return TRUE;
}
return FALSE;
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
typedef BOOL (WINAPI * Function_EnumDisplayDevices) (PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
typedef HMONITOR (WINAPI * Function_MonitorFromWindow) (HWND hwnd, DWORD dwFlags);
typedef BOOL (WINAPI * Function_GetMonitorInfo) (HMONITOR hMonitor, LPMONITORINFO lpmi);
typedef LONG (WINAPI * Function_ChangeDisplaySettingsEx) (LPCSTR, LPDEVMODE, HWND, DWORD, LPVOID);
static Function_MonitorFromWindow pMonitorFromWindow = 0;
static Function_GetMonitorInfo pGetMonitorInfo = 0;
static Function_EnumDisplayDevices pEnumDisplayDevices = 0;
static Function_ChangeDisplaySettingsEx pChangeDisplaySettingsEx = 0;
HWND
CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int n, pf;
HWND hWnd;
WNDCLASS wc;
LOGPALETTE* lpPal;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;
DISPLAY_DEVICE dd;
RECT wclr, wcr;
HMODULE hmodule;
/* only register the window class once - use hInstance as a flag. */
if (!hInstance) {
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if (!RegisterClass(&wc)) {
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return NULL;
}
}
hWnd = CreateWindow("OpenGL", title, WS_POPUP |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);
if (hWnd == NULL) {
MessageBox(NULL, "CreateWindow() failed: Cannot create a window.",
"Error", MB_OK);
return NULL;
}
hmodule = LoadLibrary("user32.dll");
pEnumDisplayDevices = ((Function_EnumDisplayDevices) GetProcAddress(hmodule, "EnumDisplayDevicesA"));
dd.cb = sizeof(DISPLAY_DEVICE);
if (pEnumDisplayDevices (NULL, 1, &dd, 0))
{
DEVMODE sm;
sm.dmSize = sizeof(DEVMODE);
sm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
//sm.dmBitsPerPel = 32;
sm.dmDriverExtra = 0;
//EnumDisplaySettings (dd.DeviceName, ENUM_CURRENT_SETTINGS, &sm);
sm.dmPelsWidth = width;
sm.dmPelsHeight = height;
ChangeDisplaySettingsEx (dd.DeviceName, &sm, NULL, CDS_FULLSCREEN, NULL);
EnumDisplaySettings (dd.DeviceName, 0, &sm);
GetClientRect(hWnd,&wclr);
ClientToScreen(hWnd,&wclr.left);
ClientToScreen(hWnd,&wclr.right);
GetWindowRect(hWnd, &wcr);
wclr.left-=wcr.left;
wclr.top-=wcr.top;
wclr.right-=wcr.right;
wclr.bottom-=wcr.bottom;
SetWindowPos(hWnd, HWND_TOPMOST, -1024-wclr.left, -wclr.top, width+wclr.left-wclr.right, height+wclr.top-wclr.bottom, 0);
}
hDC = GetDC(hWnd);
/* there is no guarantee that the contents of the stack that become
the pfd are zeroed, therefore _make sure_ to clear these bits. */
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
pfd.iPixelType = type;
pfd.cColorBits = 32;
pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0) {
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return 0;
}
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return 0;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE