vc编程教程
① 用vc++实现usb接口通信编程的一般步骤
我来说下我做过的USB通信,我没有做过DSP跟上位机的通信,我只做过ARM类的STM32跟上位机的数据传递,虽然做过但是也不是很 懂,只是略知一二,我来说说我怎么做的吧,我是这么实现的:
USB是个很复杂的协议,你如果完全搞懂,我估计没有几个月专心钻研是不行的,但是如果只是能实现你的这个功能,我估计不是很复杂。
首先来说说USB通信:
USB通信传输方式分为四种:控制,中断,批量,同步传输四种,这个你可以看看网上资料,然后我用STM32通信,因为数据量不是很大,我用的是中断传输方式,但是DSP数据量应该会比较大,不知道中断传输行不行,但是一般问题不大。
传输方式说完了,再说说USB设备类型,你每次插usb设备到电脑上的时候就会有提示,这是一个什么设备,USB设备类型就是说的这个意思,是鼠标还是键盘还是别的什么的,如果你选用标准的类,你就不用自己写上位机(PC)的驱动程序,但是如果不用标准的类,就是用自定义的类就要自己写上层的设备驱动程序,就是所谓的DDK,WDM,WDF什么的,你没写过这方面的还真有点棘手,但是也不一定要写驱动程序,你可以试试有个类叫HID类,这个类在USB通信的时候用的还挺多的,不过这个类也有缺点,这个地方还要说一点,USB还分低速,全速,高速三种,不太了解DSP,不知道他支持什么模式,但是USB2.0的全速应该至少可以支持的。
USB2.0全速模式HID用中断方式每秒最多可以传输64KB的数据,不知道能不能达到你的要求,但是我估计一般问题不大了,如果你这歀DSP能支持高速模式,每秒用这种方式可以传输高达22MB的数据,这个速度一般问题不大了。
你可以照着我说的思路,去网上搜搜人家写好的程序,肯定有人做过DSP的USB通信,然后你按照自己的要求改一改,主要应该是USB的设备描述符部分要自己修改,然后可能还要根据自己的电路改改配置什么的,上位机软件网上有源代码的多的是,然后自己摸索摸索,我估计你要是编程水平还可以的话,只是摸索USB,一两个星期完全没有问题,祝你好运!
② 如何用vc++2010编写一个c++程序我是win7 32位的系统 写清详细步骤,谢谢。
打开C++2010,进入主界面之后,点击左上角“文件”,点击下拉菜单中的“新建->项目”,然后选择“win32”,在下面的名称输入框输入您的自定义名称,点击“确定”之后直接点击“完成”,然后进入编辑界面,在#include "stdafx.h"语句的下一行,删除原有的代码,输入下面的代码:
#include<iostream>
using namespace std;
void main()
{
cout<<"hello world "<<endl;
}
或者是在在#include "stdafx.h"语句的下一行,输入下面的代码:
#include<iostream>
using namespace std;
在原有的代码,即在return 0;之前输入 cout<<"hello world "<<endl;即可。
其他的你懂得,谢谢~~~
③ 如何学习VC++
VC只是一款软件,就是能使C,C++语言编写的代码在上面运行的IDE。首先你得学好C和C++语法,不知道你有没有C语言基础,没有的话先买本《C++ primer plus》自学,有的话买本《C++primer》学习,都学好了,基础语法就会了。既然你有其他语言功底,应该很快能学好。接着是实际运用,就是vc开发了。那么首推孙鑫的《VC++深入详解》,这是入门级的手把手地教你使用vc的。然后根据自己的情况,可以自己去做几个简单的软件,也可以继续学习有关vc++开发项目的书籍,看看别人是怎么开发的。然后就是自己实际去开发了,其实就是将所学的东西适当地组合运用(例如某个项目要将界面,数据库编程,多线程组合)。
④ vc 6.0 怎么编程
在VC里不需要新建工程,你可以新建一个文件,对程序进行调试运行,具体做法是:单击“文件”,选择“新建”,在弹出的对话框里默认选项是“工程”,你点击“文件”,选定C/C++Source File,然后在右侧的“文件名”文本框里输入你的文件名,在“位置”里选择你要保存的路径,再“确定”就好了!
编译程序时在编辑区域上方有几个小按钮,分别是编译、连接、调试、运行
你点击编译、连接,如果没有错误,再运行就可以了
⑤ 我想学编程,请问该怎么入门
一:确定一个方向,编程语言太多了:java、C++、python、PHP、C等,需要确定方向,从基础学起,建议零基础学编程的小伙伴从C语言开始学起,C语言入门比较简单,会提升自信心。
二:自学编程入门一定要阶段性的看到成果,这个“成果”并不是在“黑匣子”里面实现,要在用户展现界面呈现,很容易提升信心。
三:视频和图书同步查阅,网上的是鱼龙混珠,建议找一些免费的学编程入门的初级视频进行学习,最好是成套视频,如果条件允许也可以购买一套编程入门的视频资料。
四:计算机编程入门一定要理论和实践相结合只有这样才能真正学好
五:如果你有会编程的好朋友,多请教请教他,能让他带带你就是最好不过的了。
⑥ VC++怎么入门
按照楼上兄弟的说法!可能学了n年还没开始学 VC 吧!在你的心中VC就是那么难的吗!怎么说我也是学VC的,虽然不敢说很厉害,但是自觉对VC还是挺有心得的。
学VC最主要的首先要对 C++ 有一定程度的了解,如果C++不懂,学VC将难度很大。
有一定的C++基础之后特别是 继承,多肽摸版这些东西。
然后就可以去看 MFC 的教程,如实例之类的书来看,对那些编程叫熟悉之后,可以买一些原理类的书来看,如 深入浅出 MFC 。学VC一般的说法就是学 MFC ,不要以为VC就是C++。
其实VC没有想象的那么难,只要用心。
⑦ 怎样才能学会编程VC和C有什么区别
首先VC是一个软件(IDE集成开发环境)(编译、编辑、调试)
C和C++。但C++中的有些特性是不用的,例如I/O流,多态继承
WindowsSDK(软件开发工具)
VC的灵魂:MFC(微软基础类库)
ATL(ActiveX模板类库)
其他的SDK,如OpenGL,DirectX,ActiveMoive,DrawDib(WinG)
VC是许许多多技术的综合,就好像少林72般绝技,一般在应用中学会其中很少一部分就够了。我们的现在目的,其实不过是学一套少林长拳。这套长拳应包括:
1、养成一种严谨的软件开发习惯,熟悉软件工程的基本原则。
2、C语言基础
3、C++最基本内容:类、继承性、封装性、多态性的概念
4、如何用向导建立一个程序框架
5、设计菜单
6、设计工具条
7、设计和使用对话框,熟悉最常用的对话框控件:按钮、静态文本、编辑框等
8、知道怎样新建类、成员函数、成员变量、消息处理函数。
9、了解最常用的Windows消息:如WM_PAINT(重绘窗口),鼠标按下、弹起、移动,初始化对话框,等。
10、了解最简单的GDI(图形设备接口):写文字、画框、画点、画线、画圆,设置画笔、画刷。
11、熟悉最常用的MFC类:
CWnd
CDocument
CView
CDC
CDialog
CWinApp
CGdiObject及子类
CString、CPoint、CRect、CSize等简单数据类型
CFile
以上提到的这些内容,是每个人都会用到的内容。
二、MFC简介
上述主要内容都是与实际操作关系非常密切的,在此不可能讲清楚;而且,这些在一般的书里都会讲到。我主要将最重要的MFC介绍一下。
MFC是对WindowsAPI的封装,大大简化了我们的工作;学VC主要就是要学MFC,大约有100多个类,但常用的也就二三十个。应该象背4级单词一样将这些常用类搞懂;当然不要死记,要通过看帮助、看例子、动手练习来学会它们;而且,并非每个类的内部的所有函数都要学会,要日积月累。如果真的想成为高手,做个笔记本把自己认为重要的类、函数记下来,随时学习,也是很好的突击方法。
下面介绍最重要的MFC。
CWnd:窗口,它是大多数“看得见的东西”的父类(Windows里几乎所有看得见的东西都是一个窗口,大窗口里有许多小窗口),比如视图CView、框架窗口CFrameWnd、工具条CToolBar、对话框CDialog、按钮CButton,etc;一个例外是菜单(CMenu)不是从窗口派生的。该类很大,一开始也不必学,知道就行了。
CDocument文档,负责内存数据与磁盘的交互。最重要的是OnOpenDocument(读入),OnSaveDocument(写盘),Serialize(读写)
CView视图,负责内存数据与用户的交互。包括数据的显示、用户操作的响应(如菜单的选取、鼠标的响应)。最重要的是OnDraw(重画窗口),通常用CWnd::Invalidate()来启动它。另外,它通过消息映射表处理菜单、工具条、快捷键和其他用户消息。你自己的许多功能都要加在里面,你打交道最多的就是它。
CDC设备文本。无论是显示器还是打印机,都是画图给用户看。这图就抽象为CDC。CDC与其他GDI(图形设备接口)一起,完成文字和图形、图像的显示工作。把CDC想象成一张纸,每个窗口都有一个CDC相联系,负责画窗口。CDC有个常用子类CClientDC(窗口客户区),画图通常通过CClientDC完成。
CDialog对话框
CWinApp应用程序类。似于C中的main函数,是程序执行的入口和管理者,负责程序建立、消灭,主窗口和文档模板的建立。最常用函数InitInstance():初始化。
CGdiObject及子类,用于向设备文本画图。它们都需要在使用前选进DC。
CPen笔,画线
CBrush刷子,填充
CFont字体,控制文字输出的字体
CBitmap位图
CPalette调色板
CRgn区域,指定一块区域可以用于做特殊处理。
CFile文件。最重要的不外是Open(打开),Read(读入),Write(写)
CString字符串。封装了C中的字符数组,非常实用。
CPoint点,就是(x,y)对
CRect矩形,就是(left,top,right,bottom)
CSize大小,就是(cx,cy)对(宽、高)
三、用好MSDN和例子
作为提高,推荐看的例子有:
nHello最简单的程序框架
nScribble鼠标绘图。教程:编程基础,GDI
nDiblook图像处理最简单范例
nMFCIE因特网浏览器
nEnroll数据库
nDaoviewDao(数据访问对象)范例。树型和列视控件
nCubeOpenGL范例,画一个不断旋转的方块
nHierSvrOLE服务器
nOclientOLE包容器
nDrawcli鼠标绘图。也包括OLE。
nWordPad写字板。OLE
四、几点经验
A.为什么要用Windows而不是DOS编程
Windows编程并不比DOS编程难很多,只是在刚刚接触的时候感到头绪繁多,不知从何下手。实际上,如果你会C语言,你会发现Windows编程的难度并不比当年学C语言时大。DOS编程要想成为高手,也需要学习几百个函数(无论是TC、BC、MicrosoftC),并要深入了解汇编语言级的DOS功能调用。而现在在Windows下,付出相同的工作量,你却可以获得几倍的收益。如果你以前熟悉DOS编程,现在再搞Windows编程,只要两个星期肯定会感到巨大的优越性:在DOS下,每一件事都要自己干,而且还有64K内存、显示精度等的限制,实在是事倍功半了。
B.为什么要用VC而不是其他Windows编程语言
n大多数大型软件(包括Windows自己)都是用C、C++编的,所以可以利用的源代码特别多。例如Photoshop,就有VC的编程接口。的其他的语言都不如VC有历史优势。而且VC的开发工具特别多,从控件公司到硬件开发商,其产品很少敢不提供VC接口的。
nVC适合组织大工程(VB就不行)
nBorlandC++或C++Builder也很不错,并不比VC差。但BC的版本兼容性不好,从3.1到4.0就出现“代沟”,而且VC提供了极为丰富的文档和范例,VC的参考资料也远比BC多。并且VC与其他的VisualStudio成员可以协调工作,对软件工程有利。
学习VC,千万不要用我们在学校里学英语的方法,而要用小孩学说话的方法。所谓学英语的方法,就是我们在本科时学C语言的那种模式:详细搞懂每一个细节,背大量的规则,很少上机实践,没有实际问题供解决,最后由考试来断定学习成果。这种模式的后果大家都清楚:我们学了十几年英语,可有不少人还只会四五千个单词,写百把字的文章,不会说,不能听;尤其要命的是,看不懂VC的帮助文档。我们要象婴儿一样,在使用中学会语法、修辞和词汇;一开始肯定只能编出最糟糕的,就好像小孩开始只会说:“爸爸坐车车”;但“爸爸”“车车”这些词对小孩是最需要的,学习的效率反而最高。学VC的时候,应从我的需要出发,先做一个最简单的东西,然后一点一点复杂起来,象滚雪球一样。
学习VC尤其要和别人交流,你苦苦思考不明白的,也许别人早就解决了。一定要善于学习:从书店找出有用的书;向身边的高手学习;寻找可以利用的源代码、类库、组件、控件、库;如果能上互连网,那就更加能解决问题了。
⑧ 学VC应该怎么起步(学过c++)
一、VC是什么?学VC是学什么? (转载)
首先VC是一个软件(IDE集成开发环境)(编译、编辑、调试)
C和C++。但C++中的有些特性是不用的,例如I/O流,多态继承
WindowsSDK(软件开发工具)
VC的灵魂:MFC(微软基础类库)
ATL(ActiveX模板类库)
其他的SDK,如OpenGL,DirectX,ActiveMoive,DrawDib(WinG)
VC是许许多多技术的综合,就好象少林72般绝技,一般在应用中学会其中很少一部分就够了。我们的现在目的,其实不过是学一套少林长拳。这套长拳应包括:
1、养成一种严谨的软件开发习惯,熟悉软件工程的基本原则。
2、C语言基础
3、C++最基本内容:类、继承性、封装性、多态性的概念
4、如何用向导建立一个程序框架
5、设计菜单
6、设计工具条
7、设计和使用对话框,熟悉最常用的对话框控件:按钮、静态文本、编辑框等
8、知道怎样新建类、成员函数、成员变量、消息处理函数。
9、了解最常用的Windows消息:如WM_PAINT(重绘窗口),鼠标按下、弹起、移动,初始化对话框,等。
10、了解最简单的GDI(图形设备接口):写文字、画框、画点、画线、画圆,设置画笔、画刷。
11、熟悉最常用的MFC类:
CWnd
CDocument
CView
CDC
CDialog
CWinApp
CGdiObject及子类
CString、CPoint、CRect、CSize等简单数据类型
CFile
以上提到的这些内容,是每个人都会用到的内容。
二、MFC简介
上述主要内容都是与实际操作关系非常密切的,在此不可能讲清楚;而且,这些在一般的书里都会讲到。我主要将最重要的MFC介绍一下。
MFC是对WindowsAPI的封装,大大简化了我们的工作;学VC主要就是要学MFC,大约有100多个类,但常用的也就二三十个。应该象背4级单词一样将这些常用类搞懂;当然不要死记,要通过看帮助、看例子、动手练习来学会它们;而且,并非每个类的内部的所有函数都要学会,要日积月累。如果真的想成为高手,做个笔记本把自己认为重要的类、函数记下来,随时学习,也是很好的突击方法。
下面介绍最重要的MFC。
CWnd:窗口,它是大多数“看得见的东西”的父类(Windows里几乎所有看得见的东西都是一个窗口,大窗口里有许多小窗口),比如视图CView、框架窗口CFrameWnd、工具条CToolBar、对话框CDialog、按钮CButton,etc;一个例外是菜单(CMenu)不是从窗口派生的。该类很大,一开始也不必学,知道就行了。
CDocument文档,负责内存数据与磁盘的交互。最重要的是OnOpenDocument(读入),OnSaveDocument(写盘),Serialize(读写)
CView视图,负责内存数据与用户的交互。包括数据的显示、用户操作的响应(如菜单的选取、鼠标的响应)。最重要的是OnDraw(重画窗口),通常用CWnd::Invalidate()来启动它。另外,它通过消息映射表处理菜单、工具条、快捷键和其他用户消息。你自己的许多功能都要加在里面,你打交道最多的就是它。
CDC设备文本。无论是显示器还是打印机,都是画图给用户看。这图就抽象为CDC。CDC与其他GDI(图形设备接口)一起,完成文字和图形、图像的显示工作。把CDC想象成一张纸,每个窗口都有一个CDC相联系,负责画窗口。CDC有个常用子类CClientDC(窗口客户区),画图通常通过CClientDC完成。
CDialog对话框
CWinApp应用程序类。似于C中的main函数,是程序执行的入口和管理者,负责程序建立、消灭,主窗口和文档模板的建立。最常用函数InitInstance():初始化。
CGdiObject及子类,用于向设备文本画图。它们都需要在使用前选进DC。
CPen笔,画线
CBrush刷子,填充
CFont字体,控制文字输出的字体
CBitmap位图
CPalette调色板
CRgn区域,指定一块区域可以用于做特殊处理。
CFile文件。最重要的不外是Open(打开),Read(读入),Write(写)
CString字符串。封装了C中的字符数组,非常实用。
CPoint点,就是(x,y)对
CRect矩形,就是(left,top,right,bottom)
CSize大小,就是(cx,cy)对(宽、高)
三、用好MSDN和例子
作为提高,推荐看的例子有:
nHello最简单的程序框架
nScribble鼠标绘图。教程:编程基础,GDI
nDiblook图像处理最简单范例
nMFCIE因特网浏览器
nEnroll数据库
nDaoviewDao(数据访问对象)范例。树型和列视控件
nCubeOpenGL范例,画一个不断旋转的方块
nHierSvrOLE服务器
nOclientOLE包容器
nDrawcli鼠标绘图。也包括OLE。
nWordPad写字板。OLE
四、几点经验
A.为什么要用Windows而不是DOS编程
Windows编程并不比DOS编程难很多,只是在刚刚接触的时候感到头绪繁多,不知从何下手。实际上,如果你会C语言,你会发现Windows编程的难度并不比当年学C语言时大。DOS编程要想成为高手,也需要学习几百个函数(无论是TC、BC、MicrosoftC),并要深入了解汇编语言级的DOS功能调用。而现在在Windows下,付出相同的工作量,你却可以获得几倍的收益。如果你以前熟悉DOS编程,现在再搞Windows编程,只要两个星期肯定会感到巨大的优越性:在DOS下,每一件事都要自己干,而且还有64K内存、显示精度等的限制,实在是事倍功半了。
B.为什么要用VC而不是其他Windows编程语言
n大多数大型软件(包括Windows自己)都是用C、C++编的,所以可以利用的源代码特别多。例如Photoshop,就有VC的编程接口。的其他的语言都不如VC有历史优势。而且VC的开发工具特别多,从控件公司到硬件开发商,其产品很少敢不提供VC接口的。
nVC适合组织大工程(VB就不行)
nBorlandC++或C++Builder也很不错,并不比VC差。但BC的版本兼容性不好,从3.1到4.0就出现“代沟”,而且VC提供了极为丰富的文档和范例,VC的参考资料也远比BC多。并且VC与其他的VisualStudio成员可以协调工作,对软件工程有利。
n
C.开始不要学WinAPI编程,但以后最好学学WinAPI
特别要注意,开始不要买讲WindowsSDK编程的书。一个臭名昭着的例子就是“HelloWorld”。各种计算机语言在入门课中往往都给出一个例子,显示一行文字“HelloWorld”,无论是在Basic、C、Pascal,甚至汇编中,这个最简单的小程序都几行就可以写完。但在早期的Windows编程中,刚才讲到的“HelloWin”这个有名的例子就要组织一个工程、写上几百行代码才能实现。这就吓跑了很多想学Windows编程的人。实际上,在Windows下显示“Helloworld”,最简单的方法只要5行就够了:
#include“windows.h”
voidWinMain()
{
MessageBox(NULL,”HelloWorld!”,”MyFirstWindowsApplication”,MB_OK);
}
当然这个程序只建立了一个最简单的对话框,但这已经够了。
如果你没有SDK编程的经验,学VC就是要利用MFC绕过Windows编程的许多细节。有好的工具为什么不用呢?现在你在VC写一个”HelloWorld”,只要写一行代码就可以了。
voidCYourView::OnDraw(CDC*pDC)
{
//…….其他的代码
pDC->TextOut(100,100,”HelloWorld!”);
}
但MFC不是万能的,WinAPI和VC中有很多功能在MFC中并不能反映出来。在入门后,要想发挥VC的完全能力,WindowsAPI还是非常重要的。而且,这些API在其他Windows语言中也用得到。
学语言,与练武道理也差不多。VC、VB、Dlphi、VFP,以及其他的Windows编程语言,都属于同一个门派:Windows门,虽然招式不同,但内功都是一样的,这就是WindowsAPI(应用编程接口),大概是两千个函数。任何武功,招式即使再复杂,通常也能在很短时间内记下来;但内功就不是一朝一夕的事。而且,各门派的内功不同,Unix、Linux门有Uinx的内功,Apple(苹果)门有Mac的内功,Java更是自成一派。我们这里说的学VC,只是学招式,学招式一个月差不多就够了,聪明的两个星期就可以掌握。光学招式,吓唬人是够了,但和高手一过招,非出丑不可。要想精通VC,必须熟悉WindowsAPI。
D.高级语言与自然语言
一门高级语言与一门自然语言是类似的。关键要素有三:
语法:了解C和C++基本语法,这是比较容易的。
修辞:编程的艺术和风格。通常,这是与软件工程联系起来的。算法上的小伎俩并非是关键的。严谨,严格按照规范去做,同时又能发挥出极大的创造性,才是语言学家的本色。
词汇:如何利用别人的工作?如何利用自己以前的工作?这是一个软件工程师成功的关键。如果词汇量不丰富,就写不出好文章,就会有想法表达不出。一个人的语法在上小学之前就基本上学成了,修辞水平也在年轻时就确定了,惟有词汇量需要根据需要不断学习、不断扩充。VC编程中,拥有大的词汇量就意味着要掌握较多的类、函数和其他编程组件。如:WindowsSDK,MFC,以及你所专攻的领域的现成的SDK,比如3D编程中的OpenGL,多媒体编程中的DirectX,图像处理中的Victor库。另外,ActiveX控件的掌握往往也是成败的关键。我们这几年的工作也总结成了一个类库,叫IPX(图像处理框架),大大简化了图像处理的工作;不过现在还有很多细节问题要解决,如果有同学感兴趣可以参与这方面的工作。
学习VC,千万不要用我们在学校里学英语的方法,而要用小孩学说话的方法。所谓学英语的方法,就是我们在本科时学C语言的那种模式:详细搞懂每一个细节,背大量的规则,很少上机实践,没有实际问题供解决,最后由考试来断定学习成果。这种模式的后果大家都清楚:我们学了十几年英语,可有不少人还只会四五千个单词,写百把字的文章,不会说,不能听;尤其要命的是,看不懂VC的帮助文档。我们要象婴儿一样,在使用中学会语法、修辞和词汇;一开始肯定只能编出最糟糕的,就好象小孩开始只会说:“爸爸坐车车”;但“爸爸”“车车”这些词对小孩是最需要的,学习的效率反而最高。学VC的时候,应从我的需要出发,先做一个最简单的东西,然后一点一点复杂起来,象滚雪球一样。
学习VC尤其要和别人交流,你苦苦思考不明白的,也许别人早就解决了。一定要善于学习:从书店找出有用的书;向身边的高手学习;寻找可以利用的源代码、类库、组件、控件、库;如果能上互连网,那就更加能解决问题了。
⑨ 求用vc++编程实现显示灰度直方图的详细步骤,越详细越好
步骤和程序:
打开VC程序——文件——新建——工程中的MFC AppWizard(exe),在工程下面的框中输入工程名(假定工程名为111),点确定——选多重文档,点下一个——后面都点下一个直到完成确定,基本框架就完成了,下面就加代码。
这时VC界面上左边框的下面有三个按钮:ClassView、ResourceView和FileView,ClassView里面是工程111的类:CAdoutDlg、CChildFrame、CMy111App、CMy111Doc、CMy111View和Globals;点ResourceView里面是资源类:Accelerator、Dialog、Icon、Menu、String Table、Toolbar和Version;点开FileView里面是文件类:Source File、Header Files、Resource Files和ReadMe.txt。
点界面的“工程”按钮——添加工程——新建——选C++ Source File,在文件下面的框里输入文件名(如DIBAPI),点“结束”,这样在FileView中的Source Files里面就多了一个DIBAPI.cpp文件,所有的代码都加在该文件中。再点界面的“工程”按钮——添加工程——新建——选C/C++ Header File,在文件下面的框里输入文件名(和前面的文件名必须一致),点“结束”,这样在FileView中的Header Files里面就多了一个DIBAPI.h文件,该文件是DIBAPI.cpp的头文件。
点开DIBAPI.h文件,里面是空白的,把如下代码考入文件中:
//DIBAPI.h
#ifndef _INC_DIBAPI
#define _INC_DIBAPI
DECLARE_HANDLE(HDIB);
#define PALVERSION 0x300
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))
#define RECTWIDTH(lpRect) ((lpRect)->right-(lpRect)->left)
#define RECTHEIGHT(lpRect) ((lpRect)->bottom-(lpRect)->top)
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define DIB_HEADER_MARKER ((WORD)('M'<<8)|'B')
BOOL WINAPI PaintDIB(HDC,LPRECT,HDIB,LPRECT,CPalette* pPal);
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* cPal);
LPSTR WINAPI FindDIBBits(LPSTR lpbi);
DWORD WINAPI DIBWidth(LPSTR lpDIB);
DWORD WINAPI DIBHeight(LPSTR lpDIB);
WORD WINAPI PaletteSize(LPSTR lpbi);
WORD WINAPI DIBNumColors(LPSTR lpbi);
HGLOBAL WINAPI CopyHandle(HGLOBAL h);
BOOL WINAPI SaveDIB(HDIB hDib,CFile& file);
HDIB WINAPI ReadDIBFile(CFile& file);
//在此处输入自己的函数声明
#endif//!_INC_DIBAPI
上面这些函数是实现图像的读取、存储等图像处理的基本功能的,你将自己需要的函数也输入到“//在此处输入自己的函数声明”的下面。
点开DIBAPI.cpp文件,里面是空白的,将如下代码加入其中:
//DIBAPI.cpp
#include "stdafx.h"
#include "DIBAPI.h"
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
if(IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if(dwClrUsed)
return (WORD)dwClrUsed;
}
if(IS_WIN30_DIB(lpbi))
wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
else
wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
WORD WINAPI PaletteSize(LPSTR lpbi)
{
if(IS_WIN30_DIB(lpbi))
return (WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));
else
return (WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
}
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));
}
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biWidth;
else
return (DWORD)lpbmc->bcWidth;
}
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biHeight;
else
return (DWORD)lpbmc->bcHeight;
}
BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette* pPal)
{
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
BOOL bSuccess=FALSE;
HPALETTE hPal=NULL;
HPALETTE hOldPal=NULL;
if(hDIB==NULL)
return FALSE;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=FindDIBBits(lpDIBHdr);
if(pPal!=NULL)
{
hPal=(HPALETTE)pPal->m_hObject;
hOldPal=::SelectPalette(hDC,hPal,TRUE);
}
::SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
{
bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),0,(WORD)DIBHeight(lpDIBHdr),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
}
else
{
bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
lpDIBRect->top,RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
}
::GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal)
::SelectPalette(hDC,hOldPal,TRUE);
GlobalUnlock(hDIB);
return bSuccess;
}
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* pPal)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal=NULL;
LPSTR lpbi;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
int i;
WORD wNumColors;
BOOL bResult=FALSE;
if(hDIB==NULL)
return FALSE;
lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=DIBNumColors(lpbi);
bWinStyleDIB=IS_WIN30_DIB(lpbi);
if(wNumColors!=0)
{
hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
{
::GlobalUnlock((HGLOBAL)hDIB);
return FALSE;
}
lpPal=(LPLOGPALETTE)::GlobalLock(hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=(WORD)wNumColors;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
for(i=0;i<(int)wNumColors;i++)
{
if(bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
}
}
bResult=pPal->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL)hLogPal);
::GlobalFree((HGLOBAL)hLogPal);
}
::GlobalUnlock((HGLOBAL)hDIB);
return bResult;
}
HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{
if(h==NULL)
return NULL;
DWORD dwLen=::GlobalSize((HGLOBAL)h);
HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);
if(hCopy!=NULL)
{
void* lpCopy=::GlobalLock((HGLOBAL)hCopy);
void* lp=::GlobalLock((HGLOBAL)h);
memcpy(lpCopy,lp,dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
BOOL WINAPI SaveDIB(HDIB hDib,CFile& file)
{
BITMAPFILEHEADER bmfHdr;
LPBITMAPINFOHEADER lpBI;
DWORD dwDIBSize;
if(!hDib)
return FALSE;
lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
if(lpBI==NULL)
return FALSE;
if(!IS_WIN30_DIB(lpBI))
{
::GlobalUnlock((HGLOBAL)hDib);
return FALSE;
}
bmfHdr.bfType=DIB_HEADER_MARKER;
dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage;
else
{
DWORD dwBmBitsSize;
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBmBitsSize;
lpBI->biSizeImage=dwBmBitsSize;
}
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+::PaletteSize((LPSTR)lpBI);
TRY
{
file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
file.WriteHuge(lpBI,dwDIBSize);
}
CATCH(CFileException,e)
{
::GlobalUnlock((HGLOBAL)hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL)hDib);
return TRUE;
}
HDIB WINAPI ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
dwBitsSize=file.GetLength();
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
return NULL;
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
return NULL;
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
if(hDIB==0)
return NULL;
pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
{
::GlobalUnlock((HGLOBAL)hDIB);
::GlobalFree((HGLOBAL)hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL)hDIB);
return hDIB;
}
//在此处输入自己的函数定义
上面是DIBAPI.h头文件中声明的函数的定义,你将自己的函数定义加到“//在此处输入自己的函数定义”后面。
下面加相应的消息映射函数,点Ctrl+W键,会出现MFC ClassWizard对话框,点Message Maps,在Class name下面的框中选择CMy111Doc,在Messages里面选中OnOpenDocument,然后点击Add Function按钮就加入了相应的消息映射函数,同样的方法以此加入OnSaveDocument、DeleteContents、CanCloseFrame相应的消息函数,点“确定”即可。
点开111Doc.cpp文件,里面有相应的消息映射函数定义位置,在函数CMy111Doc::CMy111Doc()里输入以下代码:
m_refColorBKG=0x00808080;
m_hDIB=NULL;
m_palDIB=NULL;
m_sizeDoc=CSize(1,1);
在函数CMy111Doc::~CMy111Doc()里输入以下代码:
if(m_hDIB!=NULL)
::GlobalFree((HGLOBAL)m_hDIB);
if(m_palDIB!=NULL)
delete m_palDIB;
在函数BOOL CMy111Doc::OnOpenDocument(LPCTSTR lpszPathName)里/ TODO: Add your specialized creation code here下面添加如下代码:
CFile file;
CFileException fe;
if(!file.Open(lpszPathName,CFile::modeRead|CFile::shareDenyWrite,&fe))
{
ReportSaveLoadException(lpszPathName,&fe,FALSE,AFX_IDP_FAILED_TO_OPEN_DOC);
return FALSE;
}
DeleteContents();
BeginWaitCursor();
TRY
{
m_hDIB=::ReadDIBFile(file);
}
CATCH(CFileException,eLoad)
{
file.Abort();
EndWaitCursor();
ReportSaveLoadException(lpszPathName,eLoad,FALSE,AFX_IDP_FAILED_TO_OPEN_DOC);
m_hDIB=NULL;
return FALSE;
}
END_CATCH
InitDIBData();
EndWaitCursor();
if(m_hDIB==NULL)
{
CString strMsg;
strMsg="读取图像时出错!可能是不支持该类型的图像文件!";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
return FALSE;
}
SetPathName(lpszPathName);
SetModifiedFlag(FALSE);
在函数BOOL CMy111Doc::OnSaveDocument(LPCTSTR lpszPathName)里// TODO: Add your specialized code here and/or call the base class后面添加如下代码:
CFile file;
CFileException fe;
if(!file.Open(lpszPathName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareExclusive,&fe))
{
ReportSaveLoadException(lpszPathName,&fe,TRUE,AFX_IDP_INVALID_FILENAME);
return FALSE;
}
BOOL bSuccess=FALSE;
TRY
{
BeginWaitCursor();
bSuccess=::SaveDIB(m_hDIB,file);
file.Close();
}
CATCH(CException,eSave)
{
file.Abort();
EndWaitCursor();
ReportSaveLoadException(lpszPathName,eSave,TRUE,AFX_IDP_FAILED_TO_SAVE_DOC);
return FALSE;
}
END_CATCH
EndWaitCursor();
SetModifiedFlag(FALSE);
if(!bSuccess)
{
CString strMsg;
strMsg="无法保存BMP图像";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
}
点开ClassView,右键点击CMy111Doc类,点Add Member Variable出现添加成员变量对话框,在Variable Type下的框中输入变量类型名HDIB,在Variable Name中输入变量名m_hDIB,在Access中选中Public就在CMy111Doc中加入了公共成员变量m_hDIB;同样加入int类型的m_nColorIndex、COLORREF类型的m_refColorBKG公共成员变量,再添加保护成员变量(在Access中选中Protected)CSize类的m_sizeDoc、CPalette*类的m_palDIB变量。右键点击CMy111Doc类,点Add Member Function出现添加成员函数对话框,在Function Type下的框中输入函数类型名void,在Function Declaration中输入函数名InitDIBData(),在Access中选中Public就在CMy111Doc中加入了公共成员函数InitDIBData();同样方法加入void类型的公共成员函数ReplaceHDIB(HDIB hDIB)。在111Doc.cpp中加入函数的代码,InitDIBData()里加如下代码:
if(m_palDIB!=NULL)
{
delete m_palDIB;
m_palDIB=NULL;
}
if(m_hDIB==NULL)
return;
LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
if(::DIBWidth(lpDIB)>INT_MAX||::DIBHeight(lpDIB)>INT_MAX)
{
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=NULL;
CString strMsg;
strMsg="BMP图像太大!";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
return;
}
m_sizeDoc=CSize((int)::DIBWidth(lpDIB),(int)::DIBHeight(lpDIB));
::GlobalUnlock((HGLOBAL)m_hDIB);
m_palDIB=new CPalette;
if(m_palDIB==NULL)
{
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=NULL;
return;
}
if(::CreateDIBPalette(m_hDIB,m_palDIB)==NULL)
{
delete m_palDIB;
m_palDIB=NULL;
return;
}
在函数ReplaceHDIB(HDIB hDIB)中加入如下代码:
if(m_hDIB!=NULL)
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=hDIB;
在CMy111doc.h的
// Attributes
public:
下面加入如下代码:
HDIB GetHDIB() const
{
return m_hDIB;
}
CPalette* GetDocPalette() const
{
return m_palDIB;
}
CSize GetDocSize() const
{
return m_sizeDoc;
}
注意要在111Doc.h前加上#include "DIBAPI.h"语句(在class CMy111Doc:public CDocument语句前)
下面为CMy111View中的函数 void CMy111View::OnDraw(CDC* pDC)中添加如下代码:
BeginWaitCursor();
CMy111* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
HDIB hDIB=pDoc->GetHDIB();
if(hDIB!=NULL)
{
LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
int cxDIB=(int)::DIBWidth(lpDIB);
int cyDIB=(int)::DIBHeight(lpDIB);
::GlobalUnlock((HGLOBAL)hDIB);
CRect rcDIB;
rcDIB.top=rcDIB.left=0;
rcDIB.right=cxDIB;
rcDIB.bottom=cyDIB;
CRect rcDest;
if(pDC->IsPrinting())
{
int cxPage=pDC->GetDeviceCaps(HORZRES);
int cyPage=pDC->GetDeviceCaps(VERTRES);
int cxInch=pDC->GetDeviceCaps(LOGPIXELSX);
int cyInch=pDC->GetDeviceCaps(LOGPIXELSY);
rcDest.top=rcDest.left=0;
rcDest.bottom=(int)(((double)cyDIB*cxPage*cyInch)/((double)cxDIB*cxInch));
rcDest.right=cxPage;
int temp=cyPage-(rcDest.bottom-rcDest.top);
rcDest.bottom+=temp/2;
rcDest.top+=temp/2;
}
else
{
rcDest=rcDIB;
}
::PaintDIB(pDC->m_hDC,&rcDest,pDoc->GetHDIB(),&rcDIB,pDoc->GetDocPalette());
}
EndWaitCursor();
以上是关于图像打开、显示、保存的有关步骤和代码。
在111.cpp文件的InitInstance()函数的ParseCommandLine(cmdInfo);语句下输入语句
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
则启动时不自动打开一个空文档。
显示图像直方图步骤:
1、 点击ResourceView,右键点击Dialog,选Insert Dialog 在属性对话框中将ID改为ID_HIST,对话框名称改为“直方图”
2、 在工具栏中点“插入”-“新建类”,输入类名,并选Base Class为CDialog,Dialog ID为ID_HIST。这样就将对话框和类联系起来了,在该对话框中拖入一Edit控件,将其ID设为IDC_HISTSHOW;
3、 快捷键“Ctrl+W”,出现MFC ClassWizard对话框,在Messages栏中分别选WM_INITDIALOG和WM_Paint,再点击“Add Function”,即将对话框初始化和画图函数加入对话框类之中。
4、 在Hist.h文件“public:”下面输入如下变量定义:
LONG m_lCount[256];
char* m_lpDIBBits;
LONG m_lWidth;
LONG m_lHeight;
int m_iIsDraging;
CDlgIntensity(CWnd* pParent = NULL);
5、 打开Hist.cpp程序,在CHist::OnInitDialog()函数中“// TODO: Add extra initialization here”前将如下代码拷贝进去:
unsigned char* lpSrc;
LONG i;
LONG j;
6、 在“// TODO: Add extra initialization here”后将如下代码拷贝进去:
CWnd* pWnd=GetDlgItem(IDC_HISTSHOW);
CRect rect;
GetClientRect(rect);
ClientToScreen(&rect);
for(i=0;i<256;i++)
{
m_lCount[i]=0;
}
LONG lLineBytes;
lLineBytes=WIDTHBYTES(m_lWidth*8);
for(i=0;i<m_lHeight;i++)
{
for(j=0;j<m_lWidth;j++)
{
lpSrc=(unsigned char*)m_lpDIBBits+lLineBytes*i+j;
m_lCount[*(lpSrc)]++;
}
}
m_iIsDraging=0;
7、在CHist::OnPaint()函数“CPaintDC dc(this);”前将如下代码拷如其中:
CString str;
LONG i;
LONG lMaxCount=0;
LONG m_iLowGray=0;
LONG m_iUpGray=255;
在CHist::OnPaint()函数“// TODO: Add your message handler code here”后将如下代码拷如其中:
CWnd* pWnd=GetDlgItem(IDC_ HISTSHOW);
CDC* pDC=pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
pDC->Rectangle(0,0,330,300);
CPen* pPenRed=new CPen;
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* pPenBlue=new CPen;
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0,255));
CPen* pPenGreen=new CPen;
pPenGreen->CreatePen(PS_SOLID,1,RGB(0,255,0));
CGdiObject* pOldPen=pDC->SelectObject(pPenRed);
pDC->MoveTo(10,10);
pDC->LineTo(10,280);
pDC->LineTo(320,280);
str.Format("0");
pDC->TextOut(10,283,str);
str.Format("50");
pDC->TextOut(60,283,str);
str.Format("100");
pDC->TextOut(110,283,str);
str.Format("150");
pDC->TextOut(160,283,str);
str.Format("200");
pDC->TextOut(210,283,str);
str.Format("255");
pDC->TextOut(265,283,str);
for(i=0;i<256;i+=5)
{
if((i&1)==0)
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,284);
}
else
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,282);
}
}
pDC->MoveTo(315,275);
pDC->LineTo(320,280);
pDC->LineTo(315,285);
pDC->MoveTo(10,10);
pDC->LineTo(5,15);
pDC->MoveTo(10,10);
pDC->LineTo(15,15);
for(i=m_iLowGray;i<=m_iUpGray;i++)
{
if(m_lCount[i]>lMaxCount)
{
lMaxCount=m_lCount[i];
}
}
pDC->MoveTo(10,25);
pDC->LineTo(14,25);
str.Format("%d",lMaxCount);
pDC->TextOut(11,26,str);
pDC->SelectObject(pPenGreen);
pDC->MoveTo(m_iLowGray+10,25);
pDC->LineTo(m_iLowGray+10,280);
pDC->MoveTo(m_iUpGray+10,25);
pDC->LineTo(m_iUpGray+10,280);
pDC->SelectObject(pPenBlue);
if(lMaxCount>0)
{
for(i=m_iLowGray;i<=m_iUpGray;i++)
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,281-(int)(m_lCount[i]*256/lMaxCount));
}
}
pDC->SelectObject(pOldPen);
delete pPenRed;
delete pPenBlue;
delete pPenGreen;
8、点开ResourceView中的Menu,出现IDR_MAINFRAME和 IDR_MY111TYPE,双击IDR_MY111TYPE就出现了程序界面,有文件、编辑、查看、窗口、帮助按钮。点“查看”下面的虚线框右键——点“属性”,输入标题(直方图),和ID(大写英文,如ID_VIEW_HIST),这样就将按钮和程序通过ID联系起来了,点击该按钮,就会执行相应的程序。下面为该按钮添加函数:点Ctrl+W ,出现MFC ClassWizard对话框,选Class name为CMy111View,在Object IDs对应的选项中选中设置的ID(如为ID_VIEW_HIST),在Messages选项中选中COMMAND,然后点击“Add Function”按钮,选默认设置,就为ID_VIEW_HIST添加了相应的函数OnViewHist()。该函数在111View.cpp文件中定义,在函数void CMy111View:: OnViewHist()添加如下代码:
// TODO: Add your command handler code here
CMy111Doc* pDoc=GetDocument();
if(pDoc->m_hDIB==NULL)
{
MessageBox("请先打开一幅256色的BMP图像!","系统提示",MB_ICONINFORMATION|MB_OK);
return;
}
LPSTR lpDIB;
LPSTR lpDIBBits;
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
lpDIBBits=::FindDIBBits(lpDIB);
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("目前只支持查看256色位图灰度直方图!","系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
BeginWaitCursor();
CHist dlgPara;
dlgPara.m_lpDIBBits=lpDIBBits;
dlgPara.m_lWidth=::DIBWidth(lpDIB);
dlgPara.m_lHeight=::DIBHeight(lpDIB);
// dlgPara.m_iLowGray=0;
// dlgPara.m_iUpGray=255;
if(dlgPara.DoModal()!=IDOK)
{
return;
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
⑩ 怎样学习VC++
关于这个问题,我来做一个系统的回答
首先,明白一点,你所说的VC++以及BC...都是编译器
要学VC++,当然要先打好语言的根基
学习VC++有相当的内容要学,而最后的深度则看个人的悟性与勤奋了。
1)掌握最新标准的C++。
如果曾经在大学里自以为学过C/C++,还对dynamic_cast/static_cast/template/try/catch/throw/stl/...感到
陌生,那你该Refresh一下新的ANSI C++标准了。 ----此与VC++无甚关联,g++/bcb均有所支持。
(2个月)
2) 学习SDK编程;:-O (6个月) 痛苦是暂时的,必要的,坚持就是胜利! 建议用
Lccwin32/Masm32/Tasm编写小而精的工具软件; "Windows Programming Guide."
"Advanced Windows programming "
3) 研究MFC源代码。(6个月)
不要被一大堆的宏所蒙蔽,just track and dig into it!! 在知道MFC如何扩展,包装SDK之后,自可功
力渐进,不被其MFC系统框架所困绕。
"MFC Internals"
4) 研究OLE/COM技术。
COM/ActiveX技术是MS的核心技术,只有彻底洞察其理论精髓才可以体会现在的
操作系统的技术趋势,以不变应万变。
在此结合本人的一些经验,我再摘引本人收藏的2个经典,肯定益处多多
C++50经典
1.把C++当成一门新的语言学习(和C没啥关系!真的。);
2.看《Thinking In C++》,不要看《C++变成死相》;
3.看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看;
4.不要被VC、BCB、BC、MC、TC等词汇所迷惑——他们都是集成开发环境,而我们要学的是一门语言;
5.不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点;
6.会用Visual C++,并不说明你会C++;
7.学class并不难,template、STL、generic programming也不过如此——难的是长期坚持实践和不遗余力的博览群书;
8.如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的;
9.看Visual C++的书,是学不了C++语言的;
10.浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!?
11.浮躁的人容易问:我到底该学什么;——别问,学就对了;
12.浮躁的人容易问:XX有钱途吗;——建议你去抢银行;
13.浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!
14.浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行;
15.浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;
16.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;
17.C++不仅仅是支持面向对象的程序设计语言;
18.学习编程最好的方法之一就是阅读源代码;
19.在任何时刻都不要认为自己手中的书已经足够了;
20.请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准;
21.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;
22.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;
23.请看《Effective C++》和《More Effective C++》以及《Exceptional C++》;
24.不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序;
25.和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好;
26.请看《程序设计实践》,并严格的按照其要求去做;
27.不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样;
28.C++绝不是所谓的C的“扩充”——如果C++一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密;
29.请不要认为学过XX语言再改学C++会有什么问题——你只不过又在学一门全新的语言而已;
30.读完了《Inside The C++ Object Model》以后再来认定自己是不是已经学会了C++;
31.学习编程的秘诀是:编程,编程,再编程;
32.请留意下列书籍:《C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)》《面向对象软件构造(Object-Oriented Software Construction)》《设计模式(Design Patterns)》《The Art of Computer Programming》;
33.记住:面向对象技术不只是C++专有的;
34.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;
35.把在书中看到的有意义的例子扩充;
36.请重视C++中的异常处理技术,并将其切实的运用到自己的程序中;
37.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;
38.不要漏掉书中任何一个练习题——请全部做完并记录下解题思路;
39.C++语言和C++的集成开发环境要同时学习和掌握;
40.既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的;
41.就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C++语言本身为主;
42.当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43);
43.别心急,设计C++的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的;
44.决不要因为程序“很小”就不遵循某些你不熟练的规则——好习惯是培养出来的,而不是一次记住的;
45.每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解——你能讲清楚才说明你真的理解了;
46.记录下在和别人交流时发现的自己忽视或不理解的知识点;
47.请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.XX;
48.保存好你写过的所有的程序——那是你最好的积累之一;
49.请不要做浮躁的人;
50.请热爱C++!
曾经有一个人写了这个东西,我觉得有些道理,就贴出来吧
C++/OPP/OOD系列:
层级一:语法/语意(C++)
[Lippman2000] Essential C++
Essential C++,by Stanley B. Lippman Addison Wesley Longman 2000,276 pages
Essential C++ 中文版 ,侯俊杰 译,282页
[Gregory95] C++:The Core Language
C++:The Core Language by Gregory Satir 1995 O'Reilly
C++语言核心,张铭泽 译 ,236页
[Deitel98] The Complete C++ Training Course
The Complete C++ Training Course 2/e by Harvey M.Deitel 1998 Prentice Hall
C++大学教程(第二版),邱仲潘等 译,816页
[Stevens2000] Standard C++ Bible
Standard C++ Bible 2000 Al Stevens IDG
标准C++宝典,林丽闽等 译,766页
[Eckel2000] Thinking in C++
Thinking in C++ 2/e Bruce Eckel 2000 1470 pages Prentice Hall
C++ 编程思想,刘宗田等 译,420页
[Lippman98] C++Primer
C++ Primer,3rd Editoin,by Stanley Lippman and Josee Lajoie
Addison Wesley Longman,1998 1237 pages
C++ Primer 中文版,侯俊杰 译,1999,1237页
[Struostrup2000] The C++ Programming Language
The C++ Programming Language,Special Editoin,by Bjarne Stroustrup
Addison Wesley Longman,2000,1017 pages
C++程序语言经典本,叶秉哲 译,儒林 1999
[ANSI C++] C++规格书 1998.9.1 PDF格式
ANSI C++ 1996 Draft
层级二:专家经验(C++/OOP)
[Meyers96] More Effective C++
More Effective C++,by Scott Meyers,Addison Wesley,1996,318pages
More Effective C++中文版,侯俊杰,培生 2000. 318页
[Meyers98] Effective C++
Effective C++,Second Edition,by Scott Meyers,Addison Wesley Longman,1998.256pages
Effective C++ 2/e 中文版,侯俊杰,培生 2000.256页
[Sutter99] Exceptional C++
Exceptional C++,by Herb Sutter,Addison Wesley Longman,2000.208pages
Exceptional C++中文版,侯俊杰,培生 2000.248页
[Sutter2001]More Exceptional C++
More Exceptional C++ by Herb Sutter,Addison Wesley Longman,2001.
层级三:底层机制(C++ Object Model)
[Ellis90] The Annotated C++ Reference Manual
The Annotated C++ Reference Manual,by Margaret A.Ellis and Bjarne Stroustrup
Addison Wesley Longman,1990,447 pages.
[Lippman96] Inside the C++ Object Model
Inside the C++ Object Model,by Stanley Lippman,Addison Wesley Longman,1996,280pages
深度探索C++物件模型,侯俊杰 译
层级四:设计观念的复用(C++/Patterns)
[Gamma95] Design Patterns:Elements of Reusable Object Oriented Software,
by Erich Gamma,Richard Helm,Ralph Johnson,and John Vlissides,Addison Wesley,1995.395pages
设计模式,李英军等译,机械工业出版社,2000.254页
[Alex2001]Modern C++ Design: Generic Programming and Design Patterns Applied
by Andrei Alexandrescu,Addison-Wesley,2001,352Paper
Genericity/STL系列:
第一个境界是使用STL:
[Josuttis99]:The C++ Standard Library -A Tutorial and Reference,by Nicolai M.Josuttis,
Addison Wesley 1999.799pages
第二个境界是了解泛型技术的内涵与STL的学理:
[Austern98]:Generic Programming and the STL -Using and Extending the C++ Standard
Template library,by Matthew H.Austern,Addison Wesley 1998.548page
第三个境界是扩充STL:
[Stepanov2001]:C++ Standard Template Library by P.J.Plauger,Alexander A.Stepanov,
Meng Lee,David R.Musser,Prentice Hall 2001
这些就是你应该看的书,如果你想成为高手。