Error C2065 "undeclared identifier" with copy-n-pasted sample code

Started by
10 comments, last by _Sauce_ 16 years, 6 months ago
I'm just starting to build an Isometric game engine but I'm having troubles with my code. I get the error ".\Direct3D.cpp(25) : error C2065: 'hWnd' : undeclared identifier" when compiling my code. I've followed 3 tutorials over and over again but no matter what I do, the code doesn't compile, not even a direct copy paste will compile. IsometricEngine.cpp:
#include <windows.h>
#include "Direct3D.h"

const char g_szClassName[] = "Simple Window";

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
		{
		case WM_CLOSE:
			DestroyWindow(hWnd);
		break;
		case WM_DESTROY:
			Cleanup();
			PostQuitMessage(0);
			return 0;
		case WM_PAINT:
			Render();
			ValidateRect(hWnd, NULL);
			return 0;
		default:
			return 0;
		} //switch(msg)
	return DefWindowProc(hWnd, msg, wParam, lParam);
} //WndProc()


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	MSG msg;

	wc.cbSize			=	sizeof(WNDCLASSEX);
	wc.style			=	0;
	wc.lpfnWndProc		=	WndProc;
	wc.cbClsExtra		=	0;
	wc.cbWndExtra		=	0;
	wc.hInstance		=	hInstance;
	wc.hIcon			=	LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor			=	LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	=	(HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName		=	NULL;
	wc.lpszClassName	=	g_szClassName;
	wc.hIconSm			=	LoadIcon(NULL, IDI_APPLICATION);

 	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window registration failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName,
		"Isometric Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
		CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);

	if(hWnd == NULL)
	{
		MessageBox(NULL, "Window creation failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	while(GetMessage(&msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
} //WinMain()
}

Direct3D.cpp:
#include <windows.h>
#include "Direct3D.h"

///////////////////////////////////////////////////////////
// InitD3D()
///////////////////////////////////////////////////////////
HRESULT InitD3D()
{
	if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
		return E_FAIL;

	LPDIRECT3DDEVICE9 pDevice = NULL;

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	d3dpp.BackBufferWidth	=	640;
	d3dpp.BackBufferHeight	=	480;
	d3dpp.BackBufferFormat	=	D3DFMT_UNKNOWN;
	d3dpp.BackBufferCount	=	1;
	d3dpp.SwapEffect		=	D3DSWAPEFFECT_FLIP;
	d3dpp.Windowed			=	TRUE;
	
	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))
		return E_FAIL;

	// Set device state.

	return S_OK;
}

///////////////////////////////////////////////////////////
// Render()
///////////////////////////////////////////////////////////
void Render(void)
{
    if( NULL == g_pD3DDevice )
        return;

    // Clear the backbuffer to a blue color
    g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
    
    // Begin the scene
    if( SUCCEEDED( g_pD3DDevice->BeginScene() ) )
    {
        // Rendering of scene objects can happen here
    
        // End the scene
        g_pD3DDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pD3DDevice->Present( NULL, NULL, NULL, NULL );
}

///////////////////////////////////////////////////////////
// Cleanup()
///////////////////////////////////////////////////////////
void Cleanup(void)
{
    if( g_pD3DDevice != NULL) 
        g_pD3DDevice->Release();

    if( g_pD3D != NULL)
        g_pD3D->Release();
}


Direct3D.h:
#pragma once

#include <D3d9.h>

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;

HRESULT InitD3D();
void Cleanup(void);
void Render(void);


Any ideas? EDIT: "Annoying error" is not an appropriate subject line and it's preferred if you use 'source' tags instead of 'code' tags for larger blocks of code. Thanks. [Edited by - _Sauce_ on September 18, 2007 9:10:35 AM]
Advertisement
Quote:
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,		D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))		return E_FAIL;


I guess the hWnd symbol is neither a local nor a global variable. I suggest you pass it as a parameter to that function.
Hitting "F1" in your IDE should bring up a page similar to this. It explains the error in full and really should be your first port of call in future [wink]

Also, simply copy-n-paste coding is prone to this sort of issue - if you're going to carry on learning this way then it might be worth taking the time to understand what this error actually means and how you fix it. Such skills are essential for serious software development.

Oh, one final thing - this isn't really anything to do with DirectX even if thats what you're coding. The HWND is part of the underlying Win32 API, the part that creates a window to display your Direct3D content in. I'm going to move this to a more appropriate forum; posting a link to the tutorial you're using might help.


Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by jollyjeffers
Hitting "F1" in your IDE should bring up a page similar to this.

Wow, I know you're a MVP and all, but I never have thought Microsoft would replace its MSDN libraries with your forum. [lol]
Hey guys.

Sorry for using code tags instead of source tags. It's been a while since I posted here and I couldn't remember which ones to use. Sorry also for the bad topic title and incorrect forum. My bro was rushing me to get off the computer so I had to make it quick.

Now that that is out of the way, I would like to point out a few things you seem to have misunderstood from my initial post. 1) The code I am using is completely from scratch. I'm piecing it together from the knowledge I have learned from the tutorials i am using, DirectX Tutorial.com and The Forger's Win32 Tutorial. I have tried direct copy pastes of the DXTutorial code which didn't work, and have also tried modifying the Forger's Win32 tutorial to add DX functionality. I have even tried using the DirectX documentation alone to create a successful app, but none have so far worked. I have gotten these code samples to work in the past but it's been an awful long time since I have programmed and I have long since reformatted. I had no trouble programming beyond this small issue in the past.

ToohrVyk: I have already tried passing it as a parameter to the function, however this causes 3 link errors:

Compiling...
Direct3D.cpp
Linking...
Isometric Engine.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) already defined in Direct3D.obj
Isometric Engine.obj : error LNK2005: "struct IDirect3DDevice9 * g_pD3DDevice" (?g_pD3DDevice@@3PAUIDirect3DDevice9@@A) already defined in Direct3D.obj
Direct3D.obj : error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "long __cdecl InitD3D(struct HWND__ *)" (?InitD3D@@YAJPAUHWND__@@@Z)
C:\Documents and Settings\Hillam\My Documents\Visual Studio 2005\Projects\Isometric Engine\Release\Isometric Engine.exe : fatal error LNK1120: 1 unresolved externals

EDIT: Forum stretching fixed. Sorry about that.

JollyJeffers: I tried pressing F1 but all it gave me was a page with a list of C++ keywords. I'm not sure this is what you intended to show me?
I think this may be due to the fact that I am passing it to the function as a HWND. What type of variable should I use in place of this? (dammit I really need to go back and read my C++ books :P)

[Edited by - _Sauce_ on September 19, 2007 8:05:23 AM]
Quote:Original post by _Sauce_
ToohrVyk: I have already tried passing it as a parameter to the function, however this causes 3 link errors:


No, it doesn't.

The C++ build process contains two steps: compiling and linking. The errors for the linking stage are not displayed until all errors for the compiling stage are. So, by correcting the compiling stage errors, you are now faced with your linking stage errors.

You have two errors: the first is referencing Direct3DCreate9 without linking the correct library (check your SDK documentation for the library to link, though I suspect it's d3d9.lib).

The second error comes from defining a global variable in two translation units. You need to define your global variable in one translation unit only (and, if other translation units need it, you can declare it as extern). readme.
gotcha. sorry about that. Like I said it's been a while.

I could have sworn I linked those .libs - ill go check now. Thanks for the article, too. I printed out a copy. It's very clear and helpful. :)
Ok, I fixed the linker errors with inclusion guards in my header files as well as adding d3d9.lib to be linked and moving my globals into the source files rather than the headers, but now when my app runs I get "Window creation failed!" The code that would appear to be responsible is the following:

HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName,	"Isometric Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,	CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);	if(hWnd == NULL)	{		MessageBox(NULL, "Window creation failed!", "Error!",			MB_ICONEXCLAMATION | MB_OK);		return 0;	}


I read through the documentation for the CreateWindowEx function and it says that a few things can cause it to return NULL, and thus cause the error window to show;


  • an invalid parameter value,

  • the system class was registered by a different module,

  • the WH_CBT hook is installed and returns a failure code, or

  • the window procedure fails for WM_CREATE or WM_NCCREATE.


I suspect that it is being caused by an invalid parameter value in my code, however I have double checked this against the documentation as well as the previously mentioned tutorials, and it all appears to be correct. Can you guys spot anything that may be a bit off?

[Edited by - _Sauce_ on September 20, 2007 8:05:05 AM]
bump.

I've checked the parameters over and over and still nothing...
What does GetLasError tell you?

This topic is closed to new replies.

Advertisement