Hi everyone,
I'm trying to add the functionality to toggle a fullscreen/windowed mode in my current DirectX 9 project. Unfortunately, whenever I try to do this, I get an access violation. Based off of tutorials at http://www.chadvernon.com/blog/tutorials/directx9/, I build my presentation parameters as follows:
BOOL BuildPresentParameters( int width, int height )
{
ZeroMemory( &m_pp, sizeof(m_pp) );
D3DFORMAT adapterFormat = (m_Windowed) ? m_displayMode.Format : D3DFMT_X8R8G8B8;
if ( SUCCEEDED( m_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
m_pp.AutoDepthStencilFormat = D3DFMT_D24S8;
}
else if ( SUCCEEDED( m_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
m_pp.AutoDepthStencilFormat = D3DFMT_D24X8;
}
else if ( SUCCEEDED( m_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
m_pp.AutoDepthStencilFormat = D3DFMT_D16;
}
else
{
SHOWERROR( "Unable to find valid depth format", __FILE__, __LINE__ );
return FALSE;
}
m_pp.BackBufferWidth = (m_Windowed) ? 0 : width; //m_displayMode.Width;
m_pp.BackBufferHeight = (m_Windowed) ? 0 : height; //m_displayMode.Height;
m_pp.BackBufferFormat = adapterFormat;
m_pp.BackBufferCount = 1;
m_pp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_pp.MultiSampleQuality = 0;
m_pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_pp.hDeviceWindow = m_hWnd;
m_pp.Windowed = m_Windowed;
m_pp.EnableAutoDepthStencil = true;
m_pp.FullScreen_RefreshRateInHz = (m_Windowed) ? 0 : m_displayMode.RefreshRate;
m_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
return TRUE;
} // BuildPresentParameters()
At that point, when I later call "m_pDevice->Reset( &m_pp );" I get that access violation.
Now, I'm not throwing everything into your lap here. I've done some debugging of my own, and I think I've narrowed down the problem to the "hDeviceWindow" setting in the present parameters, and, more specifically, my m_hWnd value. This is the code I use to create it:
BOOL Initialize( LPSTR title, HINSTANCE hInstance, int width, int height, BOOL windowed )
{
m_hInstance = hInstance;
m_WindowWidth = width;
m_WindowHeight = height;
// Define the window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_DBLCLKS;
wcex.lpfnWndProc = (WNDPROC)IFramework::StaticWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CGPICON ) );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH) GetStockObject( BLACK_BRUSH );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = title;
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CGPICON_SMALL ) );
// Register the window
RegisterClassEx( &wcex );
// Create the window
m_hWnd = CreateWindowEx( NULL,
title,
title,
windowed ? ( WS_OVERLAPPEDWINDOW & ( ~( WS_THICKFRAME | WS_MAXIMIZEBOX ) ) ) : WS_EX_TOPMOST,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
NULL,
NULL,
hInstance,
this );
// Adjust to desired size
RECT rect = { 0, 0, width, height };
AdjustWindowRect( &rect, GetWindowLong( m_hWnd, GWL_STYLE ), FALSE );
SetWindowPos( m_hWnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
SWP_NOZORDER | SWP_NOMOVE );
// ... Unimportant code here.
} // Initialize()
When I debug that code, I find that my hWnd's "unused" value is undefined (with the code CXX0030), even right after it's set by CreateWindowEx(). I know from comparing it to previous projects, which have that unused value set to zero, something is wrong here. I've also noticed that the access violation is also always in the address equal to the hexidecimal value of that unused value. My question to you all is what I could be doing for this unused value to be set to something other than zero, and if that value is undefined the entire time, why does my game only crash when I try to reset the device, rather than when I initialize it for the first time?
I also could be completely off-base, and the access violation when resetting could be from something entirely different, but this is my hunch. Any help would be appreciated! Thank you!
[Edited by - Spinewire on July 10, 2008 7:01:34 PM]