MFC编程例子.docx
- 文档编号:8552549
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:30
- 大小:2.84MB
MFC编程例子.docx
《MFC编程例子.docx》由会员分享,可在线阅读,更多相关《MFC编程例子.docx(30页珍藏版)》请在冰豆网上搜索。
MFC编程例子
例程1.MFChello
步骤1.
选择新建-项目,打开后出现如果1所示对话框。
选择VC++中的智能设备,在右边选择MFC智能设备应用程序。
在下方的名称中输入MFChello,点击确定。
步骤2.
点击下一步
步骤3.
将Mini2440-CE6-SDK移到右边,点击下一步。
步骤4.
在应用程序类型选择基于对话框,直接点击完成。
步骤5.
选择类视图,点击CMFChelloApp,在下方可以看到InitInstance(void)函数,双击该函数。
步骤6
在BOOLCMFChelloApp:
:
InitInstance()添加如下代码
AfxEnableControlContainer();//调用此函数的目的是为了使程序支持包含OLE控件
MessageBox(NULL,_T("一个简单的MFC程序"),_T("你好"),MB_OK);//谈出对话框
例程2.鼠标测试程序
同例程1一样,建立一个基于对话框的MouseTest程序。
在右边的对话框编辑器中选择StaticText,添加到对话框中一个静态文本,然后更改右下角的静态文本的属性,Caption改为提示:
点一下鼠标右键或左键,ID改为IDC_STATIC
点击对话框,在右下角点击消息按钮,出现下图。
找到WM_LBUTTONDOWN消息,添加OnLButtonDown函数。
在函数中添加代码如下
MessageBox(NULL,_T("你点的是左键"),_T("ThefirstDialog"),MB_OK);
同样操作在WM_RBUTTONDOWN消息,添加OnRButtonDown函数。
在函数中添加代码如下
MessageBox(NULL,_T("你点的是右键"),_T("ThefirstDialog"),MB_OK);
进行仿真即可。
例程3.添加图标
创建一个基于对话框的IconTest程序。
切换到资源视图。
右键点击Icon,选择添加资源,弹出下图。
选择导入,导入一个图标文件(.ico)文件,如下图。
点击CIconTestDlg类,找到CIconTestDlg函数。
找到下面的语句:
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
改为下面的语句:
m_hIcon=AfxGetApp()->LoadIcon(IDI_ICON1);
点击仿真可看到对话框左上角的图标已经改变。
例程4.简单计算机1.0
创建基于对话框的calculator 项目。
点击Dialog,添加如下控件。
在加数编辑框右击添加变量。
变量名称是m_editSummand,变量类型是double,类别为value。
同样操作添加被加数编辑框变量。
变量名称是m_editAddend,变量类型是double,类别为value。
和编辑框变量。
变量名称是m_editSum,变量类型是double,类别为value。
将计算按钮的ID设为IDC_ADDBUTTON。
双击该按钮,进入voidCcalculatorDlg:
:
OnBnClickedAddbutton()函数。
添加如下代码:
UpdateData(TRUE);
m_editSum=m_editSummand+m_editAddend;
UpdateData(FALSE);
将退出按钮的ID设为IDC_QUT。
双击该按钮,进入voidCcalculatorDlg:
:
OnBnClickedQut()函数。
添加如下代码:
ShowWindow(SW_HIDE);//将非模态对话框隐藏
仿真即可。
在这个程序中对话框基本是由MFC自己创立的,下面说一下它是在哪里弹出的。
打开calculator.cpp文件,可以看到有个InitInstance()函数。
对话框就是在这里产生的。
下面是这段代码的注释程序。
BOOLCcalculatorApp:
:
InitInstance()
{
//标准初始化
//如果未使用这些功能并希望减小
//最终可执行文件的大小,则应移除下列
//不需要的特定初始化例程
//更改用于存储设置的注册表项
//TODO:
应适当修改该字符串,
//例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CcalculatorDlgdlg;//定义对话框类CcalculatorDlg的对象
m_pMainWnd=&dlg;//将dlg设为主窗口
INT_PTRnResponse=dlg.DoModal();//弹出对话dlg,并将DoModal函数的返回值(退出时点击
//按钮的ID)赋值给nResponse
if(nResponse==IDOK)//判断返回值是否为OK按钮
{
//TODO:
在此处放置处理何时用“确定”来关闭
//对话框的代码
}
Elseif(nResponse==IDCANCEL)//判断返回值是否为Cancel按钮
//由于对话框已关闭,所以将返回FALSE以便退出应用程序,
//而不是启动应用程序的消息泵。
returnFALSE;
}
弹出对话框比较关键的一个函数,就是对话框类的DoModal()函数。
CDialog:
:
DoModal()函数的原型为:
VirtualINT_PTRDoModal();
返回值:
整数值,指定了传递给CDialog:
:
EndDialog(该函数用于关闭对话框)的nResult函数值。
如果函数不能创建对话框,则返回-1;如果出现其他错误,则返回IDABORT。
调用了它对话框就会弹出,返回值是退出对话框时所点的按钮的ID,比如,我们点了“退出”按钮,那么DoModal返回值为IDCANCEL。
添加一个新的对话框并弹出它
切换到资源视图,右击Dialog,选择插入Dialog,将新插入的Dialog的ID改为IDD_TIP_DIALOG,添加一个静态文本。
如下图
右击该对话框,选择添加类,类的名字为CTipDlg,点OK。
在calculator.cpp中添加头文件:
#include“TipDlg.h”.
修改voidCcalculatorDlg:
:
OnBnClickedAddbutton(),代码如下
INT_PTRnRes;//用于保存DoModal函数的返回值
CTipDlgtipDlg;//构造对话框类CTipDlg的实例
nRes=tipDlg.DoModal();//弹出对话框
if(IDCANCEL==nRes)//判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续
{
return;
}
仿真即可。
创建及显示非模态对话框的步骤
1.在calculatorDlg.h中包含CTipDlg类型的指针成员变量。
详细操作方法是,在calculatorDlg.cpp中删除之前添加的#include”TipDlg.h”,而在calculatorDlg.h中添加#include”TipDlg.h”,这是因为我们需要在calculatorDlg.h中定义CTipDlg类型的指针变量,所以要先包含它的头文件,然后再calculatorDlg.h中为CcalculatorDlg类添加private成员变量CTipDlg*m_pTipDlg.
2.在CcalculatorDlg类的构造函数中初始化成员变量m_pTipDlg。
如果cpp文件中函数太多,我们可以在ClassView上半个视图中找到CcalculatorDlg类,再在下半个视图中找到其构造函数双击,中间客户区域即可马上切换到构造函数的实现处。
在构造函数中添加m_pTipDlg=NULL;。
在任何指针变量使用前都初始化,可以避免因误访问重要内存地址而破坏此地址的数据。
3.将上面添加模态对话框显示代码注释掉。
修改CcalculatorDlg:
:
OnBnClickedAddbutton()函数。
voidCcalculatorDlg:
:
OnBnClickedAddbutton()
{
//TODO:
在此添加控件通知处理程序代码
/*INT_PTRnRes;//用于保存DoModal函数的返回值
CTipDlgtipDlg;//构造对话框类CTipDlg的实例
nRes=tipDlg.DoModal();//弹出对话框
if(IDCANCEL==nRes)//判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续
{
return;
}*/
if(NULL==m_pTipDlg)
{
//创建非模态对话框实例
m_pTipDlg=newCTipDlg();
m_pTipDlg->Create(IDD_TIP_DIALOG,this);
}
//显示非模态对话框
m_pTipDlg->ShowWindow(SW_SHOW);
//将各控件中的数据保存到相应的变量
UpdateData(TRUE);
m_editSum=m_editSummand+m_editAddend;
UpdateData(FALSE);
}
4.因为此非模态对话框实例是动态创建的,所以需要手动删除此动态对象来销毁对话框。
我们在CcalculatorDlg类的析构函数中添加删除代码,但是MFC并没有自动给出析构函数,这时需要手动添加,在对话框对象析构时就会调用我们自定义的析构函数。
在CcalculatorDlg.h文件中为CcalculatorDlg添加析构函数声明:
~CcalculatorDlg();然后在CcalculatorDlg.cpp文件中添加析构函数的实现。
例程5.屏幕全屏显示
//得到屏幕大小
m_nMaxX=GetSystemMetrics(SM_CXSCREEN);
m_nMaxY=GetSystemMetrics(SM_CYSCREEN);
//全屏显示
CRectrcTemp;
rcTemp.BottomRight()=CPoint(m_nMaxX,m_nMaxY);
rcTemp.TopLeft()=CPoint(0,0);
MoveWindow(&rcTemp);
例程6.WINCE添加菜单栏到对话框中
在对话框初始化程序中加入以下变量,其中IDR_MENU为菜单栏的ID。
//将菜单与界面关联起来
HINSTANCEhInst=AfxGetResourceHandle();
HWNDhwndCB=CommandBar_Create(hInst,this->GetSafeHwnd(),1);
if(hwndCB==NULL)
{
TRACE0("FailedtocreateCommandBar/n");
}
if(!
CommandBar_InsertMenubar(hwndCB,hInst,IDR_MENU,3))
{
TRACE0("FailedInsertMenutoCommandBar/n");
}
例程7.如何更改对话框的背景
在对话框中添加全局变量m_brush,在构造对话框函数中创建画刷。
在对话框中添加WM_CTRCOLOR事件。
将函数的返回值该为m_brush即可。
例程8.绘制坐标轴以及网格
voidCnewtableDlg:
:
tablebk()
{
CPaintDCdc(this);
INTi(0);
INTiXStart(0),iYStart(0),iXEnd(0),iYEnd(0);
INTiChartWidth(0),iChartHeight(0);
CPenextPenGrid;
CPenintPenGrid;
//CPen*pOldPen;
CRectrcGrid;
CRectrcClient(10,10,m_nMaxX-10,m_nMaxY/3*2);
CPensolidpen(PS_SOLID,1,RGB(0,0,0));
CPen*oldpen=dc.SelectObject(&solidpen);
dc.MoveTo(rcClient.left,rcClient.top);
dc.LineTo(rcClient.left,rcClient.bottom);
//dc.LineTo(rcClient.left,rcClient.top);
//dc.LineTo(rcClient.right-1,rcClient.top);
//dc.LineTo(rcClient.right-1,rcClient.bottom-1);
dc.LineTo(rcClient.right,rcClient.bottom-1);
dc.SelectObject(oldpen);
floatm_fYFirstValue=0.0f;
floatm_fYEndValue=500.0f;
intm_iXWord=10;
intm_iYWord=5;
CPenpen(PS_DOT,1,RGB(255,0,0));
CPenpens(PS_SOLID,1,RGB(0,0,0));
//CPen*odpen=dc.SelectObject(&solidpen);
//dc.MoveTo(rcClient.left,rcClient.Height()/2);
//dc.LineTo(rcClient.right,rcClient.Height()/2);
//CPenpens(PS_SOLID,1,RGB(0,0,0));
//绘制网格
for(inti=0;i { CStringstr; //str.Format("%d",i); //dc.ExtTextOutW(rcClient.left+5,rcClient.bottom-(i*rcClient.Height())/m_iYWord,str); //dc.MoveTo(rcClient.left,rcClient.bottom-(i*rcClient.Height())/m_iYWord); //dc.LineTo(rcClient.left+5,rcClient.bottom-(i*rcClient.Height())/m_iYWord); //画虚线 if(i>0) { oldpen=dc.SelectObject(&pen); dc.MoveTo(rcClient.left+5,rcClient.bottom-(i*rcClient.Height())/m_iYWord); dc.LineTo(rcClient.right,rcClient.bottom-(i*rcClient.Height())/m_iYWord); dc.SelectObject(oldpen); } for(intj=0;j<5;j++) { oldpen=dc.SelectObject(&pens); dc.MoveTo(rcClient.left,rcClient.bottom-(i*rcClient.Height())/m_iYWord-(j*rcClient.Height())/(m_iYWord*5)); dc.LineTo(rcClient.left+5,rcClient.bottom-(i*rcClient.Height())/m_iYWord-(j*rcClient.Height())/(m_iYWord*5)); dc.SelectObject(oldpen); } oldpen=dc.SelectObject(&pens); dc.MoveTo(rcClient.left,rcClient.bottom-(i*rcClient.Height())/m_iYWord); dc.LineTo(rcClient.left+10,rcClient.bottom-(i*rcClient.Height())/m_iYWord); dc.SelectObject(oldpen); } for(inti=0;i { //画虚线 if(i>0) { oldpen=dc.SelectObject(&pen); dc.MoveTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom); dc.LineTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.top); dc.SelectObject(oldpen); } for(intj=0;j<5;j++) { oldpen=dc.SelectObject(&pens); dc.MoveTo(rcClient.left+i*rcClient.Width()/m_iXWord+j*rcClient.Width()/(m_iXWord*5),rcClient.bottom); dc.LineTo(rcClient.left+i*rcClient.Width()/m_iXWord+j*rcClient.Width()/(m_iXWord*5),rcClient.bottom-5); dc.SelectObject(oldpen); } oldpen=dc.SelectObject(&pens); dc.MoveTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom); dc.LineTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom-10); dc.SelectObject(oldpen); } } 例程9.如何改变输出文本的大小、颜色以及背景 voidCchart: : DrawTimeScale(CDC*pDC,intm_nMaxX,intm_nMaxY) { char*a="宋体"; LPCTSTRlpb=(LPCTSTR)(LPCTSTR)a; CFontfont; font.CreatePointFont(100,lpb); CFont*def_font=pDC->SelectObject(&font); pDC->SetTextColor(RGB(255,255,0)); pDC->SetBkMode(TRANSPARENT); pDC->ExtTextOutW(rcClient.right-10,rcClient.bottom-20,ETO_CLIPPED,NULL,_T("时间"),NULL); } 例程10.避免闪烁的方法(OnEraseBkgnd) 在图形图象处理编程过程中,双缓冲是一种基本的技术。 我们知道,如果窗体在响应WM_PAINT消息的时候要进行复杂的图形处理,那么窗体在重绘时由于过频的刷新而引起闪烁现象。 解决这一问题的有效方法就是双缓冲技术。 因为窗体在刷新时,总要有一个擦除原来图象的过程OnEraseBkgnd,它利用背景色填充窗体绘图区,然后在调用新的绘图代码进行重绘,这样一擦一写造成了图象颜色的反差。 当WM_PAINT的响应很频繁的时候,这种反差也就越发明显。 于是我们就看到了闪烁现象。 我们会很自然的想到,避免背景色的填充是最直接的办法。 但是那样的话,窗体上会变的一团糟。 因为每次绘制图象的时候都没有将原来的图象清除,造成了图象的残留,于是窗体重绘时,画面往往会变的乱七八糟。 所以单纯的禁止背景重绘是不够的。 我们还要进行重新绘图,但要求速度很快,于是我们想到了使用BitBlt函数。 它可以支持图形块的复制,速度很快。 我们可以先在内存中作图,然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消除了闪烁。 以上也就是双缓冲绘图的基本的思路。 先按普通做图的方法进行编程。 即在视类的OnDraw函数中添加绘图代码。 在此我们绘制若干同心圆,代码如下: CBCDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); CPointptCenter; CRectrect,ellipseRect; GetClientRect(&rect); ptCenter=rect.CenterPoint(); for(inti=20;i>0;i--) { ellipseRect.SetRect(ptCenter,ptCenter); ellipseRect.InflateRect(i*10,i*10); pDC->Ellipse(ellipseRect); } 编译运行程序,尝试改变窗口大小,可以发现闪烁现象。 在双缓冲方法中,首先要做的是屏蔽背景刷新。 背景刷新其实是在响应WM_ERASEBKGND消息。 我们在视类中添加对这个消息的响应,可以看到缺 省的代码如下: BOOLCMYView: : OnEraseBkgnd(CDC*pDC) { returnCView: : OnEraseBkgnd(pDC); } 是调用父类的OnEraseBkgnd函数,我们屏蔽此调用,只须直接returnTRUE;即可。 下面是内存缓冲作图的步骤. CBitmapbit; bit.LoadBitmapA(IDB_BITMAP1); BITMAPbm; bit.GetBitmap(&bm); CDCmemDc; memDc.CreateCompatibleDC(pDC); CBitmap*pOldBitmap=memDc.SelectObject(&bit); CRectrect; GetClientRect(&rect); pDC->SetStretchBltMode(COLORONCOLOR);//这个模式不设置的话会导致图片严重失真 pDC->StretchBlt(0,0,rect.Width(),rect.Height(), &memDc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); memDc.SelectObject(pOldBitmap); memDc.DeleteDC(); //删除DC bm.Delete
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 编程 例子