Unhandled exception with CreateWindowEx crashes app

Started by
10 comments, last by sirlemonhead 16 years, 7 months ago
This problem has recently developed on my machine, and i'm at a loss as to how to fix it. Running XP SP2, and compiling my apps with VS 2005 standard, with the summer 2003 dx 9 sdk. I've got a small application here to create a win32 application window. It contains directx code also, but it never reaches the point where any directx objects or devices get initialised. This is the problematic piece of code, from what I can gather.


INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR cmdLine, int cmdShow  )
{
	 // Register the window class
	WNDCLASSEX wc;
	wc.cbSize  = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
	wc.lpfnWndProc = MsgProc; 
	wc.cbClsExtra = 0; 
	wc.cbWndExtra = 0; 
	wc.hInstance = hInstance; 
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = LoadCursor( hInstance, IDC_ARROW ); 
	wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); 
	wc.lpszMenuName = NULL; 
	wc.lpszClassName = "D3D"; 
	wc.hIconSm = NULL; 

     RegisterClassEx( &wc );

	 HWND hWnd = CreateWindowEx( NULL, "D3D", "D3D Application", 
			WS_OVERLAPPEDWINDOW, 
			CW_USEDEFAULT, 
			CW_USEDEFAULT, 
			300, 
			300, 
			GetDesktopWindow(), 
			NULL, 
			hInstance, 
			NULL );

The application compiles fine, and runs fine on any machine other than my own one. I've got applications from friends that compile and works fine on other machines, but will show the same problem if compiled and ran on my machine. I get a "The instruction at "0x10006621" referenced memory at "0x01d63cb0". The memory could not be "read" if I run the .exe. If I debug, I get this error "Unhandled exception at 0x10006621 in test.exe: 0xC0000005: Access violation reading location 0x01d63cb0." The line that visual studio shows the problem located at is the last parameter of CreateWindowEx, the final NULL parameter (this is the line that the green arrow points to, but i'm unsure if that means the error is on that line or the previous one?) At this point, the IDE shows that hInstance contains the value 0x0040000. Expanding information on this shows it as unused (I guess it wouldnt be used at this stage so all is normal?) I'm at a loss as to what the issue could be.. Any ideas?
Advertisement
Place your cursor on the first line of your code inside WinMain. Press F9 to set a breakpoint. Press F5 to start your application in the debugger. It will pause at the first line. Press F10 on each line until you see the error dialog. The line with the indicator next to it is the offending line. Post that line of code.

(PS. Congratulations! You've just learned about the integrated graphical debugger. [smile])
The yellow arrow gets down to the last parameter of the CreateWindowEx function,

eg:
	 HWND hWnd = CreateWindowEx( NULL, "D3D", "D3D Application", 			WS_OVERLAPPEDWINDOW, 			CW_USEDEFAULT, 			CW_USEDEFAULT, 			300, 			300, 			GetDesktopWindow(), 			NULL, 			hInstance, (arrow is here)		NULL );


I then press f10 once more, up pops the error message, and the yellow arrow has changed to a green arrow, but remains on the same line.
The arrow break at the last line of the function, but it's clearly the CreateWindowEx function who crashed. It tried to load something at "0x01d63cb0" and what's there is a wrong value. Now fast like that your code seem ok but just hover your cursor above the variables to see which one point to "0x01d63cb0". Maybe "MsgProc" don't exist? My guess go with the GetDesktopWindow(),.. are you sure you need to pass the desktop as the parent?
Replace GetDesktopWindow() with NULL? same problem.

I'm not seeing any variable pointing to that memory address :(

What's odd about it is that this code will work fine on my second machine.

Could it be a hardware memory problem perhaps?
As Oluseyi stated, stepping through the code in the debugger is the best bet.

While a memory access violation can be caused by hardware and corrupt device drivers (why it might work on one machine and not another), I'm not so sure this is the case with you, as if CreateWindowEx was broken when it came to memory, programming would be the least of your worries.

I'd just request a few changes. Mostly stylistic, as you're handling the situation, but I'd like to know exactly what these return.

Place:

memset((WNDCLASSEX*)&wc, 0, sizeof(WNDCLASSEX)); before you initialize the values (just to be sure. It doesn't look like you're missing anything though), and when you register it, assign the value.

ATOM test = RegisterClassEx(&wcex);

Also, please post your MsgProc.
I'm suspicious of this line:

wc.hCursor = LoadCursor( hInstance, IDC_ARROW );


I think it should be:

wc.hCursor = LoadCursor( NULL, IDC_ARROW );


From PSDK:

Quote:
To use one of the predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the following values...


Generally I believe you only pass the hInstance as the first parameter to LoadCursor or LoadIcon if you are loading from the exe's resources.

HTH
ATOM test shows a value of '52428' when I start running through the program, but then changes to '49749' when it reaches the CreateWindowEx function.

I added the line to zero the memory, didn't fix anything but i'll remember to use it in future :)

I changed the cursor line also. Didn't fix anything either. I've actually changed this code around a lot since the problem originally occured, and as such didn't even have the cursor line in the original version of the code.

here's my MsgProc:

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){	switch( msg )     {        case WM_CHAR:          PostQuitMessage( 0 ); // Exit Sample on any keypress. Sample only.          return 0;        case WM_DESTROY: // If you use Windowed mode process loss of it          PostQuitMessage( 0 );          return 0;        case WM_PAINT:          // NOTE: In a full-screen app, you may choose to draw the screen at          // a different point, such as using a timer message or outside of          // the windows message loop        Render();        ValidateRect( hWnd, NULL );        return 0;     }     return DefWindowProc( hWnd, msg, wParam, lParam );}


Render() calls:
void Render(){     if( dx8.pd3dDevice == NULL)          return;     // Clear the backbuffer to a white color     dx8.pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,           D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );     // Begin the scene     dx8.pd3dDevice->BeginScene();     // Rendering of scene objects	 DrawScene();     // End the scene     dx8.pd3dDevice->EndScene();     // Present the backbuffer contents to the display     dx8.pd3dDevice->Present( NULL, NULL, NULL, NULL );}
Just so you know, the first value you see of test ('52428') is garbage, since the variable have not been affected with anything yet, in your case not even been defined/created. But, after RegisterClassEx the value seem ok, since from MSDN:

Return Value    If the function succeeds, the return value is a class atom that uniquely identifies the class being registered. [...]    If the function fails, the return value is zero. To get extended error information, call GetLastError. 


MsgProc look ok, Render() have nothing to do with it. I would try the LoadCursor thing EasilyConfused talked about.
Quote:Original post by sirlemonhead
The application compiles fine, and runs fine on any machine other than my own one. I've got applications from friends that compile and works fine on other machines, but will show the same problem if compiled and ran on my machine.


If you are absolutely certain of the bit I've quoted above, given that all the code you've posted looks okay, I'd say that your next step should be to reinstall VS on your machine to be honest.

Maybe a problem with the VS C/C++ runtime?

This topic is closed to new replies.

Advertisement