VC++技术内幕第四版笔记深入浅出了解C++.docx
- 文档编号:24249181
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:30
- 大小:40.93KB
VC++技术内幕第四版笔记深入浅出了解C++.docx
《VC++技术内幕第四版笔记深入浅出了解C++.docx》由会员分享,可在线阅读,更多相关《VC++技术内幕第四版笔记深入浅出了解C++.docx(30页珍藏版)》请在冰豆网上搜索。
VC++技术内幕第四版笔记深入浅出了解C++
VC++技术内幕(第四版)笔记
第1章:
MicrosoftWindows和VisualC++
1,Windows应用程序中一定要有WinMain函数,用来完成某些特殊的任务,其中最主要的是创建应用次序的主窗口。
2,DOS下,所有次序的目标模块在创建过程中都被静态连接起来。
而Windows允许动态连接,即一些特定结构的库(DLL)可以在运行过程中被装入和连接,并且被多个应用程序共享。
3,项目是一些相互关联的源文件的集合,这些源文件经过编译、连接,然后被组合在一起形成可执行的Wwindows应用程序或DLL。
4,几个重要DeveloperStudio创建的中间文件:
CLW(支持ClassWizard)DSP(项目文件)
DSW(工作空间文件)NCB(支持ClassView)
OPT(保持工作空间的配置)PLG(建立日志文件)
5,AppWizard是一个代码生成器,它会按照用户通过对话框指定的特性、类名、及源代码文件名来产生Windows应用程序工作架构。
AppWizard所产生的代码只是一些最基本的代码,它完成的功能完全由应用程序的基类所决定。
/**************************************/
第二章:
Microsoft基本类库应用程序框架
1,按照惯例,MFC库类名用大写“C”打头。
2,类CMyApp的对象theApp就代表一个应用程序。
当运行该应用程序的时候,WINDOWS自动调用程序框架内部的WinMain函数,WinMain函数会去查找该应用程序的全局构造对象(theApp),该对象是有CWinApp类派生类的对象。
C++中,全局对象在主程序被运行之前就已经构造好了。
3,当WinMain发现该应用程序对象(theApp)时,会自动调用虚拟成员函数CWinApp:
:
InitInstance(),该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。
由于基类CWinApp中不知道我们实际需要的什么样的窗口,所以我们必须在派生出的应用程序类CMyApp中重载InitInstance()函数(CMyApp:
:
InitInstance()),由多态性,当调用CWinApp:
:
InitInstance()时候,会自动转向MyApp:
:
InitInstance().
4,WinMain函数调用完InitInstance()函数后,就调用CWinApp:
:
Run函数,CWinApp:
:
Run函数被隐藏在基类中负责传递应用程序的消息给相应的窗口,从而维护应用程序的运转。
5,关闭应用程序(对单一框架程序来说),首先CMyFrame对象被删除,然后退出Run,进而退出WinMain,最后删除CMyApp对象(theApp)。
6,一些Windows类库在基类为鼠标事件消息以及其他一些标准消息定义一些虚函数,如果需要,派生类会对这些函数进行重载。
MFC库应用程序框架没有采用虚函数来处理Windows消息,而是通过一些宏来将特定的消息映射到派生类中相应的成员函数上。
(原因:
P21。
C++类对程序中用到的每一个派生类都要求有一张虚函数分发表VTABLE,在BTABLE中每个虚函数都需要有一个4字节的入口项,而不管该函数会不会在派生类中被重载。
)
MFC消息控件函数要求提供函数原型,函数体,以及在消息映射中的入口。
7,文档-视图结构将数据从用户对数据的观察中分离出来,这样就允许对同一数据可以有多个视图。
MFC库应用程序中,文档和视图是由C++类的实例来描述的。
文档基类代码通常和FILEOPEN,FILESAVE菜单项关联,而派生文档类则一般用来完成对文档对象数据的实际读写工作。
视图基类通常表示一个包含于框架窗口中的窗口,而派生视图类则常用来和稳当类相联系,负责应用程序的显示和打印机I/O。
派生视图类及其基类共同处理WINDOWS的消息,而MFC库则协调文档,视图,框架窗口,以及应用程序之间的相互作用关系,这种协调多用虚函数来实现。
文档对象既可以与一次可全部读入内存的磁盘文件相关联,也可以同数据库相关联。
第三章:
从“Hello,world!
”着手学习AppWizard
1,视图:
从用户角度看,视图是一个普通的窗口;从程序员角度看,试图是一个从MFC库中CView类所派生的类的对象。
视图对象的行为完全由类的成员函数和数据成员决定,其中包括派生类的特定成员和基类的继承而来的成员。
2,CEx03aView类最重要的基类是CWnd和CView。
CWnd提供CEx03aView的窗口属性,而CView提供它和应用程序框架其它部分之间的联系,特别是和文档及框架窗口之间的联系。
3,视图类中OnDraw成员函数:
OnDraw成员函数被设计成一个虚成员函数,每次当视窗需要被重绘时候,应用程序都要调用OnDraw函数。
当用户改变了窗口尺寸,或当前窗口恢复了先前被遮盖的部分,或当前应用程序改变了窗口的数据的时候,窗口都需要被重绘。
当用户改变了窗口尺寸,或窗口需要恢复被遮盖的部分,则应用程序自动去调用OnDraw函数。
但注意,如果程序中某个函数修改了窗口数据,则它必须通过调用视图所继承的Invalidate(InbalidateRect)成员函数来通知Windows,调用Invalidate后会触发对OnDraw函数的调用。
4,WINDOW中不允许直接访问显示硬件,必须通过和窗口相关联的“设备环境”跟显示硬件通讯。
MFC中设备环境由CDC类对象来表示。
5,利用Win32Debug模式和Win32Release模式开发应用程序。
(默认情况不出现BUILD工具栏,可从TOOLS菜单选择Customize项,设置显示Build工具栏,VC6中也可在工具栏上直接点击右键选择Build工具栏)
Win32Release模式Win32Debug模式
源码调试不能编译器连接器都允许
MFC诊断宏不能(定义了NDEBUG)可以(定义了_DEBUG)
库连接MFCRelease库MFCDebug库
编译优化速度优化(学习版不能)没有优化(快速编译)
我们应在Win32Debug模式下开发应用程序,然后在发布或交付前用Win32Release模式重建应用程序。
in32Release模式下建立的EXE文件又小又快。
6,诊断宏TRACE宏对监测程序状态特别有用。
这些宏要求在允许追踪的情况下才有效,允许追踪是默认设置。
(问题:
TRACE宏的应用事例与运行原理。
宏TRACE的输出在在哪显示呢?
在output输出框下选择Debug项,调试运行程序即可看到TRACE宏输出。
)
7,预编译头文件代表了编译器在源代码特定行上进行‘快照’。
在MFC库程序中,快照常紧接在#include"stdafx.h"后进行。
文件StdAfx.h包含了MFC库头文件的#include语句。
该文件的内容取决于运行AppWizard时候所做的选择。
文件StdAfx.cpp只包含#include"stdafx.h"语句。
StdAfx.cpp文件用来在相应项目的目录下产生预编译头文件(PCH文件)。
编译开关/Yc只用于StdAfx.cpp文件,导致产生预编译头文件(PCH),而其它源文件的/Yu编译开关使可以使用一个存在的PCH文件。
开关/Fp用来指定专门的PCH文件名,默认情况下为相应目标输出文件目录下与项目同名扩展名为PCH的文件。
(VC6下具体设置参见:
[ProjectSettings属性框][c/c++]属性页[ProjectOptions]、[SourceFileOptions]项)
(注意:
在VC6[ProjectSettings属性框]中查看StdAfx.cpp文件[SourceFileOptions]项时候,可以看到[ProjectSettings,and/Yc"stdafx.h"],这里说明一下,StdAfx.cpp文件的[/Yc"stdafx.h"]的设置覆盖了[ProjectOptions]设置中的[/Yu"stdafx.h"])
第四章:
基本事件处理、映射模式和滚动视图
1,消息映射:
如在视窗中按下鼠标做键,会自动发送WM_LBUTTONDOWN消息,如果要对这消息有所反应的话,需
//{{AFX_MSG(CEx04aView)
afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);//头文件声明消息响应函数原型。
//}}AFX_MSG
DECLARE_MESSAGE_MAP()//头文件
BEGIN_MESSAGE_MAP(CDrawView,CView)//代码文件
//{{AFX_MSG_MAP(CEx04aView)
ON_WM_LBUTTONDOWN()//该消息映射宏将OnLButtonDown函数和应用程序框架联系在一起
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
voidCDrawView:
:
OnLButtonDown(UINTnFlags,CPointpoint)//代码文件
{
//eventprocessingcodehere
}
说明:
为了方便ClassWizard,AppWizard生成了一些注释行。
它把消息映射函数原型放在两个AFX_MSG“刮弧对”之间,在AFX_MSG_MAP“刮弧对”之间添加消息映射入口,并在代码文件中给出完整的OnLButtonDown成员函数框架。
2,视图中的OnDraw()是根据视图当前状态来绘制图象的,用户的操作可以改变这中状态。
在完整的MFC库应用程序中,文档的对象掌握在应用程序(视图)的状态。
3,如果用全程变量来保存视图状态,这将在多视图情况下会遇到麻烦;(待体会)
4,CWnd:
:
InvalidateRect函数能够触发WM_PAINT消息,该消息被窗口类如CView映射后,引起对OnDraw函数调用,从而重绘无效矩形区域。
优化窗口的绘制过程:
1)设置的无效区域越小,重画的速度就越快;
2)执行无效区域外的绘制纯属于浪费时间,OnDraw函数可以调用CDC的成员函数GetClipBox得到无效区域大小。
注意:
OnDraw函数不仅仅响应InValidate*之类的调用,它也会在窗口改变大小和窗口显露时被调用。
5,本章重要介绍函数
PtInRect(..);//测试一个点是否落在某个矩形内。
PtInRegion(..);//判断一个点是否落在椭圆(CRgn对象)内//Aregionisanellipticalorpolygonalareawithinawindow.
GetClientRect(..);//获得客户矩形坐标并保持在CRect对象中
SelectStockObject(..);//选择thepredefinedstockpens,brushes,orfonts到DC中,函数返回先前的CGdiObject对象指针。
6,在构造函数中对类数据成员初始化。
CEx04aView:
:
CEx04aView():
m_rectEllipse(0,0,200,200)//注意这种初试化方式,m_rectEllipse是CEx04aView类数据成员CRect类对象
{
m_nColor=GRAY_BRUSH;
}
7,[致WIN32程序员]:
标准的基于WINDOWS应用程序会首先登记一个窗口类(不同于C++类[补:
实际是个_WNDCLASS结构体]),同时在处理过程中,还需要对每个类指定窗口过程(WINDOWSPROCEDURE)。
每次应用程序调用CreateWindow建立一个窗口时候,都要指定一个窗口类做为参数,这样就把新建立的窗口和窗口过程函数连接起来了。
每次Windows给窗口发送消息时候,这个函数就会被调用(补:
消息循环中DispatchMessage(&msg)分派消息到窗口的回调函数处理,OS调用窗口回调函数进行处理),以检查用参数传送进来的消息码,并执行适当的代码来处理该消息。
MFC库应用程序框架有一个适用于大多数窗口类型的简单窗口类和窗口过程函数。
该窗口过程函数会根据参数传进来的窗口句柄,在MFC的句柄映射表(handlemap)中查找,从而得到对应的C++窗口对象指针。
然后,该窗口过程函数用MFC运行时类(runtimeclass)系统来决定窗口对象的C++类。
下一步,它从由消息分发映射函数生成的静态表中找到消息处理函数,最后用正确的窗口对象调用消息处理函数。
8,映射模式:
1)MM_TEXT映射模式:
坐标被映射到象素,X值向右递增,Y值向下递增。
可用它来表示[设备坐标]。
CDC:
:
SetMapMode(..)//设置映射模式
CDC:
:
GetMapMode(..)
CDC:
:
SetViewportOrg(..)//设置视口原点
CDC:
:
GetViewportOrg(..)
CDC:
:
SetWindowOrg(..)//设置屏幕原点
CDC:
:
GetWindowOrg(..)
2)固定比例映射模式(MM_HIENGLISH,MM_HIMETRIC,MM_LOMETRIC,MM_LOENGLISH,MM_TWIPS)
固定比例映射模式均X值向右递增,Y值向下递增,它们之间唯一差别是实际的比例因子。
如下:
MM_HIENGLISHEachlogicalunitisconvertedto0.001inch.
MM_HIMETRICEachlogicalunitisconvertedto0.01millimeter.
MM_LOENGLISHEachlogicalunitisconvertedto0.01inch.
MM_LOMETRICEachlogicalunitisconvertedto0.1millimeter.
MM_TWIPSEachlogicalunitisconvertedto1/20ofapoint(磅).(Becauseapointis1/72inch,atwipis1/1440inch.)
//MM_TWIPS常常用于打印机。
3)可变比例映射模式:
(MM_ISOTROPIC,MM_ANISOTROPIC)
这两种模式用许我们改变它们的比例因子和坐标原点。
应用这两中模式,如用户改变窗口的尺寸,绘制的图形大小也会发生响应的变化
具体如下:
TheMM_HIENGLISH,MM_HIMETRIC,MM_LOENGLISH,MM_LOMETRIC,andMM_TWIPSmodesareusefulforapplicationsthatmustdrawinphysicallymeaningfulunits(suchasinchesormillimeters).TheMM_ISOTROPICmodeensuresa1:
1aspectratio,whichisusefulwhenitisimportanttopreservetheexactshapeofanimage.TheMM_ANISOTROPICmodeallowsthex-andy-coordinatestobeadjustedindependently
常一起使用的函数:
SetWindowExt(..)//Setsthex-andy-extentsofthewindowassociatedwiththedevicecontext.
SetViewportExt(..)//Setsthex-andy-extentsoftheviewportofthedevicecontext.
注意:
Whenthefollowingmappingmodesareset,callstoSetWindowExtandSetViewportExtfunctionsareignored:
MM_HIENGLISH,MM_HIMETRIC,MM_LOENGLISH,MM_LOMETRIC,MM_TEXT,MM_TWIPS
WhenMM_ISOTROPICmodeisset,anapplicationmustcalltheSetWindowExtmemberfunctionbeforecallingSetViewportExt.
9,坐标变换:
(具体参见P54)
许多MFC库函数只能在设备坐标下工作(尤其CRect类成员函数)。
可以认为CDC的所有成员函数都一逻辑坐标作参数。
可以认为CWnd的成员函数都以设备坐标做参数。
(所有在实际窗口上点击获得的坐标都是逻辑坐标)。
在设置了设备环境的映射模式及相应的参数以后,CDC的LPtoDP和DPtoLP函数可以用来在逻辑坐标系和设备做表系之间进行转换。
在CView的虚函数OnPrepareDC中设置映射模式要比在OnDraw函数中要好。
//*注意:
CView:
:
OnPrepareDC
virtualvoidOnPrepareDC(CDC*pDC,CPrintInfo*pInfo=NULL);
应用程序将在调用OnDraw之前调用OnPrepareDC函数。
(OnPrepareDC在为屏幕显示而调用OnDraw函数之前,或在为打印或打印预览每一页而调用OnPrint成员函数之前。
)
10,CScrollView支持滚动条的滚动,但不支持键盘的滚动。
通过使用CWnd的ScrollWindow和SetViewportOrg函数,CScrollView类允许将视口原点移到窗口中的任何一个位置,甚至包括窗口区域的上部或窗口的原点的左边。
键盘输入是分两步处理的。
OS向窗口发送类如WM_KEYDOWN和WM_KEYUP消息时用的是虚拟键盘码,在消息到达窗口之前,被翻译成WM_CHAR消息,该消息带着正常的键码。
利用对WM_KEYDOWN消息进行响应,对按键分别调用OnVScroll就可以使应用程序支持键盘的滚动。
CWnd:
:
OnVScroll
afx_msgvoidOnVScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar);
////
nSBCode:
SB_BOTTOMScrolltobottom.
SB_ENDSCROLLEndscroll.
SB_LINEDOWNScrollonelinedown.
SB_LINEUPScrollonelineup.
SB_PAGEDOWNScrollonepagedown.
SB_PAGEUPScrollonepageup.
SB_THUMBPOSITIONScrolltotheabsoluteposition.ThecurrentpositionisprovidedinnPos.
SB_THUMBTRACKDragscrollboxtospecifiedposition.ThecurrentpositionisprovidedinnPos.
SB_TOPScrolltotop.
////
Theframeworkcallsthismemberfunction(OnVScroll)whentheuserclicksthewindow’sverticalscrollbar.
11,CView:
:
OnInitialUpdate
virtualvoidOnInitialUpdate();
说明:
OnInitialUpdate是视图窗口完全建立后框架调用的第一个函数。
框架在第一次调用OnDraw前会调用OnInitialUpdate。
具体参见下:
Calledbytheframeworkaftertheviewisfirstattachedtothedocument,butbeforetheviewisinitiallydisplayed.ThedefaultimplementationofthisfunctioncallstheOnUpdatememberfunctionwithnohintinformation.
12,MFC对140种Windows消息直接直接提供了相应的消息控制函数,当然,我们还可以定义自己的消息和相应的消息控制函数。
五种特殊Windows消息:
WM_CREATE,WM_CLOSE,WM_QUERYENDSESSION,WM_DESTROY,WM_NCDESTROY.(具体参见p62-63页。
这两页强烈建议看看,这里简要笔记三个最常用最重要的)
1)WM_CREATE消息:
TheWM_CREATEmessageissentwhenanapplicationrequeststhatawindowbecreatedbycallingtheCreateWindowExorCreateWindowfunction.Thewindowprocedureofthenewwindowreceivesthismessageafterthewindowiscreated,butbeforethewindowbecomesvisible.ThemessageissentbeforetheCreateWindowExorCreateWindowfunctionreturns.
2)WM_CLOSE消息:
当关闭窗口或父窗口被关闭时,Windows都会发送WM_CLOSE消息。
可以重新定义该消息响应函数OnClose来完全控制关闭过程。
3)WM_DESTROY消息:
Windows在发送WM_CLOSE消息之后,紧接着就会发送WM_DESTROY消息(响应这个消息的时候,窗口已经消失但还没有销毁)。
(可以响应这个消息来做一些销毁当前窗口后的一些事情,例如再弹出其它对话框发送其他的消息)
第五章:
图形设备接口(GDI)、颜色及字体
1,任何时候当程序需要直接在屏幕或打印机上绘图的时候,都需要调用GDI函数,GDI函数包含了一些用于绘制图形、位图以及文本的函数。
2,Windows的设备环境是GDI的关键元素,它代表了物理设备。
每一个C++设备环境对象都有与之对应的Windows设备环境,并且通过一个32位类型的HDC句柄来标识。
3,MFC库设备环境类基类CDC包含了绘图所需要的所有成员函数,并且几乎所有派生类只有构造函数和析构函数不同(CMetaFileDC类除外)。
对于显示器来说,常用的派生类有CClientDC和CWindowDC,而对其它设备(如打印机或内存缓冲区),则可以构造一个基类CDC的对象。
对于显示器和打印机设备环境对象来说,应用程序框架会直接将句柄附在对象上;而对其它设备环境(如内存设备环境),为了将对象与句柄相联系,在构造完对象之后,还必须调用一个成员函数(进行初试化)。
4,CClient
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 技术 内幕 第四 笔记 深入浅出 了解 C+