非MFC工程中使用MFC库-阿里云开发者社区

开发者社区> double2li> 正文

非MFC工程中使用MFC库

简介: 目录(?)[-] 需求说明 常见问题 问题分析 参考解决方法 我的解决方案 Stdafxh的原理     需求说明 C++工程的类型有很多,从VS(或VC)可以看到常见的有:Win32 Console Application、MFC Application、Win32 Project等。
+关注继续查看
 

 

需求说明

C++工程的类型有很多,从VS(或VC)可以看到常见的有:Win32 Console Application、MFC Application、Win32 Project等。在创建MFC工程时,通过IDE的向导会自动帮我们创建相应的类文件和包含必需的头文件,但有时候我们需要在非MFC工程中包含MFC的库。至于为什么会有这个需要,为何不在一开始就创建MFC工程呢?可能有两种原因:1.在MFC工程会产生很多向导生成的代码以及资源文件,如基于单文档的工程会有View,Doc等类,很多时候我们并不需要这些东西,只需要一个空工程就可以了。2.使用第三方框架创建的工程,我们很难更改它的工程属性(如用Firebreath开发浏览器插件,通过脚本文件firebreath会自动帮我们生成VS下的工程)。

 

常见问题

在非MFC工程中使用MFC的库就需要包含相应的头文件,经常会遇到下面这个问题:

1fatal error C1189: #error :  Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

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

 

 

问题分析

对于第1个问题,很简单:

选中工程名右键属性(Project),在Properties\Configuration Properties\General\Use of MFC中选择Use MFC in a Shared DLL 

出现上面第2个问题主要是因为包含头文件的顺序不对。为什么包含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。

 

参考解决方法

解决这个问题的总体思路是:把#include <afxwin.h>的包含语句把到最前面。

sunshine1314 的博文《MFC工程使用MFC库时的问题及解决办法》给出了一序列的解决方案,大家可能参考一下,也许能解决你们的问题。但我当时通过这一系列方法还是没能解决我的问题。

 

我的解决方案

我的问题是:用Firebreath开发浏览器插件,通过fbgen.py和prep2010.cmd脚本帮我们生成了基于VS2010的工程(这个工程中没有stdaf.h),我们要在这个工程中获得MFC中的HDC以及使用MessageBox,于是就碰到了上面提到的问题。

解决方案:

手动添加stdafx.h和stdafx.cpp文件使用预编译机制,在stdafx.h的最前面包含<afxwin.h>。于是问题就变成了stdafx.h的原理和手动添加stdafx.h文件及相应配置。下面我们以Win32 Console Application工程的TextProject为例,演示一下这过程。

1.在VS2010中创建Win32 Console Application工程的TextProject,创建向导会自动生成的stdafx.h和stdafx.cpp,省去了手动添加的过程。如果你的工程没有这两个文件可以手动创建。

2.stdafx.h和stdafx.cpp这两个文件已创建并添加到工程,下面讲讲相关的配制。

2.1选中工程名,右键属性(Properties),在Precompiled Header/Precompiled Header中选择Use(/Yu),Precompiled Header File中填stdafx.h。设置工程编译时使用预编译头文件stdafx.h(在VS中文件名的大小写不敏感,即StdAfx.h和stdafx.h是等价的)。

 

 

2.2选中stdafx.cpp文件,右键属性(Properties),在Precompiled Header/Precompiled Header中选择Create(/Yc), Precompiled Header File中填stdafx.h。这样设置的作用是:每次编译stdafx.cpp文件时创建.pch文件(扩展名pch表示预编译头文件 )。

 

 

3.在stdafx.h的开发包含<afxwin.h>文件:

#include <afxwin.h>

4.这时在我们的main函数中写入下面这句话,就可以弹出一个消息框:

AfxMessageBox(L"非MFC工程使用MFC库", MB_OK, 0 );

Stdafx.h的原理

关于stdafx.h的原理请看下一篇文章《预编译头文件(stdafx.h)的原理》。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
SonicUI在MFC中的使用
SonicUI是一个GUI引擎,提供了一些简单的UI组件实现高效率的UI效果,例如:自绘按钮、异形窗体、动画、超链接和图像操作方法。此项目作者开源到CodeProject,地址为:http://www.codeproject.com/KB/GDI/SonicUI.aspx。
1004 0
在MFC中使用OTL库连接数据库
 http://hyhvi.iteye.com/blog/1549639 在Win32控制台程序下,要使用OTL库,只需在程序加入OTL头文件,并写上以下两句代码即可(ODBC方式):     #define OTL_ODBC      #include "otlv4.
859 0
C++MFC编程笔记day06 MFC向导、MFC绘图类使用
 MFC绘图    MFC绘图类包括绘图设备类和绘图对象类    1 绘图设备类      CDC类-父类是CObject,封装的是一般的绘图设备,例如:显示器,            打印机等。
1066 0
MFC画刷类CBrush使用实例 .
画刷类CBrush利用画笔可以画图形的边框,而用画刷就可以在图形内着色。大多数的GDI绘图函数既使用画笔又使用画刷,它们用画笔绘制各种图形的周边,而用画刷填充图形,因而可以用一种颜色和风格去设置画笔,而用另一种颜色和风格去设定画刷,通过一次函数调用就可以绘制出形状复杂的图形。
1062 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
9241 0
网页魔法菜单(使用说明)
地址: http://hi.baidu.com/huxing042/blog/item/ef2d62f77691d524720eecbd.html
574 0
VC/MFC ListCtrl 控件功能使用汇总(转)
以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn -------------------------------------------------------------------------------- 1.
1206 0
mfc在控制多显示器的使用方法
一、取得显示器的个数 GetSystemMetrics(SM_CMONITORS); 二、根据窗口句柄、矩形区域、点取得显示器的句柄 MonitorFromRect( lprc, MONITOR_DEFAULTTONULL ) MonitorFromPoint( pt, MONITOR_DE...
962 0
在MFC中使用OTL库连接数据库
 http://hyhvi.iteye.com/blog/1549639 在Win32控制台程序下,要使用OTL库,只需在程序加入OTL头文件,并写上以下两句代码即可(ODBC方式):     #define OTL_ODBC      #include "otlv4.
892 0
+关注
double2li
一个在IT行业摸爬滚打的老司机
2870
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载