vc++6.0中vc 控制台应用程序与win32应用程序 区别

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(1728)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'vc++6.0的使用',
blogAbstract:'&1.创建一个新的 C 语言的工程\r\n&&&& 第一步,启动 Microsoft Visual C++ 6.0\r\n启动 VC 可以通过“开始”菜单,也可以通过桌面快捷方式,或者 Quick Launch 工具栏等方式。\r\n'
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}文章目录[点击显示]
& & 许多初学C语言的同学一般接触的编译工具有几种,要么Turbo C,要么VC6.0(Microsoft Visual C++) ,要么是 Win TC。很少初学者去用VS2010(Visual Studio)这样的大型集成开发环境。这样也不利于初学者去熟悉代码,学着学着就懒了。就拿谭浩强C语言的上机实验这本书,都是在VC6.0下编译的。
& & 但是,VC6.0 在windows 7中并不兼容。网上也有一些教程教各位如何在win7下***VC6,但是过程过于繁琐。
& & 所以今天给大家找了 一个 VC6.0 win 7兼容版本,是绿色版的(exe***过程只是解压)。如果有出现错误,大家请阅读原作者留下的注意事项,该导入注册表的就导入吧!
示例图片:
& & 下载地址:
1、大家在***过程中最好不要更改默认的***路径C:\Program Files\Microsoft Visual Studio,不然可能会造成编译失败。
2、Vista、Win7系统下的***问题:
方法一:***时,出现"这个程序必须运行于Win2000/XP”,点"确定"。接下来,选择"使用推荐的设置重新***",即可正常***。
方法二:在我的电脑中,右键单击下载的***文件,点"属性",选择"兼容性"选项卡,选中"以兼容模式运行这个程序",点"确定",再运行***程序即可。
启动VC时,出现兼容性提示,点“运行程序”即可。
附:VC6.0 编译C语言过程
1、新建Project :在新建窗口中,选择Projects(项目)中的WIN32 Console Application(控制台应用程序),填写右上角的项目名称。
2、选择An empty project(空的工程)。
3、之后再新建文件,选择&C++ Souce File,并输入名字。
4、代码写完后,大家按ctrl+F5进行程序调试,debug,之后就可以看到结果了。
转载请注明: &1510人阅读
Win32&application&是基于WINDOWS平台的32位开发环境开发应用程序,SDK程序。
Win32&Console&application&是基于DOS开发平台开发应用程序,不能使用与图形有关的函数,控制台程序。&
EXE文件本身有区别:在文件头里(PE头)有一个标记表明该文件是Application还是Console
OS在创建对应的进程时,如果是Console,除了载入文件映像并开启进程外(这一点和Application相同),同时创建一个Console对象(就是那个黑黑的窗口)与之关联,而且这种关联是可以编程脱开的.
除此以外,就没什么区别了,在Console程序里调用相应的API也可以创建窗口,对话框什么的。
Win32&Application和Win32&Console&Application都是工作在32位Windows环境的程序。&
其中Win32&Application就是普通的常见的窗口应用程序,当然有的界面做得比较个性化,比如圆形的、不规则形状的……它们都是所谓的GUI(Graphics&User&Interface图形用户接口),我们可以通过鼠标点击来完成控制。&
而Win32&Console&Application(win32控制台应用程序)往往是像MS-DOS窗口(XP中叫命令提示符)的样子出现,我们得用键盘输入各种命令来使用它;或者叫CUI(Character&User&Interface字符用户接口)。&
vc6里Win32&Application和Win32&console&Application的区别&
很多VC初学者可能会常遇到如下链接错误:&
Linking...&/subsystem:windows&
LIBCD.lib(wincrt0.obj)&:&error&LNK2001:&unresolved&external&symbol&_WinMain@16&
Debug/TestWin.exe&:&fatal&error&LNK1120:&1&unresolved&externals&
Error&executing&link.exe.&
解决方法是:将project-settings-link的project&options里的&
/subsystem:windows&
/subsystem:console&
原因:Win32&Application的入口函数为WinMain&
Win32&Console&Application的入口函数是main&
换句话说,如果你编写传统的C程序,必须建立Win32&Console程序,但VC里面默认的是Win32&Application,于是上面提及的链接错误就就经常出现了而Win32&Application和Win32&Console的区别就在于VC里链接参数不同 。
Win32 Console Application只能运行命令行程序
Win32 Application是基于消息响应机制的,可以运行图形化的C++程序
对于这两种程序VC里面有专门的设置对应:
打开project-setting,c/c++选项卡中Category选General,下面就会有Preprocessor definetions一项,里面有_WINDOWS或者_CONSOLE。然后再看Link选项卡,Category同样选General,在下面的Project Options里就会有/subsystem:windows或者/subsystem:console。
运行Win32 Console Application一定要把这两个地方改成console,不然编译出错。
同理Win32 Application要把两个地方改成windows。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场& VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
&&&&&& 前两讲中鸡啄米为大家讲解了如何创建对话框资源。创建好对话框资源后要做的就是生成对话框类了。鸡啄米再声明下,生成对话框类主要包括新建对话框类、添加控件变量和控件的消息处理函数等。&&&&&& 因为鸡啄米给大家的例程Addition是基于对话框的程序,所以程序自动创建了对话框模板IDD_ADDITION_DIALOG,并自动生成了对话框类CAdditionDlg,它是从CDialogEx类派生的。大家用过 6.0的可能记得,我们定义的对话框类都是从CDialog类派生的,但在中,一般对话框类都是继承自CDialogEx类。&&&&&& 创建对话框类&&&&&& 如果是自己新添加的对话框模板,怎样为它创建对话框类呢?&&&&&& 1.首先鸡啄米就按中说的那样,在Resource View的&Dialog&节点上右键,然后在右键菜单中选择&Insert Dialog&创建一个新的对话框模板,ID就使用默认的IDD_DIALOG1。&&&&&& 2.在中间区域会显示新建的对话框模板,然后选中此对话框模板,点右键,在右键菜单中选择Add Class。&&&&&&& 3.选择&Add Class&后会弹出一个对话框,在对话框中&Class name&下的编辑框中写入自定义的类名就可以了,例如CMyDialog。&&&&&& 4.最后点&Finish&完成。&&&&&& 最终你就可以在Class View中看到新生成的对话框类CMyDialog了,并且在Solution Explorer中有相应的MyDialog.h头文件和MyDialog.cpp源文件生成。CMyDialog类同样派生于CDialogEx类。&&&&&& 注意,一般类名都以C打头,又比如,CTestDlg。&&&&&& 为对话框中的控件添加变量&&&&&& 在上一讲中,包括三个静态文本框,三个编辑框,一个按钮控件。程序自动生成的Cancel按钮保留,作为退出按钮,而OK按钮删除掉了。&&&&&& 静态文本框只是为了说明后面紧跟的编辑框中数据的意义,是被加数、加数还是和,所以它们是不会变的,我们就不为它们添加变量了。按钮控件是用来操作的,这里也不为它们添加变量。编辑框中的数据可能会经常变化,有必要为它们每个控件关联一个变量。&&&&&& 首先为被加数的编辑框IDC_SUMMAND_EDIT添加变量。&&&&&& 1.在编辑框上点右键,在右键菜单中选择&Add Variable&。弹出添加成员变量的向导对话框。&&&&&& 2.我们想为其添加值变量而不是控件变量,所以对话框中&Category&下的组合框中选择Value。&&&&&& 3.&Variable type&下的组合框此时默认选中的是&CString&,CString是字符串类,显然不能进行加法运算。我们可以选择double、float、int等。这里我们选择double,即编辑框关联一个double类型的变量。&&&&&& 4.在&Variable name&中写入自定义的变量名。鸡啄米为其取名m_editSummand。&&&&&& 5.点&Finish&完成。&&&&&& 注意,类的成员变量名一般以m_打头,以标识它是一个成员变量。&&&&&& 参照此方法,再分别为加数的编辑框IDD_ADDEND_EDIT添加double型变量m_editAddend、和的编辑框IDD_SUM_EDIT添加double型变量m_editSum。&&&&&& 对话框类的数据交换和检验&&&&&& 在程序运行界面中,用户往往会改变控件的属性,例如,在编辑框中输入字符串,或者改变组合框的选中项,又或者改变复选框的选中状态等。控件的属性改变后会相应修改控件关联变量的值。这种同步的改变是通过MFC为对话框类自动生成的成员函数DoDataExchange()来实现的,这也叫做对话框的数据交换和检验机制。&&&&&&&我们为三个编辑框添加了变量以后,在AdditionDlg.cpp中CAdditionDlg的DoDataExchange()函数的函数体中多了三条DDX_Text调用语句。下面是函数体代码和鸡啄米添加的注释。
void&CAdditionDlg::DoDataExchange(CDataExchange*&pDX) &&
&&&&CDialogEx::DoDataExchange(pDX); &&
&&&&DDX_Text(pDX,&IDC_SUMMAND_EDIT,&m_editSummand); &&
&&&&DDX_Text(pDX,&IDC_ADDEND_EDIT,&m_editAddend); &&
&&&&DDX_Text(pDX,&IDC_SUM_EDIT,&m_editSum); &&
}&&&&&&&& 鸡啄米再以Addition程序为例简单说下数据交换机制。如果我们在程序运行界面中输入被加数,则通过CAddition的DoDataExchange()函数可以将输入的值保存到m_editSummand变量中,反之如果程序运行中修改了变量m_editSummand的值,则通过CAddition的DoDataExchange()函数也可以将新的变量值显示到被加数的编辑框中。&&&&&& 但是这种数据交换机制中,DoDataExchange()并不是被自动调用的,而是需要我们在程序中调用CDialogEx::UpdateData()函数,由UpdateData()函数再去自动调用DoDataExchange()的。&&&&&& CDialogEx::UpdateData()函数的原型为:&&&&&& BOOL UpdateData(BOOL bSaveAndValidate = TRUE);&&&&&& 参数:bSaveAndValidate用于指示数据传输的方向,TRUE表示从控件传给变量,FALSE表示从变量传给控件。默认值是TRUE,即从控件传给变量。&&&&&& 返回值:CDialogEx::UpdateData()函数的返回值表示操作是否成功,成功则返回TRUE,否则返回FALSE。&&&&&& 在下一讲中鸡啄米将具体演示CDialogEx::UpdateData()函数如何使用。&&&&&& 鸡啄米本节主要讲的是新建对话框类和添加控件变量,控件的消息处理函数将在下一讲详细介绍。依然欢迎大家常回鸡啄米博客学习和讨论。&
除非特别注明,文章均为原创
转载请标明本文地址:
作者:鸡啄米
&&( 22:15:37)&&( 22:36:0)&&( 23:17:45)&&( 19:46:26)&&( 22:7:57)&&( 23:32:16)&&( 1:53:2)&&( 23:22:54)&&( 22:18:8)&&( 22:47:28)
MFC没学了,直接用C#鸡啄米 于
10:58:03 回复嗯,现在用C#的也很多。
你的文章对我帮助很大,如果我想做两个对话框,一个是对话框里全是参数,自己输入,另一个全是运算结果,请问如何实现?我是新手,希望能详细点,非常感谢!鸡啄米 于
21:19:10 回复比较简单的是通过全局变量来保存第一个对话框里的参数,第二个对话框计算并显示结果InitWaiter 于
19:32:28 回复建议用结构体实现,需要设置的参数都放置在结构体中,虽然该结构体也是全局的,不过可控性更强,有点类似于命名空间,主要还是模块化的思想。
你好!你的文章对我太有用了,非常感谢您!
鸡啄米你好!我在看这一讲时遇到了困难,在给控件添加变量时,右键之后单击add variable可是我的vs2010却没有任何反应,也就是说不能添加变量,请问你知道这是什么原因吗?鸡啄米 于
11:28:15 回复首先确定是否生成了对话框类,如果有了对话框类还是不行,就关闭工程,删除sdf等中间文件,再打开试试。实在不行就手动添加吧。jiayaosmile 于
12:21:57 回复我也遇到了5楼的问题,按照楼主的方法,没有用呀。鸡啄米 于
17:04:31 回复可以再试试class wizard,应该可以jiayaosmile 于
17:01:55 回复是我自己的问题了,没有添加类就直接添加变量,就没反应了。谢谢鸡啄米,你的博客很好,很适合我这种初学者。plcwoaini 于
21:14:06 回复enum=IDD_xx这个对话框的IDD不同时,双击对话框,不能弹出类向导.可以手动修改.
这个文章很好,呵呵,虽然我没有看任何内容。但是它已经帮我解决了问题。其实MFC默认生成的对话框其实是不关联任何类的,所以你就无法添加变量,因为VS不知道你添加的变量到底应该放到哪个类之中!如果我们自己派生一个对话框类的话,那么是可以添加的,原因是我们此时已经派生了类,并且关联了资源。
读过你的文章,觉得写的很好,简单明了,这里支持你一下。希望你能继续写下去。
我又来了 问的是控件如何关联变量问题 就是我定义了一个MFC的类 就比如把class CEditLimit : public CEdit
比如我想关联一个我的edit控件的Control的变量 可为什么没有我的CEditLimit呐
是所有的vs都是这呐 还是我的vs是这啊 都是自己手动的更改嘛 刚从vc6转过来 好多的都不熟悉 还希望版主都赐教啊 鸡啄米 于
22:43:21 回复自定义的类是不会显示到那个列表里的,你可以先关联一个CEdit类型的控件变量,然后到头文件中手动修改为CEditLimit类型。
谢谢啊 还有就是 每次更改以后都得是生成解决方案 在调试运行嘛我以前每次用vc6.0都是直接Ctrl+F5 就是问下 在vs中怎么办啊 每次修改以后不能直接点运行 是嘛 很困惑 对与vs的一些基本操作 还请博主都体谅
你好,我在看这章的时候也出现了5楼的问题,在AdditionDlg.cpp中CAdditionDlg的DoDataExchange()函数的函数体中没有变化,只有一条CDialogEx::DoDataExchange(pDX);语句。在AdditionDlg.h中有新加的变量名。只能手动添加,有什么其他方法吗?鸡啄米 于
20:04:40 回复呵呵,真是什么问题都有啊。如果你的添加方法正确的话,只加一半还真是没有道理的。这种情况下,只能手动加了
谢谢啊,学习了,可是第六讲的时候我评论中提出了一个小问题,后来咋找不到回复及我的原帖了,记得好像成功了的,觉得这边好多资源供学习,还有交流群么?
之前在公司用的VC6.0,自己电脑刚装上了VS2012,想业余时间自己学学VS,感谢你的文章,给了我不少的帮助。祝你工作顺利,身体健康!鸡啄米 于
23:17:54 回复很高兴能帮到你。同祝工作顺利!
类似于CDialogEx类。我看到它是CMyDialog的一个基类那么这样的的类又是什么样的含义呢!!博主你真的太好了!非常受用!
CDialogEx::UpdateData()函数是在哪里呢?本文来源于鸡啄米 / , 原文地址:/software/153.html
你好,我在这章照做的时候遇见了问题,就是在Add Class的时候填写Class name后点击完成,就弹出不是正当的.....***件鸡啄米 于
22:45:30 回复sorry,这种问题从没遇到过未来记忆 于
10:16:21 回复谢谢你了。我知道了,是我在***的时候吧一个开发工具给去掉了,我现在解决了。
非常好的博客。论述简单明了,针对性强!
非常有用的文章。感谢你的奉献!
你好!读了你的文章感觉很好,谢谢!现在有个问题请教:我用MFC做了一个界面,上面添加了2个对话框,在对话框1上有滑拉条、文本框以及spin控件,想实现当这些控件的值变化时能实时地反应到对话框2中。我不想在每个控件上都添加处理函数,能在对话框中找到一个共同的函数,处理对话框1中所有的变化?谢谢!
鸡啄米老师,你好!我想实现直接鼠标双击就可以进行文字输入,并把文字直接显示在屏幕上,按回车回到正常状态。不想用弹出对话框,接收输入文字那种,那种太麻烦了。请教下先生这个该真么实现呢?我看好多软件比如world,金山文字都这么搞的,想知道下他们是怎么弄的?谢谢
给控件添加成员变量:1.在Dialog对话框上添加一个Edit控件。2.选中Edit控件,鼠标右键点击,选择“类向导”(我用的汉化版,就不打英文了)3.在“类向导MFC”对话框中,中间部分有一个“成员变量”选项卡。点击。在下部会显示“成员变量”列表框。4.根据你自己设定的Edit的ID,在列表中选择。5.点击右侧的“添加变量”按钮。打开“添加成员变量”对话框。默认已经有“m_”。6.“类别”“变量类型”就不要改了。然后确定。7.DoDataExchange函数中会自动添加。然后直接使用关联的成员变量就行。其他也是一样。鸡啄米 于
23:19:38 回复很高兴有如此热心的网友,欢迎常来Caramel 于
9:22:04 回复我试了下这种方法,我的还是不能关联呢。。。好奇怪。。。
嗯,写的很简单明了。支持一下鸡啄米 于
21:36:56 回复谢谢支持,常来看看啊
继续学习,争取先做一个加法的简单MFC程序
谢谢楼主哦 嘿嘿
我都很认真的看啦鸡啄米 于
22:43:04 回复不用谢,常来逛逛啊
楼主,我刚接触这些,不过看你的这个觉得真心不错,我会很认真的看了,支持你哦鸡啄米 于
16:19:14 回复加油,常来交流啊
我添加对话框类的时候,右键单击 add class没反应,用class wizard 时报错?鸡啄米请问我的问题出在哪?还是软件***的有问题
博主这样具体形式的例子比起其他长篇大论从WINDOWS原理开始介绍的MFC教程要好很多,前段时间我看了《深入浅出MFC》,书前半部分全是理论,我看完了还是编不出一个最基本的程序,那样的书可能不适合入门。感谢您的文章。鸡啄米 于
16:19:06 回复个人认为,那种书适合作工具书
很喜欢你把问题分成一部分一部分来讲,很容易理解接受~
我一直很困惑,对话框程序文档程序有啥区别么?还有 win32 程序
这三个项目模版都是干啥用的?应用场景是啥?能给讲讲不?
鸡啄米,你好,我觉得你这句话应该是写错了:“参数:bSaveAndValidate用于指示数据传输的方向,TRUE表示从控件传给变量,FALSE表示从变量传给数据。”最后的应该是“FALSE表示从变量传给控件。”你的文章写得简单明了,非常适合入门。在此感谢你。鸡啄米 于
16:34:27 回复已经修正,谢谢提醒。
我出现了和10楼相同的问题,即添加变量之后CAdditionDlg::DoDataExchange中没有自动增加DDX_Text函数。我发现了问题所在原因,按照教程,这个窗口是在一个单窗口的MFC工程中自己新建的窗口。它的变量是无法自动关联到AdditioniDlg.cpp中的。如果对项目本来自动创建的窗口进行操作,就可以自动建立函数了。
vs2010能不能像vc 6.0
一样将一个对话资源与一个已有的类关联,比如说我从CFileDialog 派生一个类CCustomDialog ,如何将这个类和一个对话框资源关联?
你好,我的VS2010里面的I没有IDC_SUMMAND_EDIT和那两个,手动修改后在addiondlg.cpp里错误ID没定义.怎么办?南风 于
21:30:35 回复我的也一样南风 于
21:31:33 回复怎么解决?
跪谢,太厉害了~
作者您好 我右键按完添加变量后 没有任何反应 怎么办
一开始DoDataExchange() 里面没有自动生成。。。后来就手动添加了。 看了评论应该是有问题的。 然后参考了 秦风 的方法
。解决了。。这下问题就来了, 我按照楼主的方法为什么出错了?最后我找到问题了: 添加变量的时候,太疏忽了,类别没有切换到value。所以关联不上拉,不能自动生成代码。
大家是不是和我犯的错是一样的呢。 呵呵。。。本人新手,鸡啄米老师给力哈!~~~
请问QQ交流群号是多少?
请问一下,添加了控件变量之后忘记了自己添加的变量名了,怎么可以方便的查看米 于
10:31:15 回复一个就是在DoDataExchange里看,一个就是在添加变量的对话框内,会显示之前添加的变量的,为灰色。我也是新手、
您好,我按你的说明写了以后,就是提示:m_editsum,未声明的标识符。另外,请问CDialogEx::UpdateData()这个函数写在哪个位置?
求问不小心修改了主dilogID之后,修改回来依旧无法右键添加变量的解决方法QAQ。
你好,我用vs2013按照你所说的方法去操作(加法计数器),但是一直没有成功。错误列表如下:IntelliSense:
无法用 &double& 类型的值初始化 &CWnd && 类型的引用(非常量限定)error C2664: “void DDX_Control(CDataExchange *,int,CWnd &)”: 无法将参数 3 从“double”转换为“CWnd &”请问应该如何解决?
新手求教:如果控件的变量信息填错了,怎么修改,比如我把其中“和”的变量类型填错了,怎么修改,在点击添加变量的时候,原有的修改项都灰了,不能改。
请问我按照这两节的课程完成Addition对话框的创建,控件添加,变量添加。为什么在对话框类的头文件中没有实现函数的声明,在实现类的文件中也没有消息映射,在void CAdditionDlg::DoDataExchange(CDataExchange* pDX) 函数中也没有控件和变量的数据交换自动生成。请问是不是有什么内容没有设置好呀?
为什么运行之后结果是最开始Addition的窗口而不是我后来自己插入的那个窗口呢
完全随机文章控制台应用程序下使用GDI在内存中画图
控制台应用程序下使用GDI在内存中画图
1&&&&& 背景
以前写MFC应用程序的时候,就接触到GDI了。只不过那个时候,Visual Studio已经帮你生成了MFC应用的基本框架,在Visual Studio生成的View文件里,存在一个方法::OnDraw(CDC* /*pDC*/),Visual Studio会添加注释&// TODO: 在此处为本机数据添加绘制代码&,即是说,请在此处调用CDC进行绘制操作。CDC的创建和初始化MFC都帮你完成了,你只需要添加一些个性化代码即可,当然,这对于一个MFC应用来说,当然够了,但是如果你想写一个不使用MFC的应用,我该怎么获得CDC呢?
很多时候,我们并不需要将绘制的图像显示在窗口,只需要将图像绘制在内存中,然后将内存中的图像保存成图片文件。说到内存绘制,也许有人会说,我直接创建一块内存像素数据,然后计算每个图形的像素结构,填充内存像素数据不就可以了么,没有必要使用GDI呀,对于大部分几何图像来说,这么做完全没问题,但是如果你想绘制字符的时候,这么做就很困难了,因为你很难去计算一个字符的像素结构,所以当你需要绘制字符的时候,你还是得使用GDI。
接下来,我将介绍:(1)如何在控制台应用程序下使用GDI在内存中画图;(2)将内存中的图像存储为图片。
2&&&&& 使用GDI在内存中画图
GDI是Windows API,因此只要是Win32程序(包括Win32应用程序和Win32控制台程序),都可以使用GDI。为了简单起见,如果你想运行本文介绍的代码,新建一个空的Win32控制台程序即可。我觉得在代码中加注释比在这描述更加明了,那么让我们看看代码吧:
#include &Windows.h&&&
#include &tchar.h&&&
#include &stdio.h&&&
&* 将HBITMAP保存为BMP图片,实现细节见第三节
static void hbitmapToImage(HDC hdc, HBITMAP hbm);&
int main(int argc, char *argv[])&
&&& // 创建绘制环境&&
&&& HDC memDC = CreateCompatibleDC(NULL);&
&&& // 创建画布&&
&&& HBITMAP hbm = CreateBitmap(100, 100, 1, 32, NULL);&
&&& // 创建一个字体,其中40是字体大小,参数可以根据自己需求调整&&
&&& HFONT hfont = CreateFont(40, 0, 0, 0, FW_THIN, false, false, false,&&
&&&&&&& DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,&&
&&&&&&& DEFAULT_QUALITY, FF_MODERN, _T(&宋体&));&
&&& // 选择画布和字体,你可以保存之前的画布和字体用于恢复,为了篇幅起见,在此就不这样做了&&
&&& SelectObject(memDC, hbm);&
&&& SelectObject(memDC, hfont);&
&&& // 开始绘制操作&&
&&& RECT imgRect = {0, 0, 100, 100};// 设置为画布的宽高&&
&&& SIZE fontPixS&&&&&&&&&&&&&& // 字符的像素大小,对于一种字体来说,其字符的高是一致的,但是宽基本不同&&
&&& // 将背景填充为黑色&&
&&& FillRect(memDC, &imgRect, (HBRUSH)GetStockObject(BLACK_BRUSH));&
&&& // 得到字符串的像素宽高,可以为任意字符串&&
&&& GetTextExtentPoint32(memDC, _T(&我&), 1, &fontPixSize);&
&&& SetTextColor(memDC, RGB(255, 255, 255));&&& // 设置文本颜色&&
&&& SetBkMode(memDC, TRANSPARENT);&&&&&&&&&&&&& // 设置背景模式&&
&&& // 计算绘制起始位置,使字符在画布的中间;当然你也可以添加更多的绘制操作,如PolyDraw,LineTo等&&
&&& TextOut(memDC, (100 - fontPixSize.cx) / 2, (100 - fontPixSize.cy) / 2, _T(&我&), 1);&
&&& // 将HBITMAP保存为BMP图片&&
&&& hbitmapToImage(memDC, hbm);&
&&& // 释放资源&&
&&& DeleteObject((HGDIOBJ)hfont);&
&&& DeleteObject((HGDIOBJ)hbm);&
&&& DeleteDC(memDC);&
&&& return 0;&
#include &Windows.h&
#include &tchar.h&
#include &stdio.h&
&* 将HBITMAP保存为BMP图片,实现细节见第三节
static void hbitmapToImage(HDC hdc, HBITMAP hbm);
int main(int argc, char *argv[])
&// 创建绘制环境
&HDC memDC = CreateCompatibleDC(NULL);
&// 创建画布
&HBITMAP hbm = CreateBitmap(100, 100, 1, 32, NULL);
&// 创建一个字体,其中40是字体大小,参数可以根据自己需求调整
&HFONT hfont = CreateFont(40, 0, 0, 0, FW_THIN, false, false, false,
&&DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
&&DEFAULT_QUALITY, FF_MODERN, _T(&宋体&));
&// 选择画布和字体,你可以保存之前的画布和字体用于恢复,为了篇幅起见,在此就不这样做了
&SelectObject(memDC, hbm);
&SelectObject(memDC, hfont);
&// 开始绘制操作
&RECT imgRect = {0, 0, 100, 100};// 设置为画布的宽高
&SIZE fontPixS&&&&// 字符的像素大小,对于一种字体来说,其字符的高是一致的,但是宽基本不同
&// 将背景填充为黑色
&FillRect(memDC, &imgRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
&// 得到字符串的像素宽高,可以为任意字符串
&GetTextExtentPoint32(memDC, _T(&我&), 1, &fontPixSize);
&SetTextColor(memDC, RGB(255, 255, 255));&// 设置文本颜色
&SetBkMode(memDC, TRANSPARENT);&&&&// 设置背景模式
&// 计算绘制起始位置,使字符在画布的中间;当然你也可以添加更多的绘制操作,如PolyDraw,LineTo等
&TextOut(memDC, (100 - fontPixSize.cx) / 2, (100 - fontPixSize.cy) / 2, _T(&我&), 1);
&// 将HBITMAP保存为BMP图片
&hbitmapToImage(memDC, hbm);
&// 释放资源
&DeleteObject((HGDIOBJ)hfont);
&DeleteObject((HGDIOBJ)hbm);
&DeleteDC(memDC);
&return 0;
3&&&&& 将HBITMAP保存为BMP图片
第2节描述了如何使用GDI在内存中画图,本节介绍如何将HBITMAP保存为BMP图片。代码如下:
&* 将HBITMAP保存为BMP图片
void hbitmapToImage(HDC hdc, HBITMAP hbm)&
&&& // 得到hbm中每个像素所占的位数&&
&&& int bmPixBitCount = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);&
&&& int wBitCount = 0;&
&&& if(bmPixBitCount &=& 1)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& wBitCount = 1;&&&&&&&&&&&&
&&& else if(bmPixBitCount &=& 4)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& wBitCount = 4;&&&&&&&&&&&&
&&& else if(bmPixBitCount &=& 8)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& wBitCount = 8;&&&&&&&&&&&&
&&& else&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& wBitCount = 24;&
&&& //////////////////////////////////////////////////////////////////////////&&
&&& BITMAP&
&&& GetObject(hbm, sizeof(bm), &bm);&
&&& int bmRowCount = ((bm.bmWidth * wBitCount + 31) / 32) * 4; // 一行所占的字节数,BMP像素数据按四字节对齐&&
&&& int bmByteCount =& bmRowCount * bm.bmH // 像素数据的大小&&
&&& char *buf = new char[bmByteCount];&
&&& // 位图信息头结构,定义参考MSDN&&
&&& BITMAPINFOHEADER&
&&& bi.biSize= sizeof(BITMAPINFOHEADER);&&&&&&&&
&&& bi.biWidth = bm.bmW&&&&&&&&
&&& bi.biHeight =& bm.bmH&&&&&&&&
&&& bi.biPlanes =& 1;&&&&&&&&
&&& bi.biBitCount = wBitC&&&&&&&&
&&& bi.biCompression= BI_RGB;&&&&&&&&
&&& bi.biSizeImage=0;&&&&&&&&
&&& bi.biXPelsPerMeter = 0;&&&&&&&&
&&& bi.biYPelsPerMeter = 0;&&&&&&&&
&&& bi.biClrImportant = 0;&&&&&&&&
&&& bi.biClrUsed =& 0;&
&&& GetDIBits(hdc, hbm, 0, bm.bmHeight, buf, (BITMAPINFO*)(&bi), DIB_RGB_COLORS); // 得到像素值,保存在buf中&&
&&& // 位图文件头结构,定义参考MSDN&&
&&& BITMAPFILEHEADER&
&&& bf.bfType = 0x4D42; // BM&&
&&& bf.bfSize = bmByteC&
&&& bf.bfReserved1 = 0;&
&&& bf.bfReserved2 = 0;&
&&& bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);&
&&& // 写入文件&&
&&& FILE *bmFile = fopen(&demo.bmp&, &w+b&);&
&&& if (bmFile)&
&&&&&&& fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, bmFile);&& // 写入位图文件头&&
&&&&&&& fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, bmFile);&& // 写入位图信息头&&
&&&&&&& fwrite(buf, sizeof(char), bmByteCount, bmFile);&&&& // 写入像素数据&&
&&&&&&& fclose(bmFile);&
&&& delete []&
&* 将HBITMAP保存为BMP图片
void hbitmapToImage(HDC hdc, HBITMAP hbm)
&// 得到hbm中每个像素所占的位数
&int bmPixBitCount = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
&int wBitCount = 0;
&if(bmPixBitCount &=& 1)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&wBitCount = 1;&&&&&&&&&&
&else if(bmPixBitCount &=& 4)&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&wBitCount = 4;&&&&&&&&&&
&else if(bmPixBitCount &=& 8)&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&wBitCount = 8;&&&&&&&&&&
&else&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&wBitCount = 24;
&//////////////////////////////////////////////////////////////////////////
&GetObject(hbm, sizeof(bm), &bm);
&int bmRowCount = ((bm.bmWidth * wBitCount + 31) / 32) * 4; // 一行所占的字节数,BMP像素数据按四字节对齐
&int bmByteCount =& bmRowCount * bm.bmH // 像素数据的大小
&char *buf = new char[bmByteCount];
&// 位图信息头结构,定义参考MSDN
&BITMAPINFOHEADER
&bi.biSize= sizeof(BITMAPINFOHEADER);&&&&&&
&bi.biWidth = bm.bmW&&&&&&
&bi.biHeight =& bm.bmH&&&&&&
&bi.biPlanes =& 1;&&&&&&
&bi.biBitCount = wBitC&&&&&&
&bi.biCompression= BI_RGB;&&&&&&
&bi.biSizeImage=0;&&&&&&
&bi.biXPelsPerMeter = 0;&&&&&&
&bi.biYPelsPerMeter = 0;&&&&&&
&bi.biClrImportant = 0;&&&&&&
&bi.biClrUsed =& 0;
&GetDIBits(hdc, hbm, 0, bm.bmHeight, buf, (BITMAPINFO*)(&bi), DIB_RGB_COLORS); // 得到像素值,保存在buf中
&// 位图文件头结构,定义参考MSDN
&BITMAPFILEHEADER
&bf.bfType = 0x4D42;&// BM
&bf.bfSize = bmByteC
&bf.bfReserved1 = 0;
&bf.bfReserved2 = 0;
&bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
&// 写入文件
&FILE *bmFile = fopen(&demo.bmp&, &w+b&);
&if (bmFile)
&&fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, bmFile);&// 写入位图文件头
&&fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, bmFile);&// 写入位图信息头
&&fwrite(buf, sizeof(char), bmByteCount, bmFile);&&// 写入像素数据
&&fclose(bmFile);
&delete []
程序运行结果如图1所示:
图1:程序运行结果
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

参考资料

 

随机推荐