Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My subject may be a bit confusing, but it's correct. I have what i would a call a hierarchy of header files, all with classes that support classes up the line, and I'm having some difficulty with the information being passed down.

I am working on a small direct 3d application. The code is split up, where i have a header file called Engine.h, and then for right now, 2 headers that are included in it, Input.h and Graphics.h . At the top of Engine.h I have this entry:

C++
#include <Windows.h>

#include "Graphics.h"
#include "Input.h"


Now the weird thing is here, in the class i have defined in Input.h , it is able to use windows types just fine, namely HWND, but for some reason i get an error about missing types when trying to use HWND in my Graphics.h file. here is that file:

C++
#ifndef GRAPHICSCLASS
#define GRAPHICSCLASS

const bool VSYNC_DEPTH = true;
const float SCREEN_DEPTH = 1000.0f;
const float SCREEN_NEAR = 0.1f;

class GraphicsClass
{
public:
    GraphicsClass();
    ~GraphicsClass();

    bool Initialize(int, int, HWND);
    void Shutdown();
    bool Frame();

private:
    bool Render();

private:
};

#endif


The error I receive when attempting to compile this is exactly as follows:

1>------ Build started: Project: engine, Configuration: Debug Win32 ------
1>  Graphics.cpp
1>c:\users\wyatt\documents\visual studio 2010\projects\engine\engine\graphics.h(15): error C2061: syntax error : identifier 'HWND'
1>c:\users\wyatt\documents\visual studio 2010\projects\engine\engine\graphics.cpp(14): error C2061: syntax error : identifier 'HWND'
1>  Generating Code...
1>  Compiling...
1>  Engine.cpp
1>  Generating Code...
1>  Compiling...
1>  EntryPoint.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


I just assume that this error has to do with it not finding the HWND type, but could it be something else? any help would be appreciated. BTW, MSVC++ express.

EDIT: Here is the Input.h file:

Input.h
C++
#ifndef _INPUTCLASS_H_
#define _INPUTCLASS_H_

#define DIRECTINPUT_VERSION 0x0800

#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

#include <dinput.h>


class InputClass
{
public:
	InputClass();
	~InputClass();

	bool Initialize(HINSTANCE, HWND, int, int);
	void Shutdown();
	bool Frame();
	bool IsEscapePressed();
	void GetMouseLocation(int &, int &);

private:
	bool ReadKeyboard();
	bool ReadMouse();
	void ProcessInput();

private:
	IDirectInput8* m_directInput;
	IDirectInputDevice8* m_keyboard;
	IDirectInputDevice8* m_mouse;

	unsigned char m_keyboardState[256];
	DIMOUSESTATE m_mouseState;
	
	int m_screenWidth, m_screenHeight;
	int m_mouseX, m_mouseY;
};

#endif
Posted
Updated 21-Sep-11 21:16pm
v8
Comments
Emilio Garavaglia 22-Sep-11 3:17am    
replaced < > and removed spurious tags

Include the windows header files in each of your headers files as they are needed.
So use #include <WinDef.h> or #include <Windows.h> in your Graphics.h file.

To answer why Input.h does work without including #include <Windows.h>:
Your Input.h file includes dinput.h, which in turn includes objbase.h, which in turn includes many other header files. At some point in this chain of headers the header that defines HWND is included, hence the fact that Input.h works without including Windows.h.
This should not be relied on though and it is better practice to also include #include <WinDef.h> or #include <Windows.h> in your Input.h file.

Include Windows.h multiple time:
This is not a problem, the file contains preprocessor directives[^] that ensure it is actually included only once.
C++
#ifndef _GNU_H_WINDOWS_H
#define _GNU_H_WINDOWS_H
..
#endif /* _GNU_H_WINDOWS_H */
 
Share this answer
 
v3
Comments
FatalCatharsis 21-Sep-11 8:46am    
hmm, yeh, that works, but i'm still curious why i'm able to use the types in my input.h file without needing to include windows. thanks for your help though :P
André Kraak 21-Sep-11 9:17am    
I have updated the solution.
André Kraak 21-Sep-11 8:48am    
Would you please post the Input.h file so I can have a look at it?
FatalCatharsis 21-Sep-11 9:36am    
ah, intersting, this actually explains alot of other instances where i had similar issues. Are there any problems with including windows multiple times throughout the program?
André Kraak 21-Sep-11 10:40am    
I have updated the solution.
While your problem is solved, here is some advice how to tackle problem of this type (and improve your use of #include statements):

For any header causing a problem do the following:
1. Create a .cpp file that contains nothing but an #include statement to that header (plus maybe an include to the precompiled header, if you use one)
2. remove all #include statements in your header file (or comment them out, you might need them later)
3. compile your .cpp file
4. look at the text output of your compiler and find the first error message; it might complain about some 'unknown symbol'.
5.a) If there is no more 'unknown symbol' message your done with that header!
5.b) If there is an unkown symbol message, see if you can work without it, using a forward declaration; if not, check the documentation which include file you need for that symbol, and add an #include for that. Then continue with 3.

I can't stress enough that you check the documentation (or ask someone familiar with the library) to find the right header file to include. Often you will not want to directly include the one file that contains the definition, but one that contains (or includes) some related stuff as well which may be required for that definition. (Such dependencies shouldn't exist, but unfortunately they do. The main point of the algorithm outlined above is to avoid such dependencies in your own headers.)

When you're done with all offending headers, do the same with any .cpp file that won't compile due to unknown symbols: steps 2. to 5, only this time don't use forward declarations.

This may take quite some time, but it will remove problematic dependencies between your headers, especially those that require you to include them in specific order, and it might reduce your build time. (I once spent the better part of a week to clean up such dependencies in a large project, and in the end the compile time was reduced to a third!)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900