Fullscreen on second display

System: windows xp, 1 ati video card (radeon x600), 2 monitors

A simple program that changes the video mode with ChangeDisplaySettingsEx, creates a window (in proper position for fullscreen mode), sets up opengl and displays some shapes, works correctly when targetted to the first monitor, but the display is corrupted (only about 1/3 of the screen is rendered, desktop shows through on other 2/3) when the second monitor is used. The size of the window does not matter; even if it is smaller than the new video mode the display is still wrong.

Using the second monitor (“fullscreen” or not) without changing the video mode in the application works normally. Calling ChangeDisplaySettingsEx with the same video mode that is in use also works.

Any ideas?
A pointer to more documentation for ChangeDisplaySettingsEx and the members of devmode would also be helpful, as I have not found much.

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

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.