郑州大学地理信息系统 MFC上机练习.docx
《郑州大学地理信息系统 MFC上机练习.docx》由会员分享,可在线阅读,更多相关《郑州大学地理信息系统 MFC上机练习.docx(19页珍藏版)》请在冰点文库上搜索。
![郑州大学地理信息系统 MFC上机练习.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/35bfb074-7e66-49a6-8ee3-482f120546e0/35bfb074-7e66-49a6-8ee3-482f120546e01.gif)
郑州大学地理信息系统MFC上机练习
1、ActiveX控件
步骤:
1、新建—》MFCActiveXControlWizard—》功成名为HYK_ActiveX.点击bulid,系统会生成三个类。
类1:
CHYK_ActiveXApp从CwinApp派生而来,相当于单文档的应用程序类。
类2:
CHYK_ActiveXCtrl相当于单文档应用程序类的view类,所有关于窗口的操作都在这个类中完成。
类3:
:
CHYK_ActiveXPropPage用来显示自定义控件的属性,类似与对话框类。
2、在CHYK_ActiveXCtrl类中添加绘图相关的代码,添加在HYK_ActiveXCtl.cpp的onDraw()函数里(在下面)。
3、添加鼠标左键响应函数。
打开类向导在CHYK_ActiveXCtrl类中添加WM_LBUTTONDOWN消息映射。
在HYK_ActiveXCtl.cpp的OnLButtonDown函数里添加画椭圆代码。
4、添加用户自定义函数MyAdd,实现两数相加。
打开类向导,选中AutoMation选项卡,选择AddMethod。
完善函数信息函数名MyAdd返回值long,在prameterlist填写函数参数n0long、n1long;在HYK_ActiveXCtl.cpp的MyAdd()函数里完善代码。
这样控件就做好了,有时win7/win8不能自动注册控件,需要手动注册
5、建立名为HYK_ActiveX_Test的exe测试程序。
把控件添加到测试工程里。
点击工程-》增加到工程-》ComponentandControlsCallery打开RegisteredActiveXControls文件夹找到对应的控件把控件.lnk去掉。
点击insert,系统会在测试程序添加两个文件一个是HYK_ActiveX.cpp一个是HYK_ActiveX.h.(ps:
如果找不到RegisteredActiveXControls文件夹说明你登陆的账户不是超级管理员,单击计算机右键,管理,本地用户和组,用户,Administor。
勾选掉“账户已禁用”即可赋予当前管理员最高权限)
6、用类向导在测试程序view.cpp文件下添加几个函数
CHYK_ActiveX_Test1View:
:
OnCreate下添加代码创建于客户区大小相同的控件
CHYK_ActiveX_Test1View:
:
OnSize下添加添加代码调整控件大小
CHYK_ActiveX_Test1View:
:
OnLButtonDown调用MyAdd函数
CHYK_ActiveX_Test1View:
:
Onadd()菜单栏add按钮调用MyAdd函数
CHYK_ActiveX_Test1View:
:
OnDestroy()删除控件
具体代码在下方,重点下面写的比较详细
HYK_ActiveXCtl.cpp
(控件部分代码)
voidHYK_ActiveXCtrl:
:
OnDraw(CDC*pdc,constCRect&rcBounds,constCRect&rcInvalid)
{
pdc->FillRect(rcBounds,CBrush:
:
FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
pdc->TextOut(10,10,"我是控件!
");;
}
/******************************************************************************
通过CDC对象的成员函数进行所有的绘图。
成员函数:
Ellipse(intx1,inty1,intx2,inty2);绘制椭圆。
参数x1指定椭圆的外接矩形左上角的x坐标;参数y1指定椭圆的外接矩形左上角的y坐标;参数x2指定椭圆的外接矩形右下角的x坐标;参数y2指定椭圆的外接矩形右下角的y坐标;
TextOut(intx,inty,constCString&str);使用当前选择的字体在指定位置输出文本。
FillRect()该函数用指定的画刷填充矩形.
***************************************************************************/
voidHYK_ActiveXCtrl:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
CClientDCdc(this);
//CClientDC:
(继承于CDC类)用于客户区的输出,与特定窗口关联,可以让开
//发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC。
intx=point.x;
inty=point.y;
dc.Ellipse(x-10,y-10,x+10,y+10);
COleControl:
:
OnLButtonDown(nFlags,point);
}
longHYK_ActiveXCtrl:
:
Add(longn0,longn1)
{
returnn0+n1;
}
测试程序代码
HYK_ActiveX_TestView.h
#include"HYK_ActiveX.h"
classHYK_ActiveX_TestView:
publicCView
{
public:
CTempX*m_pTempX;
}
HYK_ActiveX_Test_View.cpp
voidCHYK_ActiveX_TestView:
:
OnDraw(CDC*pDC)
{
CRectrC;GetClientRect(&rC);
pDC->FillSolidRect(rC,COLORREF(RGB(255,255,0)));
/*GetClientRect(&rC)该函数获取窗口客户区的坐标。
客户区坐标指定客户区的左上角和右下角。
由于客户区坐标是相对窗口客户区的左上角而言的,因此左上角坐标为(0,0)
FillSolidRect与CDC:
:
FillRect类似,FillSolidRect只能使用固体色(由COLORREF参数决定)。
但FillRect带有画刷,因此可以为矩形填充固体色、抖动色、阴影或使用调色板。
FillRect通常比FillSolidRect慢。
*/
}
intCHYK_ActiveX_TestView:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CView:
:
OnCreate(lpCreateStruct)==-1)
return-1;
m_pTempX=newCTempX();
m_pTempX->Create(_T("abcd"),WS_CHILD|WS_VISIBLE,CRect(10,10,100,100),this,2000);
//实例化控件
return0;
}
voidCHYK_ActiveX_TestView:
:
OnDestroy()
{
CView:
:
OnDestroy();
deletem_pTempX;
}
voidCHYK_ActiveX_TestView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
if(m_pTempX)
{
longnResult=m_pTempX->Add(1,2);
}
CHYK_ActiveX_TestView:
:
OnLButtonDown(nFlags,point);
}
voidCHYK_ActiveX_TestView:
:
OnSize(UINTnType,intcx,intcy)
{
CHYK_ActiveX_TestView:
:
OnSize(nType,cx,cy);
//OnSize(nType,cx,cy)在窗口的大小更改后,框架调用该成员函数。
//nType:
指定请求的调整大小的类型。
//cx指定工作区的新的宽度
//cy指定工作区的新的高度。
if(m_pTempX&&m_pTempX->GetSafeHwnd()!
=0)
{//MoveWindow()用来改变控件的位置和大小
m_pTempX->MoveWindow(0,0,cx,cy);
//创建与客户区大小相同的控件
}
}
voidCHYK_ActiveX_TestView:
:
OnAdd()
{
if(m_pTempX)
{
longnResult=m_pTempX->Add(1,2);
}
}
2、扩展动态库ExtendDll(隐式链接)
步骤:
1、使用向导创建一个扩展库。
新建、MFCAppWizard(dll)工程名为HYK_ExtendDll
2、在预编译头文件里定义一个宏#defineHANYAKUI
3、插入、新建类窗体。
选择GenericClass类名为CPointEx。
新建一个头文件到当前工程,名为Export.h
4、在CpointEx.h中添加代码,在预编译头文件里添加#include“Export.h”
5、在Export.h中添加代码(这里是重点)
以上为dll部分
6、建立测试程序步骤………
Export.h
#ifndefMY_EXTERN_DLL
#defineMY_EXTERN_DLL
#ifdefHANYAKUI
#definehan_declspec(dllexport)
#else
#definehan_declspec(dllimport)
#pragmacomment(lib,"..\\HYK_ExtendDll\\Debug\\HYK_ExtendDll.lib")
//可以让链接器在链接时查找这个指定的库
#endif
#include"PointEx.h"
#endif
/*在所有的预处理指令中,#Pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。
依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
*/
StdAfx.h
#defineHANYAKUI
#include"Export.h"
PointEX.h
classhanCPointEX
{
public:
CPointEX();
virtual~CPointEX();
intx,y;
};
HYK_ExternDll_Test\StdAfx.h
#include"..\\HYK_ExtendDll\\Export.h"
TestView.h
#include"vector"
usingnamespacestd;
classCHYK_ExternDll_TestView:
publicCView
{
vectorm_vPt;
}
TestView.cpp
voidCHYK_ExternDll_TestView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
CPointEXptT;
ptT.x=point.x;
ptT.y=point.y;
m_vPt.push_back(ptT);
CView:
:
OnLButtonDown(nFlags,point);
}
copy.\Debug\HYK_ExternDll_Test.exe..\Bin
copy.\Debug\HYK_ExtendDll.dll..\Bin
3、常规动态库RegularDll(动态加载)
可以在需要的时候动态加载动态链接库,隐式链接在程序启动时所有dll都被加载,占内存.
步骤:
1、使用向导创建一个扩展库。
新建、MFCAppWizard(dll)工程名为HYK_RegularDll
2、创建以个名为Math.cpp文件添加代码声明一个AddEx函数
3、在模块定义文件.def文件下指定AddEx为导出函数并其编号
以上为常规库的定义,把常规库的.lib和.dll拷贝到测试工程目录下
4建立测试程序在鼠标左键响应函数添加代码(重点下面写的比较详细!
)
CHYK_RegularDLL\Math.cpp
#include"StdAfx.h"
intMyAdd(intn0,intn1)
{
returnn0+n1;
}
CHYK_RegularDLL.def
;DataType.def:
DeclaresthemoduleparametersfortheDLL.
;LIBRARY"DataType"
DESCRIPTION'DataTypeWindowsDynamicLinkLibrary'
EXPORTS
;Explicitexportscangohere
MyAdd@1
CHYK_RegularDLL_TestView.cpp
intAddEx(intn0,intn1);
voidCHYK_RegularDLL_TestView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//1装载动态库LoadLibrary返回dll的句柄
HINSTANCEhIns=:
:
LoadLibrary("DataTypeD.dll");
if(hIns==0)return;
//2GetProcAddress获取常规库导出函数地址
typedefint(abcd)(int,int);
abcd*pProc=(abcd*):
:
GetProcAddress(hIns,"AddEx");
if(pProc==0)return;
//3使dll导出的用函数
intnResult=(*pProc)(1,2);
//4释放动态库
:
:
FreeLibrary(hIns);
CView:
:
OnLButtonDown(nFlags,point);
}
4、对话框数据的交换机制
voidCMyEditBoxDlg:
:
OnSum3()
{
UpdateData(TRUE);
m_num9=m_num7+m_num8;
UpdateData(FALSE);
}
voidCMyEditBoxDlg:
:
OnSum4()
{
intnum1,num2,num3;
charch10[10],ch11[10],ch12[10];
m_edit10.GetWindowText(ch10,10);
m_edit11.GetWindowText(ch11,10);
num3=atoi(ch10)+atoi(ch11);
itoa(num3,ch12,10);
m_edit12.SetWindowText(ch12);
}
5、Com组件
说明:
设计一个Com组件很困难,VC++提供了ActiveX模板库ATL。
使用ATL可以很方便地设计各种Com组件
步骤:
1、创建一个组件工程。
新建、ATLComAppWizard工程名为TempMath
2、插入com对象。
选择菜单insert、newATLObject选项。
选择
SimpleObject点击Next
3、在出现的ATLObjectWizard属性对话框的shortname栏中添加组件名MathEx,其余属性系统自动添加。
4、在接口中加入方法。
在ClassView选项卡中选中接口ImathEx单击右键。
在弹出的窗口中填写方法名Add参数为[in]longn0,[in]longn1,[out]long*n01
5、实现方法。
在MathEx.cpp中完善Add函数。
组件编写完毕。
6、编写测试程序。
新建一个test.exe工程添加鼠标左键响应函数。
第一步导入类型库,#import“路径\.tlb”,点击bulid。
这时会在测试程序的Debug目录下生成**.tlh
7、包括代理头文件#include“Debug\**.tlh”
8、创建智能指针……略(重点下面写的比较详细)
AtlCom\TempMath\TempMath.dsp
MathEx.h
classATL_NO_VTABLECMathEx:
{
public:
STDMETHOD(Add)(/*[in]*/longn0,/*[in]*/longn1,/*[out]*/long*n01);
};
MathEx.cpp
STDMETHODIMPCMathEx:
:
Add(longn0,longn1,long*n01)
{
*n01=n1+n0;
returnS_OK;
}
AtlCom\Test\TestView.cpp
//第一步导入类型库
#import"F:
\数据库\\AtlCom\TempMath\tempmath.tlb"
//第二步包括代理头文件
#include"Debug/TempMath.tlh"
voidCTestView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
:
:
CoInitialize(0);//通常在构造函数里面初始化
//第三步创建智能指针
TEMPMATHLib:
:
IMathExPtrabc;
//ProgId为TempMath.MathEx.1
abc.CreateInstance("TempMath.MathEx.1");
//用.创建实例
longnResult;
abc->Add(1,2,&nResult);
//用->调用函数
:
:
CoUninitialize();//通常在析构函数里面注销
CView:
:
OnLButtonDown(nFlags,point);
}
6、序列化
步骤比较简单这里不再介绍,重点介绍及各类
FILE类
格式
HYK_SerializeView.h
#include"vector"
usingnamespacestd;
classCPointEx
{
public:
intx,y;
voidSave(FILE*fp)
{
fprintf(fp,"%d,%d\n",x,y);//保存点坐标
}
voidSerialize(CArchive&ar)
{
if(ar.IsStoring())//判断是否为写操作
{
ar<ar<}
Else//为读操作
{
ar>>x;
ar>>y;
}
}
};
CArchive&operator<<(CArchive&ar,CPointEx&t);
CArchive&operator>>(CArchive&ar,CPointEx&t);
classCHYK_SerializeView:
publicCView
{
public:
vectorm_vpT;
}:
HYK_SerializeView.cpp
voidCHYK_SerializeView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
//捕获鼠标焦点位置信息将坐标存入数组
CPointExptT;
ptT.x=point.x;
ptT.y=point.y;
m_vpT.push_back(ptT);
Invalidate();
CView:
:
OnLButtonDown(nFlags,point);
}
voidCHYK_SerializeView:
:
OnTextWrite()
{
//将数组中的点信息存入txt文件中
FILE*fp=fopen("D:
\\data.txt","wt");
if(fp==0)
{
return;
}
intnCount=m_vpT.size();
fprintf(fp,"%d\n",nCount);//将点的个数存入文件
for(inti=0;i{
CPointEx&ptEx=m_vpT[i];//将数组中的点信息依次读出
ptEx.Save(fp);//调用CPointEx的Save方法吧点信息存入文件
}
fclose(fp);
}
voidCHYK_SerializeView:
:
OnTextRead()
{
//从文件中读出点信息存入数组
FILE*fp=fopen("D:
\\data.txt","rt");
if(fp==0)
{
return;
}
intnCount;
fscanf(fp,"%d",&nCount);
for(inti=0;i{
CPointExptEx;
fscanf(fp,"%d,%d",&ptEx.x,&ptEx.y);
//将点信息读出赋给CPointEx的实例再存入数组
m_vpT.push_back(ptEx);
}
fclose(fp);
Invalidate();
}
CArchive&operator<<(CArchive&ar,CPointEx&t)
{
t.Serialize(ar);
returnar;
}
CArchive&operator>>(CArchive&ar,CPointEx&t)
{
t.Serialize(ar);
returnar;
}
voidCHYK_SerializeView:
:
OnBinWrite()
{
/*********************************************************************/
/*文件打开模式可组合使用,用“|”隔开,常用的有以下几种:
CFile:
:
modeCreate:
以新建方式打开,如果文件不存在,新建;如果文件已存在,
把该文件长度置零,即清除文件原有内容。
CFile:
:
modeNoTruncate:
以追加方式打开,如果文件存在,打开并且不将文件长
度置零,如果文件不存在,会抛出异常。
一般与CFile:
:
modeCreate一起使