#include <windows.h> in MFC

I receive the following message many times when buiding a MFC program:

fatal error C1189: #error :  WINDOWS.H already included.  MFC apps must not #include <windows.h>

I incorporate some public domain libraries (JPEG and TIFF) that include windows.h themselves. Is there a general way to handle this problem? Thank you.
LVL 1
kentktAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chensuCommented:
You should include the MFC header files before including any other library header files.

#include <afxwin.h>  // or "stdafx.h"
#include "jpeglib.h"
0
chensuCommented:
If you include other header files first, which include <windows.h>, the _WINDOWS_ macro is defined and the MFC header files will detect it, thus the error message comes out.
0
SwordSaintCommented:
did u manually include the <windows.h> yourself?
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

chensuCommented:
As a general programming practise, I always include standard header files first followed by third party header files and finally my own header files.
0
kentktAuthor Commented:
chensu,

The problem is I cannot control the order of the inclusion:

// in mylib.h
#ifdef _WINDOWS
#include <windows.h>
#endif

// in stdafx.h
#include <afxwin.h>

// in mycpp1.cpp
#include <mylib.h>

// in mycpp2.cpp
#include <stdafx.h>

In mycpp1.cpp, I do not include "stdafx.h" because I want it to be a generic class that is to be compiled under different kinds of platforms. In mycpp2.cpp, the class is to be used under MFC only and so it includes "stdafx.h". Maybe I can change the filenames to force mycpp2.cpp to compile first. However, I think it is impractical in general.

Anyway, thank you for your proposal and you are welcome to give me more help on this topic.
0
chensuCommented:
Your actual case must be different from what you described here. The compiler compiles each .cpp file seperately. mycpp1.cpp won't conflict with mycpp2.cpp. If mycpp1.cpp does not use MFC while mycpp2.cpp uses MFC, it is not a problem. I have been doing so.

So, please check it carefully. The compiler should tell you which cpp file is being compiled when the error message occurs. Take that cpp file and check the order of all the #include statements carefully. It should follow the following order.

#include <standard header file>
#include "third party header file"
#include "your own header file"
0
kentktAuthor Commented:
chensu,

Thank you for your help first.

I have just fully reviewed one of the source file that causes the problem. In fact, includes several libraries indirectly. One includes <windows.h> while the the others include <afxwin.h>. It is again impractical to control the order of inclusion because:

1. My cpp file includes these libraries indirectly through the header files of other modules of my system at hand. Often I include module1 that includes lib1 and module2 that includes lib2 in arbitrary order. How can I order the inclusion of header files in general to prevent the problem?

2. Even though I can control the inclusion order of cpp1.cpp, it is hard to control the inclusion order of the header files included in cpp1.cpp. That means it is in general hard to control the order of inclusion if many header files and libraries are involved.

In fact, I want a solution THAT IS INDEPENDENT OF INCLUSION ORDER, which is a SOLUTION easily obtained myself by the error message itself. I want to have a solution that allows me to wildly include any header files in arbitrary order. Or, I want to know whether this solution exists.
0
LucHoltkampCommented:
I noticed that if I make a MFC app with VC6 (basic app generated with Wizard), I ALWAYS have to include <stdafx.h> as the first include file in all my source modules, even if they don't use MFC.
I did get strange errors if I didn't do so.

For example, I have a module that implement a certain protocol, and it's fully OS independent, so no MFC needed.
It's part of my library and I used it succesfully before on a Console application, however when I wanted to use it in a MFC app (basic framework generated with the Wizard), then if I didn't include <stdafx.h> in the *.cpp before anything else  (even before #defines) VC6 failed to include the headers correctly, complaining about 'unexpected end of file'. I didn't have time yet to find out why but I suspect it has something to do with precompiled headers... Our friends at Microsoft probably did something again which (only) makes perfectly sense to them :-)

But it is indeed very anoying... VC6 fails to compile ANY *.cpp file in a MFC project that doesn't include <stdafx.h> as the first thing.
Luc
0
kentktAuthor Commented:
Luc,

If what I understand from your comment is right, I can assert that I have faced your problem many times.

Try this: Open Project:Settings... and click the tab "C/C++". Select the "Pre-compiled Headers" and click the second option, allow VC to use pre-compiled headers automatically.

I don't know why the original codes fail, nor why this method success. Perhaps I should post this a question.
0
kentktAuthor Commented:
Luc,

I do aggree with you that Microsoft encourages novice C++ programmers to include stdafx.h as the first thing. This encourages un-reusability and makes people stick to VC forever.

Another problem with stdafx.h is that this file may have a different content if you choose different settings in AppWizard. That means, even if you stick to VC, you may have problems writing a library that ports to any program written with MFC.

Rediculous!

So, I started to include <afxwin.h> or other MFC headers rather than "stdafx.h".

BTW, anyone out there know why MFC forbids us to #include <windows.h> before <afxwin.h>? Any secrets behind the scene?

Kent.
0
mikeblasCommented:
> complaining about 'unexpected end of file'. I
 > didn't have time yet to find out why but I suspect
 > it has something to do with precompiled headers

It makes perfect sense to me, sure. And it makes perfect sense to almost anyone else who bothers to RTFM.  You've told the compiler that you plan to use precompiled headers via a certain #include directive, but you never invoked that #include directive. The compiler read all the way to the end of the file looking for it!

 > VC6 fails to compile ANY *.cpp file in a MFC project
 > that doesn't include <stdafx.h> as the first thing.

That's only true when you don't know what you're doing and give the compiler incorrect options.

I'm sorry you don't know how to use the tool--but you really should try to figure things out before lashing out at the tools and Microsoft.

..B ekiM
0
mikeblasCommented:
> Rediculous!

Uh, none of your points are valid. You're showing that you don't understsand what precompiled headers (and, maybe even header files, in general!) are all about. Plus, you spelled "ridiculous" wrong.

 > anyone out there know why MFC forbids us to #include <windows.h> before <afxwin.h>?

Because MFC itself is (well, at least, _was_) a cross-platform library. MFC wants to handle the inclusion of some of the system header files so that you get definitions that will match MFC for binary compatibility, and so that you'll get the right headers for the target system.

..B ekiM


0
kentktAuthor Commented:
mikeblas,

Thank you for your comment. Indeed I am always wondering what is going on for pre-compiled headers. Could you explain:

1. what is RTFM
2. what is the format of a pre-compiled heaer and how it is created?
3. the options of VC about pre-compiled headers?
4. what is the default behaviour about pre-compiled headers in VC?

Yes, I admit that I should understand the tools first and I am always trying to. However, the #include <windows.h> make me feel so sad because this must be a common problem and I cannot even find a Help document in VC.
Also, the default behaviours (eg. pre-compiled header)  are sometimes difficult for beginners.

Kent.
0
mikeblasCommented:
Just read the documentation for the C1010 error you received, LucHoltkamp:

Fatal Error C1010
unexpected end of file while looking for precompiled header directive

A precompiled header was specified, but it did not contain a precompiled header directive.

This error can be caused by specifying an incorrect file as a header file, or by specifying an include file with the /Yu (Use Precompiled Header) command line option that is not listed in the source file as an include file.


..B ekiM

0
mikeblasCommented:

 > 1. what is RTFM

[R]ead [t]he, uh, _[f]ine_ [m]anual! It's the step you skipped between getting an error message and publicly saying "Rediculous! [sic]".

 > 2. what is the format of a pre-compiled heaer and how it is created?

*.PCH files have an undocumented, proprietary format.

 > 3. the options of VC about pre-compiled headers?

/Yu, /Yc, and /YX.

 > 4. what is the default behaviour about pre-compiled headers in VC?

This question doesn't make any sense to me. Let me try to shotgun around to see if I can answer whatever it is you're asking:

The compiler has no default behaviour. It only uses (or creates) a precompiled only if you specifiy one of the above options (in #3).

An AppWizard-produced MFC project will use precompiled headers. STDAFX.CPP builds with /Yc, then every other file builds with /Yu. That way, if you want to reference a big header, or any header that's interesting to most of your modules, just edit STDAFX.H and put it in there. If you have a file that's changing lots, or of only local interest, reference it _after_ #include "stdafx.h" in any of your modules.

If you don't want to use stdafx.h, just make sure you turn off /Yu. (That's how you avoid C1010, LucHoltkamp.)

 > this must be a common problem

It isn't.  I mean, it might be common among people who don't understand what they're doing, but it's not common among people who understand how a compiler works.

..B ekiM
0
Tommy HuiEngineerCommented:
Hi Kent,

1. RTFM is Read The Fine Manual (although Fine is typically replaced with another 7 letter word, "F***ing")

2-4. Precompiled headers is a difficult option for beginners to understand, because it does some "magic" behind the scenes to improve compiling time. Typically, this works great and most people don't learn about it. It is only when it doesn't work correctly that people get frustrated with it.

Okay, imagine a large project. This large project contains about 50 header files each about 500 lines long. All of the source files (.cpp) include some subset of these 50 header files and other system files. Now, in the case of no precompiled headers, the compiler has to read each .cpp file and for each header file, parse it. This is quite time consuming, especially if most of the header files are included in the same order. This used the be the reason why C/C++ compilers were "slow", they spent much of their times, parsing files that predominantly never change.

So to improve compiling time, someone thought it would be advantageous to compile some of the headers into a binary file, so that when the compiler compiles multiple .cpp files, it only has those headers once. The next .cpp files that are compiled will use the binary file and thus eliminate the time needed to parse those headers multiple times.

But this brought out another problem. How does the compiler know which header files to precompile? One way is that almost all .cpp files have #include statements at the top of the file, start from the top until a known entity says stop, which is what #pragma hdrstop does or until the end of the #includes stop.

Another possible solution (the one that is by default for VC wizard applications) is to indictate that one header file is to be precompiled. This is the stdafx.h file. Anything inside of stdafx.h file is to be precompiled. The only other restriction is that every .cpp file in the project must include stdafx.h, typically at the top. Note that this requirement is only the default behavior. If your source file does not include stdafx.h, you have two choices: 1. include it, this is the most obvious choice, but you have indicated that you don't want this one. So use #2. don't use precompiled header for this source file. To do this, switch to the files pane in the project workspace window. Go to the source section, select your .cpp file. Hit the menu selection Project | Settings. In the dialog, change the "Settings For" to All Configurations. The right side should already be set to C/C++. Change the category to Precompiled headers. The choice should be Use precompiled header file (.pch), change it to Not using precompiled headers.

Rebuild, and it should fix your problem.
0
mikeblasCommented:
Thui is pretty much right on.

The one extra thing I'd stress is that, when you use a precompiled header, the compiler doesn't pay any attention to anything until the precompiled header reference is satisifed.

It looks, line by line, to see if you're referencing the header you said would be precompiled. If that line has an #include directive, it's checked. If it doesn't, its skiped.  _Completely_; no syntax, no preprocessor directives, no code, no constants.

..B ekiM
0
kentktAuthor Commented:
Mikeblas,

Your help is appreciated but I cannot accept because:

1. You said my Q4 was not sensible but what I asked is the default behaviour of VC, not the compiler. So, you'd better tell me that the default behavour of AppWizard will generate project settings that tell that compiler that stdafx.h is used as the PCH. Maybe my question is not clear, but I cannot make it too clear since I did not quite understand PCH at that moment.

2. In previous messages, you quoted some documentation from VC, which I had read them through already. However, I was still confused so I asked here. Maybe my comment "Rediculous" is ridiculous, but this is my feeling because I cannot find an answer to such a common problem even though I have tried the Help system in so many ways.

3. Your answers is not satisfying because they are based on the VC documentation. You did not explain the more fundamental concepts behind as thui.

Sorry for that.
0
kentktAuthor Commented:
Thui,

I find your comment very satisfying. Would you lock the question to allow me to award you?

Thanks.

Kent.
0
LucHoltkampCommented:
You're arrogance is ****ing anoying mikeblass, why don't you give a normal answer like thui?
Yes, I do know what pch are, and yes it did work nicely in borland, and unfortunatly, I don't have time to find out how everything works, perhaps you didn't notice, but some people actually have work to do, deadlines and so on. That's why I'm here, not to ventilate my superiority (like you mike) but to get my work done as quickly as possible, and with sufficient maturity. I don't need you to know that I'm a good OO designer and C++ programmer, the product that we make, and my paycheck every month tell me enough. Why should I Read The ****ing Manual if you can tell me it straight away?
Still, I think it's a strange decision from microsoft, to default to inclusion of a header. Borland is not perfect, but most of their concepts make a lot more sense to me, not only the compiler, but certainly also the class library...
Luc
0
Tommy HuiEngineerCommented:
Thanks.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
linda101698Commented:
Experts Exchange tries to maintain a professional site where people can get solutions to their problems.  We encourage the customers and experts to keep their responses positive. If you disagree with the solutions being suggested, try to do it in a postive way.  A lot of the solutions to problems are a troubleshooting process and ideas from several experts can lead to the solution of difficult to solve problems.

If you have problems, I would appreciate it if you contacted community support directly rather than post at a customer's question.

Linda Gardner
Community Support @ Experts Exchange
cs@experts-exchange.com
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Languages and Standards

From novice to tech pro — start learning today.