而c语言的标准输入输出头文件是stdio.h,scanf和printf等。
10.this指针是一个隐含的指针,它是指向对象本身,代表了对象的地址。
11.子类继承父类描述为“子类:
父类”,中间是冒号,构造也是如此:
子类-构造函数:
父类-构造函数;“A:
:
B”是函数标示符,表明B这个函数是属于哪一个类的(A类的)。
12.函数的覆盖和虚函数
函数的覆盖是发生在子类和父类之间,父类中的函数重新定义
虚函数(virtual…),迟绑定技术,调用子类的函数,根据对象的类型调用函数,c++的多态性。
当C++编译器在编译的时候,发现Animal类的breathe()函数是虚函数,这个时候C++就会采用迟绑定(latebinding)的技术,在运行时,依据对象的类型(在程序中,我们传递的Fish类对象的地址)来确认调用的哪一个函数,这种能力就做C++的多态性
含有纯虚函数(virtualvoidfunction()=0;)的抽象类不能实例化对象,只是作为父类进行继承,子类中进行虚函数的实化。
通常,我们把类的定义和函数声明(用函数名+;来声明)放在一个c++的头文件(.h)中,而把具体的函数实现语句放在源文件(.cpp,即cplusplus)中,然后在源文件中进行包含#include’’xxx.h”
13.include“”和include<>,前者表示从当前目录开始查找,然后系统目录。
后者从系统目录开始查找,一般是这对系统的头文件
14.头文件的重复包含问题解决:
在头文件中添加预编译指令符
#ifndefPOINT_H_H
#definePOINT_H_H
Classname{};
#endif
“#”预编译指令符
编译:
只编译源文件;即源文件单独参与编译
VC++既是编译器,又是链接器,又是编辑器。
Compile单独编译某个源文件;Build编译整个工程中的源文件;
编译链接原理如下图:
15.引用定义时必须初始化,相当于给变量起了个别名,引用名不占用内存,与被引用的变量共用同一内存,这是引用与指针的区别。
引用用在函数传参中,避免发生值的拷贝。
第三集MFC库函数的使用
16.lesson3(注意消息的传送!
)
所有与窗口相关的类,CFrameWnd,CDialog,CView类都封装在CWnd类中。
每个工程中都有且仅有一个.app文件,其派生自CWinApp类,唯一的表示当前的这个应用程序。
WinMain函数在AppModule中
AfxWinMain在WinMain文件中。
af是applicationframework“应用程序框架”的缩写
CMainFrame:
CFrameWnd是框架窗口,另外还有一个CTestView:
CView的窗口
MFC窗口工作脉络:
(注意与Win32的窗口应用程序相比,相比而言Win32更容易理解,自己编写嘛)
外部变量生命-构造函数(父-子)-此处定义一个应用程序的实例,即当前应用程序
App中的winmain(),利用AfxWinMain()函数来实现;
AfxWinMain()函数中有InitInstance(虚函数)-设计(系统已经设计好的)、完成注册窗口类、显示窗口
PreCreateWindow()(一般来说,注册窗口类应在此处,但单文档的应用程序在InitInstance()中进行了注册),此时调用基类的PreCreateWindow(),去注册窗口类(如果已注册,则不在注册,否则则进行注册,命令是AfxDeferRegisterClass()即AfxEndDeferRegisterClass来完成)
CreateWindow()创建窗口,CFrameWnd:
:
Create()函数来完成,其.Cpp调用CreatEx()函数;而CreatEx()函数是基类CWnd的一个函数,所以运行基类函数,然后进入PreCreateWindow()函数?
(解析:
PreCreateWindow(CREATESTRUCT&cs)是一个虚函数,因此调用的是子类的函数-多态性,完成“ModifytheWindowclassorstylesherebymodifyingtheCREATESTRUCTcs”);
(以上是在CMainFrame(继承自CFrameWnd)中完成对类的构造和注册)
显示:
利用指向框架窗口的一个指针来完成窗口的显示和更新;
Msg:
CWinThread:
:
Run()完成我们的消息循环。
系统采用的消息映射中的消息响应函数来处理。
17.添加新的窗口的代码应添加到:
frm中的oncreat函数,或view类中的oncreat消息响应函数(添加Windows)。
比如说添加一个Button按钮(注意:
它也是一个窗口,添加仪表控件与此类似)
可以添加代码如下:
CButtonBtn;//创建一个对象;
Btn.Create(LPCTSTRlpszCaption,DWORDdwStyle,constRECT&rect,CWnd*pParentWnd,UINTnID);//创建一个窗口,关联这个对象,此后Btn这个对象即包含后面所涉及使用的句柄,直接进行操作即可.Btn.***等进行赋值。
m_btn.Create("维新",WS_CHILD|BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123);
//m_btn.ShowWindow(SW_SHOWNORMAL);
this指针指向对象本身;
但此时的Btn对象仅仅是一个局部对象,在OnCreate()函数体中,超出此函数外,则该对象将发生析构,析构的时候会将与其相关的窗口资源进行回收,如何保证构建的对象不析构呢?
将定义对象的语句添加到frm的头文件中,或在frm中添加成员变量(可以选择是私有的,因为外部不访问)
this也可以利用得到父窗口的指针:
CWnd:
:
GetParent,改变位置
18.把数据保存和处理显示分离开来,使用文档(数据存储和加载)和视类结构(编辑和修改)来完成。
19.在单文档应用程序中,如何将CMainFrame,CTestView窗口及CTestDoc文档链接在一起?
有机的组织在一起!
在CTestApp类中的InitInstance()函数中,添加相应的代码:
CSingleDocTemplate*pDocTemplate;//其他加载类应该也是如此!
pDocTemplate=newCSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
RUNTIME_CLASS(CMainFrame),//mainSDIframewindow
RUNTIME_CLASS(CTestView));
AddDocTemplate(pDocTemplate);
20.注意窗口类,窗口类的对象及窗口之间的关系:
例如:
CDialogCTestDlg;//构建一个对象;
CTestDlg中的Create()则为创建一个窗口,并把其句柄给对象的成员变量,句柄
窗口销毁,只代表对象中的句柄为空,对象并没有销毁,仍然可以利用Create()函数重新生成一个窗口,并把句柄给对象的成员变量;
而一旦对象销毁,则窗口一定不会存在了。
21.平台SDK函数是Win32的API函数(全局函数),调用时可用:
:
来引导,对局部函数和全局函数进行区分。
22.类的对象和窗口的生命周期
窗口销毁但对象不一定销毁,但对象销毁了,窗口也销毁了,联系的纽带断了。
联系的纽带是类中定义了一个窗口的句柄而已。
C++对象的生命周期一直到winmain函数执行结束后。
譬如:
CButtonbtn;创建一个对象。
Btn.Create(),生成窗口。
第四集绘图知识
23.在MFC中,消息的处理是通过消息影射的方式实现的。
每一个类的对象都有一个与其相对应的指针。
在某一个窗口中产生的消息中会包含某个窗口的句柄,MFC中维护了一个句柄和c++类的对象指针的一个对照表。
通过句柄可以找到与其相对应的c++对象的一个指针。
将指针传递给基类,基类调用windowProc()函数,确定与之相关的窗口(通过句柄),并通过句柄相对应的指针找到基类。
Windowproc()是一虚函数(内有on_wndmsg),调用子类中的虚函数(通过指针),系统判断子类中有无消息响应函数(通过头文件中的declaremsg前的函数声明和cpp文件中的消息影射。
),然后调用消息响应函数进行消息处理。
24.每一个消息函数,产生以后,(10分钟和15分钟介绍)
1)首先会在当前窗口的头文件,注释宏中(protected:
#afx内)添加消息响应函数原形的声明(灰色形式表示,在DECLAR_MESSAGE_MAP之前,afx_msg表示函数原形是消息响应函数原形的声明,形式为:
afx_msgvoidOnLButtonDblClk(UINTnFlags,CPointpoint);)。
在当前窗口的源文件(.cpp)中BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间添加on_****msg,把****msg消息与相应的on_****msg()函数关联起来(形式为:
ON_WM_LBUTTONDBLCLK())。
2)按14中的消息影射方式进行消息处理。
25.CView类是由CWnd派生而来,在CWnd中,有一m_hWnd成员函数,为公有,保存了该类对象的一个句柄。
在hdc=GetDC(**)时,可以用到此句柄。
26.画线:
MoveToEx()
LineTo()
27.所有与作图相关的操作封装在一个CDC类中,可以参看其成员函数。
例如其句柄m_hDc保存了与此类相关的一个句柄。
等。
(32分钟开始介绍)
28.CClientDC对象派生自CDC,封装了GetDC和ReleaseDC()。
获取父窗口的指针,可以访问mainfrme
29.CWindowDC对象派生自CDC,封装了GetDC和ReleaseDC()。
获取父窗口的指针,可以访问window对象。
hdc=:
:
GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
:
:
ReleaseDC(m_hWnd,hdc);*/
/*CDC*pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);*/
//CClientDCdc(this);
/*CClientDCdc(GetParent());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);*/
//CWindowDCdc(this);
//CWindowDCdc(GetParent());
/*CWindowDCdc(GetDesktopWindow());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);*/
/*CPenpen(PS_DOT,1,RGB(0,255,0));
CClientDCdc(this);
CPen*pOldPen=dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
30.创建画笔CPen,然后将笔添加到设备描述表中。
CDC:
:
SelectObject(),完成绘图之后,要替换为原来的画笔。
画刷也是如此。
画刷是填充矩形区域颜色,有颜色画刷和位图画刷。
空画刷的创建:
GetStockObject;
CBrush:
:
Fromhandle(静态函数static,可以直接访问,不必先创建对象,但类中的静态成员变量必须在类的外面进行初始化如:
类名:
变量=**)
Dc.SelectObject();
DC.selectObject()恢复画刷
DC.SetRop2()设定绘图的颜色。
也可以使用CPEN,SelectObject来完成。
第五集文本编程
31.创建插入符:
cwnd:
:
createsolidcaret(尺寸)后跟ShowCaret()
插入符与字体保持一致:
获取设备当前文本的字体信息:
GetTextMatrix()用TEXTMETRIC接收字体信息。
注:
GetTextExtent()用来获得整个字符串占据的矩形区域大小,宽度和高度(csize型)大小。
Stringlen()字符的个数。
位图插入符使用CreateCaret()
32.使文字始终保持在屏幕上,将代码添加在OnDraw消息响应函数中。
此函数是窗口发生重绘时,系统会发送WM_Paint消息,应用程序的框架类就会调用这个函数。
33.文本输出:
CDC:
:
TextOut()
34.CString类-字符串类可以实现自动分配内存;
CStringxx;对CString的对象xx进行赋值时,可以使用xx.LoadString(字符串资源),字符串资源定义的方法:
35.路进程的概念:
BeginPath()
要区分的内容代码写入此处
EndPath()
好处:
使用SelectClipPath(),设置当前的路进程与剪贴区域进行一定的互操作。
对图像进行区别。
dc.GetTextMetrics获得字符本身的度量;
dc.GetTextExtent获得一个字符串的度量(其长度和宽度)
36.字符的输入:
先将插入符放置在待输入字符的位置:
SetCaretPos()
CString对象的清空,CString:
:
Empty();
得到当前文本的背景色:
CDC:
:
GetBkColor()
设置SetBkColor()注意要恢复。
字体的创建,CFont类
37.CDC:
:
DrawText(),平滑变色文字输出函数
38.CString的用法
39.获取窗口的大小CRect,GetWindowRect
40.CEditView和CRichEditView这两个类中带有了很多字处理的函数,如果我们对的View类从这两个类继承而来,则其自己具有一些字处理的命令。
41.在固定元件上绘图
CWnd*pWnd=GetDlgItem(IDC_PICBOX);
pWnd->GetClientRect(&rect);//对话框显示窗口大小
pDC->Rectangle(&rect);//这个很重要!
!
CWnd:
:
SetTimer
UINTSetTimer(UINTnIDEvent,UINTnElapse,void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD));有回调函数
如果回调函数设为空,则系统响应WM_TIMER消息的响应函数。
第六课菜单
42.菜单中添加命令,命令响应函数在Wizzard中添加,command,
Frm类接受到命令响应,菜单响应命令消息执行的顺序依次是view类,doc类,frm类,最后应用程序cpp类。
WM_CREATE,WM_CHAR,WM_PAINT等与此同,是从CWND派生来,可以接收标准和命令消息,而doc类和app类不是从CWND派生,不能接收标准消息只能接受命令WM_COMMAND。
WM_COMMAND形式呈现的命令消息。
WM开头的除WM_COMMAND外,其他的都是标准消息。
由控件产生的通告消息,也是以WM_COMMAND的形式的呈现的。
由CComdTarget(doc,app由此派生)派生的类都可以接受这些消息。
整个的横条称之为Menu“菜单”,每一个菜单的项目,如“文件”“编辑”等称之为子菜单,即含有菜单项的这一部分,而每一个字菜单的下拉栏里的项目称之为菜单项
43.标记菜单的创建:
获取菜单栏的指针:
CMenu*CWND:
:
GetMenu()
获取子菜单的指针:
CMenu*CMenu:
:
GetSubMenu()
菜单项上添加或删除标记:
CMenu:
:
CheckMenuItem()
所以:
GetMenu()->GetSubMenu()->CheckMenuItem()
44.创建缺省菜单项
CMenu:
:
SetDefaultItem()粗体显示。
45.创建图形标记菜单
CMenu:
:
SetMenuItemBitmaps(寻找方式,标志,选中位图,取消位图)
获取系统的信息:
GetSystemMetrics(图形标记flag,SM_CXMENUCHECK)
46.CString提供了format函数,将数据格式化到对象中
例如。
Cs.format(“x=%d,y=%d”,x,y)
47.CMenu:
:
EnableMenuItem()使得某个菜单项取消,将m_bAutoMenuEnable=FALSE,使得自动命令响应函数更新取消。
看EnableMenuItem的例子。
但设置FALSE后,其他的菜单项,在未设置命令响应函数的情况下,将会全部变成灰色,即Disabled。
48.CWND:
:
SetMenu(),移除菜单。
加载菜单(3步),CMenumenu;(应定义为成员变量,若否,使用CMenu:
:
detach())
Menu.loadMenu();
SetMenu(&)
Menu.Detach()(可以查看SetMenu()的注意,detach将菜单句柄与c++对象断开,但不销毁)
49.MFC对菜单项的命令更新机制:
UI是用户接口的简称。
菜单项的维护依赖于CN_UPDATE_COMMAND_UI消息,谁捕获此消息,MFC就在其中创建CCmdUI对象,我们可以通过手工或利用ClassWizard在消息影射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。
在后台所做的工作是:
操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类如CFrameWnd接管。
它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。
这个函数发出CN_UPDATE_COMMAND_U