MFC工程去掉#include <windows.h>

本文探讨了在MFC项目中因重复包含windows.h而导致的编译错误问题,并提供了详细的解决方案,包括调整包含顺序及工程设置等。

 

【原因分析篇章】

如果在MFC工程中#include   <windows.h>,那么会有以下编译错误(因为afxwin.h文件中包含了afx.h,afx.h文件中包含了afxver_.h,afxver_.h中包含了afxv_w32.h,而afxv_w32.h中包含了windows.h,请看以下分析):

  compile   error:  
  c:\program   files\microsoft   visual   studio\vc98\mfc\include\afxv_w32.h(14)   :  
  fatal   error   C1189:   #error   :     WINDOWS.H   already   included.     MFC   apps   must   not   #include   <windows.h>  
           
  如果编译器在编译afxv_w32.h文件之前编译了windows.h文件,编译器会报上面的错误,因为在afxv_w32.h文件中有下面的一句预编译报警:  
  #ifdef   _WINDOWS_  
  #error   WINDOWS.H   already   included.     MFC   apps   must   not   #include   <windows.h>  
  #endif  
   
  问题在于为什么afxv_w32.h中要有这么一句预编译处理。看了afxv_w32.h和windows.h文件就有点明白了。  
  在afxv_w32.h中有下面的预编译语句:  
  ...   ...  
  #undef   NOLOGERROR  
  #undef   NOPROFILER  
  #undef   NOMEMMGR  
  #undef   NOLFILEIO  
  #undef   NOOPENFILE  
  #undef   NORESOURCE  
  #undef   NOATOM  
  ...   ...  
  在afxv_w32.h中还有一句:  
  #include   "windows.h"  
   
  而在windows.h文件中有下面的预编译语句:  
  ...   ...  
  #define   NOATOM  
  #define   NOGDI  
  #define   NOGDICAPMASKS  
  #define   NOMETAFILE  
  #define   NOMINMAX  
  #define   NOMSG  
  #define   NOOPENFILE  
  ...   ...  
   
  注意到在windows.h的开头有防止windows.h被重复编译的预编译开关:  
  #ifndef   _WINDOWS_  
  #define   _WINDOWS_  
   
  这样问题就明白了,虽然我不知道微软为什么要这么做,但是我知道如果在afxv_w32.h没有那句预编译报警,那么如果在编译afxv_w32.h之前  
  编译了windows.h,那么在windows.h中#define的NOATOM等宏就会被#undef掉,可能会导致相应的错误发生。  
   
  猜想原因可能如上所述,我的解决方法是,将包含有#include   “windows.h"的头文件放在所有包含的头文件的最后面,这样使得对afxv_w32文件  
  的编译处理发生在先,这样,由于在afxv_w32.h中已经包含了windows.h,那么宏_WINDOWS_将被定义,后继的#include   "windows.h"语句将形同虚设,  
  上面的编译报警也不会发生了。我觉得这种处理要比将所有的#include   "windows.h”语句删掉要好一点。  
   
  一句话,编译器必须在编译windows.h之前编译afxv_w32.h,因为我不是十分清除什么时候afxv_w32.h会被编译,所以我将可能包含有#include   "windows.h"的头文件放在其他头文件之后#include。

 

---------------------------------------------------------------------------------------------

【处理篇】

 

一、问题由来

vc6vc71的工程向导中都包含非MFC的工程,诸如win32 console project, win32 static library。非MFC工程创建时是不支持MFC特性的,然后我们在处理实际问题时有时会用到MFC相关类,如Cstring, Cedit等等,这是很正常的。可能有人会说,为何不在一开始就创建MFC工程呢?问题在于MFC工程会产生很多向导生成代码,如基于单文档的工程会有View,Doc等类,很多时候我们只需要一个空工程就可以了。

 

二、常见问题

MFC工程使用MFC库时最常见的问题就是windows.h重复包含错误,具体如下:

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

 

三、解决办法

MFC工程使用MFC库时,可参考以下步骤

1、工程设置中,将MFC的使用由原来的“使用标准windows库”改为“在共享DLL中使用MFC”(VC71

如果是英文版,相关选项是:

Microsoft Foundation Classes: Use MFC in a shared dll, no using MFCVC6

NOTE:因为我用的是中文版的vc71,英文版的vc6.

2、头文件包含

不同的MFC类需包含的头文件是不一样的。

常用的类,如Cstring, Cedit 等,包含afxwin.h就可以了

如果不清楚包含什么头文件的话,可以同msdn进行查询,msdn中,对于MFC类的介绍中,都会给出相应的header file requirement.

3、#include 语句一定要写在首行

这一点很重要,通常出现前面讲到的windows.h重复包含错误,都是因为#include 语句没有写在首行。

另外还要注意的是,如果#include语句是在一个头文件里,那么对应头文件的包含也要写在首行。示例如下:

=============

test.h文件的内容如下:

include <afxwin.h> //保证该语句在首行

test.cpp的文件内容如下:

#include “test.h” //同样也要保证该语句在首行

=============

 

 

 

 

<think>首先,用户的问题是关于解决在MFC应用程序中包含windows.h导致的重复包含错误:"error WINDOWS.H already included. MFC apps must not include windows.h"。我需要基于提供的引用内容来回答。 回顾引用内容: - 引用[1]:解释错误原因是重复包含windows.h,并提到MFC应用不应包含它。 - 引用[2]:同样描述错误。 - 引用[3]:指出问题在于wglext.h的位置在windows.h之前,建议将wglext.h放在windows.h之后或最后。 - 引用[4]:在控制台项目中使用MFC动态库时包含windows.h会导致错误。 - 引用[5]:详细错误日志,显示在编译时出现。 关键点: - 错误是由于windows.h被重复包含。 - MFC应用不应该直接包含windows.h,因为MFC头文件可能已经包含了它。 - 解决方案包括调整头文件的包含顺序,确保windows.h不被多次包含或避免在MFC应用中包含它。 我的回答需要: - 使用中文。 - 结构清晰,逐步解决问题。 - 确保真实可靠。 - 在引用段落末尾添加引用标识。 - 生成相关问题。 - 遵循LaTeX格式:行内数学表达式用$...$,独立公式用$$...$$并单独成段。 回答结构: 1. **解释错误原因**:简要说明为什么会出现这个错误。 2. **提供解决方案**:基于引用,给出具体解决步骤。 3. **预防措施**:如何避免类似错误。 4. **生成相关问题**:在末尾添加相关问题。 步骤: - 引用标识:在引用内容末尾加[^n],如[^1]。 - 数学表达式:如果出现,用$...$,但问题中没有数学内容,所以可能不需要。 解决方案总结: - 避免在MFC应用中直接包含windows.h,因为MFC头文件(如afxwin.h)已经包含了它。 - 如果必须包含,确保顺序正确:例如,将其他头文件如wglext.h放在windows.h之后[^3]。 - 使用预编译头或宏来防止重复包含。 最终回答框架: - 开头:解释错误。 - 步骤1:检查头文件包含顺序。 - 步骤2:移除不必要的包含。 - 步骤3:使用预编译头。 - 结尾:确认解决。 - 相关问题。 生成相关问题: - 基于主题,如MFC编程、头文件管理、编译错误等。 - 例如: 1. 如何防止头文件重复包含? 2. MFC应用中应该包含哪些头文件? 3. 如何处理其他常见编译错误? 确保回答真实可靠:基于提供的引用,不要添加未经验证的信息。</think>### 解决 MFC 应用程序中包含 windows.h 导致的重复包含错误 在 MFC(Microsoft Foundation Classes)应用程序开发中,错误 `#error WINDOWS.H already included. MFC apps must not #include <windows.h>` 是一个常见问题。它通常发生在项目中重复包含 `windows.h` 头文件时,因为 MFC 框架的头文件(如 `afxwin.h`)已经隐式包含了 `windows.h`。如果开发者再显式添加 `#include <windows.h>`,就会引发冲突和编译失败。下面我将一步步解释原因并提供可靠的解决方案,确保您的项目顺利编译。 #### 错误原因分析 - **核心问题**:MFC 应用在编译时,其框架头文件(如 `afxwin.h`)会自动包含 `windows.h`。如果您在代码中手动添加 `#include <windows.h>`,就会导致 `windows.h` 被重复包含。这违反了 MFC 的设计规则,因为 MFC 要求只通过其内部机制处理 Windows API 调用,从而避免资源冲突和编译错误[^1][^4]。 - **常见触发场景**: - 在控制台项目中使用 MFC 动态库时显式包含 `windows.h`[^4]。 - 头文件包含顺序不当,例如将 `wglext.h` 等头文件放在 `windows.h` 之前[^3]。 - 项目设置问题,如未正确使用预编译头文件(precompiled headers)。 #### 解决方案步骤 遵循以下步骤,逐步解决错误。确保在修改后重新编译项目。 1. **移除不必要的 `#include <windows.h>` 语句** 检查您的源代码文件(如 `.cpp` 或 `.h` 文件),找到所有显式包含 `windows.h` 的位置。直接删除这些行,因为 MFC 头文件(如 `afxwin.h`)已经处理了 Windows API 的包含。 - **示例代码修改前**: ```cpp #include <windows.h> // 删除此行 #include <afxwin.h> ``` - **修改后**: ```cpp #include <afxwin.h> // MFC 头文件已包含 windows.h ``` 这样可避免重复包含,是最直接有效的修复方式[^1][^4]。 2. **调整头文件包含顺序** 如果您的代码依赖其他头文件(如 OpenGL 的 `wglext.h`),确保它们被正确排序。将 `windows.h` 或其依赖项放在包含链的末尾。 - **错误示例**:`wglext.h` 在 `windows.h` 之前包含,会导致冲突[^3]。 ```cpp #include <wglext.h> // 错误顺序 #include <windows.h> ``` - **正确示例**:将 `wglext.h` 移到 `windows.h` 之后或最后位置。 ```cpp #include <windows.h> #include <wglext.h> // 正确顺序 ``` 或者,将依赖头文件放在所有 MFC 头文件之后: ```cpp #include <afxwin.h> // 先包含 MFC 头文件 #include <wglext.h> // 再添加其他头文件 ``` 3. **使用预编译头文件(Precompiled Headers)** 如果项目启用了预编译头(如 `stdafx.h`),确保所有头文件包含都通过它管理。这能减少重复包含的风险。 - 在 `stdafx.h` 中添加必要的 MFC 头文件,并避免直接包含 `windows.h`。 ```cpp // stdafx.h 文件内容示例 #include <afxwin.h> // 包含 MFC 核心头文件 #include <afxext.h> // 其他 MFC 扩展 ``` - 在源代码文件中,只包含 `stdafx.h`,而不是单独的头文件。 ```cpp #include "stdafx.h" // 确保这是第一行包含 ``` 4. **检查项目设置** 在 Visual Studio 中,验证项目配置: - 打开项目属性(右键项目 → 属性)。 - 转到 **C/C++** → **Precompiled Headers**,确保设置为 **Use Precompiled Headers**。 - 在 **Advanced** 选项卡中,检查是否有强制包含 `windows.h` 的设置。 完成以上步骤后,重新编译项目。错误应被解决。如果问题仍然存在,请提供更多代码片段,我会帮您进一步诊断。 #### 预防措施 - **避免显式包含 `windows.h`**:在 MFC 应用中,优先使用 MFC 封装的 API,而不是直接调用 Windows API。 - **使用包含保护宏**:在自定义头文件中添加 `#pragma once` 或 `#ifndef/#define` 宏,防止多重包含。 - **定期清理代码**:使用 Visual Studio 的 **Include Dependencies** 工具分析头文件依赖。 #### 相关问题 1. 如何防止头文件在 C++ 项目中重复包含? 2. MFC 应用中应该包含哪些核心头文件来避免编译错误? 3. 在 Visual Studio 中如何处理其他常见的编译错误,如链接器错误或预编译头问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值