MFC复习08总结.docx
《MFC复习08总结.docx》由会员分享,可在线阅读,更多相关《MFC复习08总结.docx(23页珍藏版)》请在冰豆网上搜索。
MFC复习08总结
一、数组的使用
按老师要求数组使用STL里面的vector,list,map,set.c++STL,即c++标准模板库,又称c++泛型库,它是在std命名空间中定义的常用的数据结构和算法。
作业要求使用vector容器。
Vector向量容器不但能像数组一样对元素进行随机访问,还能在尾部插入元素,是一种简单高效的容器,完全可以代替数组,vector的优点是具有内存自动管理的功能,对于元素的插入和删除,可以动态调整所占的内存空间。
作业1(画点连线)示例如下:
1、用MFCAppWizard创建一个名称为drawLine的单文档应用程序;
2、在视图类的头文件中添加两个public成员变量,如下:
public:
vectorm_vPoint;
intm_nNum;
3、在视图类定义的上方添加vector头文件和std命名空间,如下:
#include
usingnamespacestd;
4、在视图类的构造函数对m_nNum进行初始化,m_nNum=0;
5、在视图类源文件添加OnLButtonDown和OnRButtonDown函数,如下进行添加,即完成了画点连线功能。
voidCDrawLineView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
m_vPoint.push_back(point);
m_nNum++;
CClientDCdc(this);
if(m_nNum>1)
{
dc.MoveTo(m_vPoint.at(m_nNum-2));//因为vector容器的下标是从0开始计数的
dc.LineTo(m_vPoint.back());
}
CView:
:
OnLButtonDown(nFlags,point);
}
voidCDrawLineView:
:
OnRButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
FILE*file;
if(_access("点信息.txt",0)==-1)
{
file=fopen("点信息.txt","wt+");
}
else
{
file=fopen("点信息.txt","at+");
}
for(inti=0;i{
CPointpt;
pt=m_vPoint[i];
fprintf(file,"(%d,%d)\n",pt.x,pt.y);
}
m_nNum=0;
m_vPoint.clear();
CView:
:
OnRButtonDown(nFlags,point);
}
知识点追加:
vector的常用函数:
1、push_back(),用来对vector容器尾部追加新元素,如:
m_vPoint.push_back(point);v.push_back(9);
2、insert(),在vector对象的任意位置前插入一个新的元素,如v.insert(v.begin(),6)//在最前面插入新元素,元素值为8;
3、at(),返回元素所在位置的元素值。
二、序列化
在面向对象理论中,能使对象成为永久性对象的机制叫做序列化(Serialization)。
作业2(建一个画线管理类)示例如下:
1、用MFCAppWizard创建一个名称为drawReadManage212的单文档应用程序;
2、右键单击工程,单击NewClass,弹出NewClass对话框,如下进行设置:
3、在新建的类中添加下列变量成员和函数:
classCPesMana:
publicCObject
{
public:
CPesMana();
virtual~CPesMana();
public:
std:
:
vectorm_vPoint;
voidsave(constchar*pfile);//保存函数
voidload(constchar*pfile);//加载函数
voidSerialize(CArchive&ar);//序列化函数
};
4、在CpesMana类定义的上方,添加vector头文件:
#include
5、分别实现自定义的成员函数
voidCPesMana:
:
Serialize(CArchive&ar)
{
CObject:
:
Serialize(ar);//必须使用这个语句
if(ar.IsStoring())
{
intnum=m_vPoint.size();
ar<for(inti=0;i{
ar<}
}
else
{
intnum;
ar>>num;
if(num>0)
{
m_vPoint.resize(num);
}
for(inti=0;i{
ar>>m_vPoint[i];
}
}
}
voidCPesMana:
:
save(constchar*pfile)
{
CFilefile;
if(!
file.Open(pfile,CFile:
:
modeCreate|CFile:
:
modeWrite))
{
return;
}
CArchivear(&file,CArchive:
:
store);//初始化
Serialize(ar);//调用序列化函数保存
ar.Close();
file.Close();
}
voidCPesMana:
:
load(constchar*pfile)
{
CFilefile;
if(!
file.Open(pfile,CFile:
:
modeRead))
{
return;
}
CArchivear(&file,CArchive:
:
load);//初始化
Serialize(ar);//调用序列化函数保存
ar.Close();
file.Close();
}
6、在视图类中加入头文件#include"PesMana.h",并实例化CpesMana类,如下:
#include"PesMana.h"
classCDrawReadManage212View:
publicCView
{
protected:
//createfromserializationonly
CDrawReadManage212View();
DECLARE_DYNCREATE(CDrawReadManage212View)
//Attributes
public:
CDrawReadManage212Doc*GetDocument();
//Operations
public:
CPesManam_pesMana;
7、在Resource视图下,在IDR_MAINFRAM中添加四个按钮,如下图:
三个弹出按钮分别对应的ID为
8、在OnDraw()函数添加如下代码:
intnum;
num=m_pesMana.m_vPoint.size();
for(inti=0;i{
pDC->MoveTo(m_pesMana.m_vPoint.at(i));
pDC->LineTo(m_pesMana.m_vPoint.at(i+1));
//pDC->MoveTo(m_pesMana.m_vPoint[i]);
//pDC->LineTo(m_pesMana.m_vPoint[i+1]);
}
}
9、在视图类源文件添加OnLButtonDown、OnSave、OnLoad、OnClear函数进行如下编写,即可
voidCDrawReadManage212View:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
m_pesMana.m_vPoint.push_back(point);
Invalidate();
CView:
:
OnLButtonDown(nFlags,point);
}
voidCDrawReadManage212View:
:
OnSave()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.save("点信息.txt");
}
voidCDrawReadManage212View:
:
OnLoad()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.load("点信息.txt");
Invalidate();
}
voidCDrawReadManage212View:
:
OnClear()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.m_vPoint.clear();
Invalidate();
}
知识点追加:
序列化的几个关键点:
1、使用序列化函数的类必须继承自CObject,因为Serialize是Cobject提供的一个虚函数;
2、重写序列化函数时,必须加入CObject:
:
Serialize(ar);这条语句,以调用基类函数的实现;
3、序列化函数实现过程中,必须进初始化:
CArchivear(&file,CArchive:
:
store);//初始化
三、动态链接库:
1)常规动态库
常规动态库需要对导出的函数加以声明:
一是使用def文件声明导出函数,记载def文件EXPORTS语句后写下导出函数的名字;而是使用_declspec(dllexport)。
作业3(常规动态库并显示加载)示例如下:
1、用MFCAppWizard创建一个名称为regularDll212的常规性DLL;
2、在CRegularDll212App.h头文件中加入导出函数声明:
extern"C"_declspec(dllexport)voidsave(vector&vPt,constchar*pfile);
3、在CRegularDll212App.h头文件类定义上方加入以下头文件和命名空间:
#include
usingnamespacestd;
#include
4、在CRegularDll212App.cpp源文件中加实现函数,Build即完成(一般将Outputfils设置成..\lib,以便于动态库的使用);
extern"C"_declspec(dllexport)voidsave(vector&vPt,constchar*pfile)
{
FILE*file;
//-------------------------------------------------------------
//如果txt文件不存在,就以新建的方式打开
if(_access(pfile,0)==-1)
{
file=fopen(pfile,"wt+");
}
//-------------------------------------------------------------
//如果txt文件存在,就以追加的方式打开
elseif(_access(pfile,0)!
=-1)
{
file=fopen(pfile,"at+");
}
intnum=vPt.size();
for(inti=0;i{
CPointpt;
pt=vPt.at(i);
intm=pt.x;
intn=pt.y;
fprintf(file,"(%d,%d)\n",m,n);
}
fclose(file);
//-------------------------------------------------------------
//清除vector内容
vPt.clear();
}
5、用MFCAppWizard创建一个名称为regularDllTest212的单文档应用程序,在视图类头文件中加入如下成员变量;
vectorm_vPoint;
intm_nNum;
6、在视图类定义的上方加入下列头文件:
#include
usingnamespacestd;
7、在视图类的构造函数中,初始化m_nNum=0;
8、在视图类源文件添加OnLButtonDown和OnRButtonDown函数,如下进行添加代码,然后编译运行即可;
voidCRegularDllTest212View:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
m_vPoint.push_back(point);
m_nNum++;
CClientDCdc(this);
//-------------------------------------------------------------
//点数大于1时开始划线
if(m_nNum>1)
{
dc.MoveTo(m_vPoint.at(m_nNum-2));
dc.LineTo(m_vPoint.back());
}
//-------------------------------------------------------------
//每个点上画一个圆
dc.Ellipse(point.x-4,point.y-4,point.x+4,point.y+4);
CView:
:
OnLButtonDown(nFlags,point);
}
voidCRegularDllTest212View:
:
OnRButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
HINSTANCEhDllInst;//当前程序应用实例句柄
hDllInst=:
:
LoadLibrary("../lib/regularDll212.dll");//动态加载Dll
typedefvoid(*SAVEPROC)(vector&vPt,constchar*pfile);//定义函数指针类型
SAVEPROCSave=(SAVEPROC):
:
GetProcAddress(hDllInst,"save");//获得导出函数
if(!
Save)
{
AfxMessageBox("Fail");
return;
}
Save(m_vPoint,"点信息.txt");
FreeLibrary(hDllInst);
CView:
:
OnRButtonDown(nFlags,point);
}
2)扩展型DLL
扩展型动态库就在于可以继承MFC类库中的类来派生所需要的类,从而使程序设计工作变得更加快捷。
在扩展型DLL中,只要在类的名称前面增加宏AFX_EXT_CLASS,就可以把一个MFC继承类声明为导出类。
作业4(扩展动态库并隐式链接)示例如下:
1、用MFCAppWizard创建一个名称为extendDll212的扩展型DLL;
2、右键单击工程,单击NewClass,弹出NewClass对话框,如下进行设置:
3、在新添类的名称前加上AFX_EXT_CLASS,即classAFX_EXT_CLASSCPesMana:
publicCobject
4、在新建的类中添加下列变量成员和函数:
classCPesMana:
publicCObject
{
public:
CPesMana();
virtual~CPesMana();
public:
std:
:
vectorm_vPoint;
voidsave(constchar*pfile);//保存函数
voidload(constchar*pfile);//加载函数
voidSerialize(CArchive&ar);//序列化函数
};
4、在CpesMana类定义的上方,添加vector头文件:
#includeusingnamespacestd;
5、分别实现自定义的成员函数,Build即完成扩展动态库的创建。
voidCPesMana:
:
Serialize(CArchive&ar)
{
CObject:
:
Serialize(ar);
if(ar.IsStoring())
{
intnum=m_Vpt.size();
ar<for(inti=0;i{
ar<}
}
else
{
intnum;
ar>>num;
if(num>0)
m_Vpt.resize(num);
for(inti=0;i{
ar>>m_Vpt[i];
}
}
}
voidCPesMana:
:
save(constchar*pfile)
{
CFilefile;
if(!
file.Open(pfile,CFile:
:
modeCreate|CFile:
:
modeWrite))
{
return;
}
CArchivear(&file,CArchive:
:
store);
Serialize(ar);
ar.Close();
file.Close();
return;
}
voidCPesMana:
:
load(constchar*pfile)
{
CFilefile;
if(!
file.Open(pfile,CFile:
:
modeRead))
{
return;
}
CArchivear(&file,CArchive:
:
load);
Serialize(ar);
ar.Close();
file.Close();
}
6、用MFCAppWizard创建一个名称为extendDllTest212的单文档应用程序,在视图类上方加入如下头文件:
#include"../extentDll212/PesMana.h"
为什么也有这种写法:
#include"..\WPCC_ExtenDLL215\PesMana.h"
7、ProjectSetting,打开ProjectSetting对话框,进行如下设置:
8、在视图类中添加如下成员变量:
CPesManam_pesMana;
intm_nNum;
9、在Resource视图下,在IDR_MAINFRAM中添加四个按钮,如下图:
10、在OnDraw()函数添加如下代码:
m_nNum=m_pesMana.m_Vpt.size();
for(inti=0;i{
pDC->MoveTo(m_pesMana.m_Vpt.at(i));
pDC->LineTo(m_pesMana.m_Vpt.at(i+1));
}
11、在视图类cpp文件中添加OnLButtonDown、OnSave、OnClear、OnLoad函数,如下进行编写,编译运行即可。
voidCExtendDllTest212View:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
m_pesMana.m_Vpt.push_back(point);
Invalidate();
CView:
:
OnLButtonDown(nFlags,point);
}
voidCExtendDllTest212View:
:
OnSave()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.save("点信息.txt");
}
voidCExtendDllTest212View:
:
OnClear()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.m_Vpt.clear();
Invalidate();
}
voidCExtendDllTest212View:
:
OnLoad()
{
//TODO:
Addyourcommandhandlercodehere
m_pesMana.load("点信息.txt");
Invalidate();
}
四、COM组件
Com组件技术博大精深,老师推荐的文章有很好的论述,偶就不班门弄斧了,这里就直接作业了。
作业五(创建com组件并加载)
1、创建一个
,工程名字为com212;
2、在Class视图下,右键单击工程名,点击NewATLObject选项,在弹出的ATLObjectWizard选择SimpleObject,进行如下设置
3、在Class视图下,右键单击选择AddMethod如下:
4、在弹出的对话框中,进行如下设置:
5、如下图,双击sum函数并进行如下添加,注册组件即完成了com组件的创建。
STDMETHODIMPCaddInterface:
:
sum(longnum1,longnum2,long*ReturnValue)
{
//TODO:
Addyourimplementationcodehere
*ReturnV