MFC编程例子Word文档格式.docx
《MFC编程例子Word文档格式.docx》由会员分享,可在线阅读,更多相关《MFC编程例子Word文档格式.docx(30页珍藏版)》请在冰豆网上搜索。
ThefirstDialog"
同样操作在WM_RBUTTONDOWN消息,添加OnRButtonDown函数。
你点的是右键"
进行仿真即可。
例程3.添加图标
创建一个基于对话框的IconTest程序。
切换到资源视图。
右键点击Icon,选择添加资源,弹出下图。
选择导入,导入一个图标文件(.ico)文件,如下图。
点击CIconTestDlg类,找到CIconTestDlg函数。
找到下面的语句:
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
改为下面的语句:
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。
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:
voidCcalculatorDlg:
OnBnClickedAddbutton()
在此添加控件通知处理程序代码
/*INT_PTRnRes;
}*/
if(NULL==m_pTipDlg)
//创建非模态对话框实例
m_pTipDlg=newCTipDlg();
m_pTipDlg->
Create(IDD_TIP_DIALOG,this);
//显示非模态对话框
m_pTipDlg->
ShowWindow(SW_SHOW);
//将各控件中的数据保存到相应的变量
UpdateData(TRUE);
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(&
//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<
m_iYWord;
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++)
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));
oldpen=dc.SelectObject(&
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;
m_iXWord;
if(i>
dc.MoveTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom);
dc.LineTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.top);
for(intj=0;
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.MoveTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom);
dc.LineTo(rcClient.left+i*rcClient.Width()/m_iXWord,rcClient.bottom-10);
例程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));
SetBkMode(TRANSPARENT);
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);
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;
pDC->
SetStretchBltMode(COLORONCOLOR);
//这个模式不设置的话会导致图片严重失真
StretchBlt(0,0,rect.Width(),rect.Height(),
&
memDc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
memDc.SelectObject(pOldBitmap);
memDc.DeleteDC();
//删除DC
bm.Delete