Visual C++面向对象与可视化程序设计(第5版)课件 -05-资源-sdk_第1页
Visual C++面向对象与可视化程序设计(第5版)课件 -05-资源-sdk_第2页
Visual C++面向对象与可视化程序设计(第5版)课件 -05-资源-sdk_第3页
Visual C++面向对象与可视化程序设计(第5版)课件 -05-资源-sdk_第4页
Visual C++面向对象与可视化程序设计(第5版)课件 -05-资源-sdk_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1第5章

资源在Windows编程中的应用加速键对话框位图资源光标菜单工具条字符串

25.1菜单和加速键资源及其应用

菜单由以下组成部分:(1)

窗口主菜单条(2)

下拉式菜单框(3)

菜单项热键标识(4)

菜单项加速键标识(5)

菜单项分隔线5.1.1几个常用的菜单操作函数定义菜单的时候,我们可以通过可视化界面进行操作,关键是创建好菜单及菜单项后,该如何进行操作。46.1.2操作菜单项

1.禁止或激活菜单项

BOOLEnableMenuItem(UlNTwIDEnableItem,//被禁止或激活的菜单项标识

UINTdwEnable)据dwEnable的取值,可为菜单项的ID值,也为该菜单项在菜单中位置

标识 说明MF_BYCOMMAND以ID值标识菜单项MF_ENABLED 激活菜单项MF_BYPOSITION 表明以位置标识菜单项MF_GRAYED 禁止菜单项并使其变灰显示MF_DISABLED 禁止菜单项设置或取消选中标志

在菜单旁显示一个选中标志如打上“√”标记,以表明用户选择了该项。可调用函数CheckMenuItem设置或取消选中标志,该函数的原型为:hmennu->CheckMenuItem(UINTwIDCheckItem, //设置项的菜单IDUINTdwCheck //dwCheck为操作标识)标识 说明MF_CHECKED 添加选中标志MF_UNCHECKED 删除选中标志MF_BYCOMMAND以ID值标识菜单项MF_BYPOSITION 表明以位置标识菜单项63.增加菜单项(1)在菜单的尾部增加菜单项,用AppendMenu函数:AppendMenu

(HMENUhmenu //动态需要增加菜单项的菜单句柄

UINTdwFlags,//新加入的菜单项类型标识或其他状态信息

UINTdwIDNewItem, //新加入菜单项的ID标识

LPCTSTRlpNewItem//新加入的菜单项内容,取决于dwFlags

)例如在弹出式菜单“文件”的末尾增加一项“关于”的形式如下:AppendMenu(hmenu,MF_ENABLED,IDM_ABOUT,“关于(&A)”)关于dwIDNewItem:一般情况下是插入项的ID值;如果加入的是一个弹出式菜单,则为弹出式菜单的句柄;lpNewItem取决于dwFlags参数。如果dwFlags为MF_BITMAP,则该参数包含一个位图句柄。7(2)用InsertMenu在菜单中插入新的菜单项BOOLInsertMenu(HMENUhmenu, //菜单句柄UINTwPosition, //指定新菜单项插入的位置UINTdwFlag,//新加入的菜单项的信息及对wPosition的解释PTRdwIDNweItem, //新加入的菜单项的ID标识LPCTSTRlpNewItem //新插入的菜单项的内容)如果dwFlag为MF_BYCOMMAND,则该参数为插入位置的下一个菜单项的ID值;如果dwFlag为MF_BYPOSITION,则该参数为插入的位置号,菜单的第一个菜单项的位置号为0。如果加入的是一个弹出式菜单,则该参数为弹出式菜单的句柄;lpNewItem取决于dwFlag参数,如果dwFlag为MF_BITMAP,则该参数包含一个位图句柄。

如在弹出式菜单“文件”的“退出”(ID为IDM_EXIT)项之前加入新的菜单项“打印”(ID为IDM_PRINT)的语句如下;InsertMenu(hmenu,IDM_EXIT,MF_BYCOMMAND|MF_ENABLED,IDM_PRINT,L"打印(&P)");94.删除菜单项函数DeleteMenu,该函数的原型为:BOOLDeleteMenu(HMENUhmenu, UINTwPosition, //指定要删除的菜单项的位置UINTdwFlag //对wPosition的解释)

对于wPosition,由参数dwFlag解释其意义,如果dwFlag为MF_BYCOMMAND,则该参数为菜单项的ID值;如果dwFlag为MF_BYPOSITION,则该参数为菜单项的位置号。

例如,删除弹出式“文件”菜单中的“另存为”项的形式如下:

DeleteMenu(hmenu,IDM_SAVEAS,MF_BYCOMMAND)

值得注意的是,如果菜单项含有弹出式菜单,则删除该菜单项时该弹出式菜单也同时被删除。105.修改菜单项函数ModifyMenuBOOLModifyMenu(HMENUhmenu,UINTwPosition, //指定需修改的菜单项位置UINTdwFlag,PTRdwIDNweItem, //一般为修改后菜单项的标识LPCTSTRlpNewItem //一般为修改后的菜单项名)

对于wPosition,如果dwFlag为MF_BYCOMMAND,则该参数为菜单项的ID值;如果dwFlag为MF_BYPOSITION,则该参数为菜单项的位置号。

例如修改弹出式菜单“文件”中“打开”项为“加载”项的语句如下:

ModifyMenu(hmenu,IDM_OPEN,MF_BYCOMMAND,IDM_LOAD,L"加载(&L)");应用文件除使用资源描述文件中定义的菜单外,还可以动态地创建菜单。116.动态地创建菜单

动态地创建菜单可以使系统资源更加节省,在应用程序中动态创建菜单分两个步骤:(1)调用函数CreateMenu创建空的弹出式菜单:HMENUCreateMenu(void)(2)调用函数AppendMenu、InsertMenu或InsertMenultem在该菜单中加入菜单项。

例如,在应用程序的窗口菜单中动态创建弹出式菜单“编辑”的过程如下:…HMENUhmenu,hPopupmenu; //主窗口菜单句柄和新创建的菜单句柄…//将弹出式菜单“编辑”加入到菜单中AppendMenu(hmenu,MF_POPUP,(UINT)hmenuPopup,"编辑(&E)");…

12POPUP语句定义弹出式菜单,其形式为:POPUP"菜单项名"[,选项];

在菜单项名中加入符号“&”,以定义热键定义弹出式菜单项“编辑”的形式如下:POPUP“编辑(&E)”;

选项 说明MENUBARBREAK 菜单项纵向分隔标志CHECKED 显示选中标志INACTIVE 禁止一个菜单项GRAYED 禁止并变灰显示13MENUITEM用于定义菜单项,其形式为:MENUITEM"菜单项名"菜单项标识(ID)[,选项]ID为菜单项标识,在WM_COMMAND消息中字参数wParam中包含选中菜单项的标识。每个菜单项的标识必须唯一,标识值常在头文件中定义。如:创建菜单中的水平分隔符:

MENUITEMSEPARATOR14该菜单在资源描述文件中的定义如下:#include<windows.h>#include"Menu.h"∥菜单定义My_menu

MENU

MOVEABLE

{POPUP"文件(&F)"

MENUITEM "新建(&N)", IDM_NEW MENUITEM "打开(&O)", IDM_OPEN MENUITEM "关闭(&C)", IDM_CLOSE MENUITEM "保存(&S)", IDM_SAVE MENUITEM "另存为(&A)", IDM_SAVEAS MENUITEM SEPARATOR MENUITEM “退出(&X)”, IDM_EXIT

}}15menu.h文件中定义了菜单项标识所对应的数值:……#defineIDM_NEW 10#defineIDM_OPEN 11#defineIDM_CLOSE 12#defineIDM_SAVE 13#defineIDM_SAVEAS 14#defineIDM_EXIT 15…165.1.2创建菜单资源实例

【例5-1】创建一个窗口菜单的构架,单击“创建统计计算菜单项”动态地创建“统计计算”菜单,之后,“创建统计计算菜单项”变成不可操作,而原先不可操作的“删除统计计算菜单项”变成可操作,执行“删除统计计算菜单项”菜单命令删除“统计计算”菜单。17该程序的实现要注意如下几个步骤:(1)在增加菜单时,调用函数GetMenu获取窗口主菜单的句柄。该函数的原型如下: HMENUGetMenu();(2)应用程序按照前述的过程建立新菜单、加入菜单项并插入到窗口的主菜单的指定位置。在创建新的弹出式菜单后,应用程序还通过调用函数EnableMenuItem禁止“创建统计计算菜单项”并将其暗淡显示。调用函数DrawMenuBar重新显示改变后的窗口主菜单。该函数的原型如下:voidDrawMenuBar()

创建“统计计算”菜单项后,可通过选择“文件”下拉菜单中的“删除统计计算菜单项”删除所创建的“统计计算”菜单项。此时,应用程序调用函数DeleteMenu删除该菜单项,并调用函数EnableMenuItem恢复“创建统计计算菜单项”的属性。18(1)首先,创建一个基于对话框的MFC项目,工程文件名为“5-1”(2)然后,打开资源视图,右键创建一个新的MENU资源,并将其命名为IDR_MENU1(3)在对话框类的头文件中添加:CMenu*hmenu;HMENUhaddmenu;//定义菜单句柄IDM_ADDMENU//增加菜单项的IDIDM_DELMENU//删除菜单项的IDIDM_EXIT//退出菜单项的IDIDM_qiuhe

//求和菜单项的IDIDM_fangcha//方差菜单项的IDIDM_pinjunzhi//平均值菜单项的IDIDM_junfanggen//均方根菜单项的ID(3)为各个菜单项添加单击事件的响应函数,打开类视图,右键点击对话框类,打开类视图,在“命令”栏中找到菜单项的对应ID(IDM_ADDMENU,IDM_DELMENU,IDM_EXIT),在右侧的“消息”框中选择“COMMAND”,最后点击“添加处理程序”voidCMy51Dlg::OnAddmenu(){hmenu=GetMenu(); //获取主菜单句柄haddmenu=CreateMenu(); //动态创建菜单//在创建的菜单中增加菜单项AppendMenu(haddmenu,MF_ENABLED,IDM_qiuhe,L"求和");AppendMenu(haddmenu,MF_ENABLED,IDM_fangcha,L"方差");AppendMenu(haddmenu,MF_ENABLED,IDM_pinjunzhi,L"平均值");AppendMenu(haddmenu,MF_ENABLED,IDM_junfanggen,L"均方根");//将创建的动态弹出式菜单插入主菜单中hmenu->InsertMenu(2,MF_POPUP|MF_BYPOSITION,(UINT_PTR)haddmenu,L"统计计算(&C)");//相应改变菜单中有关绘图统计计算菜单项的属性hmenu->EnableMenuItem(IDM_ADDMENU,MF_GRAYED); //一旦插入动态菜单后,就不能再插入,所以要变灰,不允许操作。hmenu->EnableMenuItem(IDM_DELMENU,MF_ENABLED);DrawMenuBar(); //重新显示窗口菜单}21voidCMy51Dlg::OnDelmenu(){hmenu=GetMenu();hmenu->DeleteMenu(2,MF_BYPOSITION);//删除统计计算菜单项//相应改变“文件”菜单中有关统计计算菜单项的属性hmenu->EnableMenuItem(IDM_ADDMENU,MF_ENABLED);hmenu->EnableMenuItem(IDM_DELMENU,MF_GRAYED);DrawMenuBar(); //重新显示窗口菜单}voidCMy51Dlg::OnExit(){//TODO:在此添加命令处理程序代码 OnOK();}此时运行一下程序,看看什么效果?22

运行程序,发现界面上并没有菜单,还要在主对话框中将创建的菜单选择进来,如图,打开主对话框的属性界面,将“菜单”属性设置为IDR_MENU1。235.2位图资源及其应用

245.2.1位图概念

位图是一种数字化的图形表示形式,位图中的每个像素点由位图文件中的一位或多位数据表示。整个位图的信息被细化为每个像素点的属性值。位图数据量一般较大,为了提高显示刷新速度,位图操作须在内存中进行。

用于位图操作的系统设备环境为内存设备环境。应用程序首先要通过调用函数CreateCompatibleDC向系统申请获取内存设备环境,此内存设备环境与输出设备的设备环境hdc互相兼容。其形式为:

hdcmem=CreateCompatibleDC(hdc);25

与设备环境相似,内存设备环境也有设备描述表。应用程序获取内存设备环境后,调用函数SelectObject将位图文件内容选入内存设备环境之后,即可直接在内存设备环境中操作位图,如绘制图形及编辑等等。需要说明的是,当直接在内存设备环境中进行绘图前,需要对内存设备环境进行初始化,否则不能直接绘图。对内存设备环境初始化一般使用后面所讲的BitBlt函数将客户区复制到内存即可,或使用CreateCompatibleBitmap创建空位图,将其选入内存设备环境。等到绘图结束后,再使用Bitblt函数将内存设备环境复制到屏幕。这一系列操作就是双缓冲技术。操作位图结束后,应用程序须调用DeleteDC释放内存设备环境,其形式为:

DeleteDC(hdcmem); //hdcmem:内存设备环境句柄265.2.2位图的操作过程

位图操作过程:定义位图句柄:HBITMAPhBm;

加载或创建

hBm=LoadBitmap(hInstance,lpszName)hBm=CreateCompatibleBitmap(hdc,nWidth,nHeight)

选入内存设备环境

Hdcmem->SelectObject(hBm);;输出

BOOLBitBlt( HDChdcDest, //目的设备环境句柄

intXDest,intYDest,intnWidth,intnHeitght,//位图基点及高宽

HDChdcSrc,intnXSrc,intnYsrc,//源设备环境句柄及位图基点

DWORDdwRop //标识位图显示方式)常用SRCCOPY将源位图拷贝到目标位图27在输出位图之前,需调用函数GetObject获取位图的尺寸:GetObject(hBitmap, //位图句柄

sizeof(BITMAP), //BITMAP结构的大小

(LPVOID)&bm //BITMAP结构的地址)调用函数GetObject后,将位图的信息写入BITMAP结构中函数GetObject函数的原型为:intGetObject(HANDLEhObject, //对象句柄intnCount, //拷贝到缓冲区的字节数LPVOIDlpObject //接收信息的缓冲区地址)28typedefstructtagBITMAP { LONGbmType; //位图类型 LONGbmWidth; //位图宽度 LONGbmHeight; //位图高度 LONGbmWidthBytes; //每一光栅行的字节数 WORDbmPlanes; //位图中位面的数目 WORDbmBitsPixel; //位图中每个像素的位数 LPVOIDbmBits; //位图位值的地址}BITMAP; 如果要在输出时使图形的尺寸改变就可以使用输出函数StretchBlt输出位图,StretchBlt函数的原型如下:BOOLStretchBlt(HDChdcDest, //目标DC的句柄intnXOriginDest,intnYOriginDest,//目标设备的基点坐标intnWidthDest,intnHeightDest, //目标设备的尺寸HDChdcSrc, //源DC的句柄intnXOriginSrc,intnYOriginSrc, //源设备的基点坐标

intnWidthSrc,intnHeightSrc, //源设备的尺寸DWORDdwRop //标识位图显示方式);

29StretchBlt比BitBlt多了一个源设备的尺寸。源设备的尺寸是BitBlt中的目标设备的尺寸,而目标设备的尺寸是实际输出设备上想显示的尺寸。305.2.3位图操作实例

【例5-2】在窗口中央加载一幅坦克图片的位图,位图尺寸为窗口面积的四分之一,当单击鼠标左键或键盘上的向上箭头时,位图向上移动,当移动到窗口的上边界时,窗口显示“不能再向上移动了”字样,当单击鼠标右键或键盘上的向下箭头时,位图向下移动,当到达窗口的下边界时,显示“不能再向下移动了”字样。

在创建基于对话框的应用程序后,导入一张文件名为pic5_2.bmp(可以是任意文件名,文件名不一定要取名pic5_2,但一定是位图,后缀为.bmp)。具体如下:1:在“资源视图”中找到本例的资源文件My52.rc,再单击鼠标右键,在弹出的菜单中选择“添加资源”。31然后在“添加资源”对话框中选择bitmap,并单击“导入”按钮,在弹出的对话框中选择所要导入的位图,本例为pic5_2.bmp。这个时候,你如果打开资源文件,并用文本阅读器阅读,发现系统增加来如下代码://////////////////////////////////////////////////////////BitmapIDB_BITMAP1BITMAP"pic5_2.bmp"

/////////////////////////////////////////////////322:添加变量:在.cpp文件中添加如下变量HBITMAPhBm; //定义位图句柄BITMAPbm; //定义位图结构变量intiY=20; //位图左上角初始y坐标intiWindowWidth,iWindowHeight; //窗口的宽度和高度LPCWSTRcUpWarn=L"不能再向上移动了"; //向上警告字符串LPCWSTRcDownWarn=L"不能再向下移动了";//向下警告字符串在对话框中显示图形,还要创建DC,在5_2Dlg.h中添加如下内容:CDC*hDC;33先介绍LoadImage函数,本例要用到。原型如下:HANDLELoadImage(HINSTANCEhinst,//若加载程序外部资源传NULL,否则一般传AfxGetInstanceHandle()LPCTSTRlpszName,//图片名称或全路径UINTuType,//图片类型:IMAGE_BITMAP或IMAGE_ICON或IMAGE_CURSORintcxDesired,intcyDesired,UINTfuLoad//

一般为LR_DEFAULTCOLOR|LR_CREATEDIBSECTION);3:因为要求窗口面积为位图的4倍,所以定义全局变量iWindowWidth,iWindowHeight来表示窗口的宽度和高度,在OnInitDialog函数中加入代码:hBm=(HBITMAP)LoadImage(AfxGetInstanceHandle(),L"pic5_2.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //加载位图GetObject(hBm,sizeof(BITMAP),(LPVOID)&bm); //获得位图信息iWindowWidth=2*bm.bmWidth; //得到窗口的宽度iWindowHeight=2*bm.bmHeight; //得到窗口的高度SetWindowPos(NULL,0,0,iWindowWidth,iWindowHeight,SWP_NOZORDER|SWP_NOMOVE);调用SetWindowPos函数,将函数中的窗口长度和窗口宽度信息设置为iWindowHeight,iWindowWidth即可创建出长度和宽度都为位图长度和宽度2倍的窗口来。34位图句柄指向pic5_2.bmpMFC的全局函数,其作用是返回标识当前应用程序实例的句柄该参数说明是从文件导入位图两个参数(cxDesired和cyDesired不为0并且fuLoad不指定LR_DEFAULTSIZE,Image会根据实际大小缩放),在本例中取0,代表按实际尺寸加载,不做任何缩放。按指定大小加载。35

本例中还用到SetWindowPos函数,该函数的功能是将一个窗口在三维空间中移动,利用它可改变窗口的位置,甚至可以在Z轴上改变(Z轴决定了一个窗口和其它窗口的前后关系),还可以改变窗口的尺寸,函数原型如下:BOOLSetWindowPos(HWNDhWndlnsertAfter,

intX,intY,

intcX,intcY,

UNITFlags):其中:Flags:指定窗口尺寸和定位的标志。下面列出部分可能的取值:•SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。•SWP_NOMOVE:维持当前位置(忽略X和Y参数)。•SWP_HIDEWINDOW:隐藏窗口。•SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。•SWP_SHOWWINDOW:显示窗口。对于对话框程序,通常只用设置为:SWP_NOZORDER|SWP_NOMOVE,即保持左上角坐标不变,且保持Z轴顺序不变。此句柄用于控制对话框在Z轴上的显示顺序,参数见教材。相对以客户坐标指定窗口新位置的左边界、上边界调整后新窗口的宽度和高度364:定义全局变量iY记录位图左上角在窗口中的纵坐标。当我们单击鼠标左键时,系统发送WM_LBUTTONDOWN消息,在此消息处理程序中加入代码:voidCMy52Dlg::OnLButtonDown(UINTnFlags,CPointpoint){ iY=iY-10; //位图高度-10 Invalidate(); //刷新用户区 CDialogEx::OnLButtonDown(nFlags,point);}5:添加单击鼠标右键的消息响应代码类似如下:voidCMy52Dlg::OnRButtonDown(UINTnFlags,CPointpoint){ iY=iY+10; //位图高度+10 Invalidate(); //刷新用户区 CDialogEx::OnRButtonDown(nFlags,point);}376:在处理键盘消息WM_KEYDOWN时,加入如下代码:voidCMy52Dlg::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags){switch(nChar){caseVK_UP: //按上箭头时,位置-10 iY=iY-10; break;

caseVK_DOWN: //按下箭头时,位置+10 iY=iY+10; break;

}Invalidate(); //刷新用户区CDialogEx::OnKeyDown(nChar,nRepCnt,nFlags);}

当nChar=VK_UP时,将iY减10;当nChar==VK_DOWN时,将iY加10;同时还要调用Invalidate()发送消息重绘用户区。387:在OnPaint函数中,加入下列代码:voidCMy52Dlg::OnPaint(){CDChdcmem; //定义内存句柄CPaintDCdc(this); //用于绘制的设备上下文hDC=GetDC(); //得到设备环境指针hdcmem.CreateCompatibleDC(hDC); //得到内存指针if(iY>0&&iY<iWindowHeight/2)//当位图完整的在窗口中时{hdcmem.SelectObject(hBm); //选入内存句柄

hDC->BitBlt(60,iY,bm.bmWidth,bm.bmHeight,&hdcmem,0,0,SRCCOPY);

}elseif(iY<=0) //当位图的上边界超出了窗口时

hDC->TextOut(0,0,cUpWarn,(int)wcslen(cUpWarn));//输出警告

else //当位图的下边界超出了窗口时hDC->TextOut(0,0,cDownWarn,(int)wcslen(cDownWarn));

ReleaseDC(hDC); //输出环境句柄hdcmem.DeleteDC();}398:此外还有处理字符消息的虚函数如下:BOOLCMy52Dlg::PreTranslateMessage(MSG*pMsg){//TODO:在此添加专用代码和/或调用基类SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam);returnCDialogEx::PreTranslateMessage(pMsg);}405.3对话框资源及其应用

对话框是一个弹出式窗口,它一般用于用户输入或与用户进行交互活动的场合对话框模式非模式允许用户在该对话框与应用程序其他窗口之间的切换,非模式对话框从WinMain函数的消息循环中接收输入不允许用户在关闭对话框之前切换到应用程序的其他窗口415.3.1模式对话框的编程方法

【例5-3】模态对话框例子。本例子中有一个“文件”菜单和“帮助”菜单,其中“文件菜单”下有“打开”、“保存”和“退出”菜单项,“帮助”菜单下有一个“关于”菜单项,其中,“关于”菜单项打开的对话框是一个模态对话框,当中有一个“确定”按钮。“打开”和“保存”对话框的响应均是简单的显示一个消息对话框,说明文件已经打开或文件已经保存等消息。42dwType常用标识及其说明MB_CANCELTRYCONTINUE

含有Cancel、TryAgain和Continue按钮的消息框MB_ICONEXCLAMATION,MB_ICONWARNING

含有惊叹号图标的消息框MB_ICONQUESTION 含有问号图标的消息框MB_ICONSTOP,MB_ICONERROR,MB_ICONHAND

含有停止图标的消息框MB_OK 含有一个OK按钮的消息框MB_OKCANCEL 含有OK和CANCEL按钮的消息框MB_RETRYCANCEL含有RETRY和CANCEL按钮的消息框MB_YESNO 含有YES和NO按钮的消息框MB_YESNOCANCEL含YES、NO和CANCEL按钮的消息框43(1)创建基于MFC的对话框应用程序5_3(2)由于应用程序中用到菜单,我们需要创建菜单资源(本例介绍的菜单是在对话框中加载菜单资源,后续章节内容将介绍在文档中加载菜单资源)。打开“资源视图”,创建菜单资源,此时系统缺省的创建了一个菜单资源,并缺省的命名ID为IDR_MENU1,如下图所示。然后对其进行菜单项创建。为“打开”、“保存”、“退出”和“关于”菜单项设置ID分别为:IDM_OPENIDM_SAVEIDM_EXITIDM_ABOUT44(3)由于“帮助”菜单中的菜单下跟“关于”需要打开一个“关于”的对话框,我们创建一个名字为ABOUT的对话框资源。

打开资源视图,右键点击空白区域,选择“添加资源”,选中“Dialog”并点击新建,创建一个新的对话框。对话框的ID名称设置为ABOUT。在资源视图中找到这个对话框的ID,然后单击鼠标右键,在弹出的下拉菜单中找到“属性”项,然后修改其ID值为ABOUT)。45(4)编辑ABOUT对话框界面如下:对于上图,点击“视图—工具箱”,可以进行控件的手动拖放。选择工具箱中的“静态文本(statictext)”,在静态文本控件上单击鼠标右键,在弹出的菜单中选择“属性”菜单项,在“描述文字”项中输入“Windows模态对话框”,那么在对话框上就出现了“Windows模态对话框”的内容。同样方法在工具箱中选取按钮(BUTTON)控件,“描述文字”为“确定”,其中“确定”按钮的ID设置为“IDOK”。46(5)对新建的ABOUT对话框创建对应的对话框类,右键点击对话框,点击“添加类”,如图所示。将类名定义为MYABOUT,点击确定,即生成该类对应的头文件和cpp文件,如下图:47这个时候,会看到增加了一个头文件MYABOUT.h,这就是添加MYABOUT类后生成的类定义文件。Tip:可能有部分同学此时如果打开MYABOUT类的头文件MYABOUT.h,会出现一些红色波浪号的错误提示,这个不是代码的错误,是设置的问题。可以按如下方法解决:“工具”-“选项”-“文本编辑器”-“C/C++”-“高级”-“禁用自动更新”-“True”按上面方法修改设计即可。48(6)接下来为该对话框的“确定”按钮设置响应程序。右键单击“确定”按钮,在弹出的菜单中选择“添加事件处理程序”,如左图选择消息类型为“BN_CLICKED”,点击确定,即自动生成单击按钮的事件处理函数,如右图在函数中添加如下代码,表示点击确定按钮后关闭窗口voidMYABOUT::OnBnClickedOk(){ EndDialog(0); CDialogEx::OnOK();}49接着我们需要把菜单资源跟父对话框资源链接起来,使得程序一运行,能看到菜单并进行操作。具体如下:找到父对话框,编辑其属性项中的菜单选项为我们创建的菜单资源IDR_MENU1即可。50

然后为上述四个菜单项响应单击事件处理程序,即完成本例所要求的功能。具体操作如下。打开类视图,右键点击CMy53Dlg对话框类,打开类向导,在“命令”栏中找到菜单项的对应ID(IDM_OPEN、IDM_SAVE、IDM_EXIT和IDM_ABOUT),在右侧的“消息”框中选择“COMMAND”,最后点击“添加处理程序”,所生成如下消息处理函数如下: afx_msgvoidOnOpen(); afx_msgvoidOnSave(); afx_msgvoidOnExit(); afx_msgvoidOnAbout();voidCMy53Dlg::OnPaint(){ CPaintDCdc(this); } //用于绘制的设备上下文voidCMy53Dlg::OnOpen(){MessageBox(L"文件已经打开!",L"文件打开",MB_OK);}voidCMy53Dlg::OnSave(){MessageBox(L"文件保存成功!",L"文件保存",MB_OK);}voidCMy53Dlg::OnExit(){SendMessage(WM_DESTROY,0,0);}voidCMy53Dlg::OnAbout(){MYABOUTdiag; //定义一个MYABOUT类的对象diagdiag.DoModal(); //执行ABOUT对话框上的“确定”按钮,关闭对话框}

由于这里引用了类MYABOUT,因此,在CMy53Dlg.cpp里头需要添加如下头文件:#include"MYABOUT.h"使用模式对话框时需要注意一些问题,不要在一些反复出现的事件处理过程中生成有模式对话框,比如说在定时器中产生有模式对话框,因为在上一个对话框还未退出时,定时器消息又会引起下一个对话框的弹出。52535.3.2非模态对话框的编程方法

54非模态对话框应用实例

【例5-4】本例中,选择“模态对话框”菜单项,应用程序将创建并显示“显示模态对话框”,在对话框中可以在编辑框中输入文字,点击“确定”,就可以在主窗口中显示输入的信息。如果点击“取消”按钮,则清除编辑框中输入的内容,在模态对话框操作过程中,不能进行模态对话框以外区域的操作。若选择“显示非模态对话框”,可在对话框以外的区域进行操作。55(1)创建基于对话框的mfc工程,工程名为“5-4”。(2)然后在资源视图中创建一个菜单资源,其ID采用缺省值IDR_MENU1,菜单资源编辑结果如下:然后添加一个对话框资源,将其命名为IDD_DIALOG1,并进行如下编辑,从工具箱中选取StaticText控件和EditControl控件拉到对话框中,并设置其属性对应地为该对话框创建对话框类,类命名为Dialog1。56系统为该对话框资源生成了如下代码,读者可以分析该代码结构:IDD_DIALOG1DIALOGEX0,0,311,177STYLEDS_SETFONT|DS_MODALFRAME|DS_FIXEDSYS|WS_POPUP|WS_CAPTION|WS_SYSMENUCAPTION"Dialog"FONT8,"MSShellDlg",400,0,0x1BEGINDEFPUSHBUTTON"确定",IDOK,86,111,50,14PUSHBUTTON"取消",IDCANCEL,162,111,50,14CTEXT"Windows对话框",IDC_STATIC,77,27,141,19LTEXT"请输入要显示的内容:",IDC_STATIC,83,53,130,16EDITTEXTIDC_EDIT1,84,73,132,21,ES_AUTOHSCROLLEND

57(3)为菜单项和对话框中的编辑框添加如下ID:IDC_EDIT1 //对话框中的编辑框IDM_OPEN //打开菜单项IDM_SAVE //保存菜单项IDM_EXIT //退出菜单项IDM_MODAL //模态对话框菜单项IDM_MODALLESS //非模态对话框菜单项本例resource.h头文件中系统自动添加了如下代码(不同系统宏定义的整型数可能不同):#defineIDR_MENU1 129#defineIDD_DIALOG1 131#defineIDC_EDIT1 1000#defineIDM_OPEN 32776#defineIDM_SAVE 32777#defineIDM_EXIT 32778#defineIDM_MODAL 32779#defineIDM_MODALLESS 32780用户所定义的任何一个ID,系统都通过宏定义给映射了一个正型数,当然这些正型数是不能重复的,也就是说不允许有任何两个ID拥有相同的映射值(4)在5_4Dlg.h对话框类的头文件中添加如下代码: CDC*hDC;(5)为菜单项创建消息响应函数,这个创建过程要通过选择对话框类,然后单击鼠标右键,在弹出的菜单中选择“类向导”,然后在“类向导”对话框中选择“命令”选项卡,在“对象”框中选择我们所增加的菜单项的ID,进行消息响应函数的添加

此时在对话框类CMy54Dlg的头文件5_4Dlg.h的定义中系统增加了如下代码:public:afx_msgvoidOnOpen();afx_msgvoidOnSave();afx_msgvoidOnExit();afx_msgvoidOnModal();afx_msgvoidOnModalless();然后我们需要为这几个函数编写函数体的代码。59

要注意的是,我们现在创建的是菜单资源中菜单项的消息响应,这个菜单要安放在主对话框上,因此,要把这个菜单资源绑定到主对话框中,其处理方法就是找到主对话框,单击鼠标右键,在弹出的快捷菜单中找到“属性”项,然后设置菜单为我们所创建的菜单资源,本例为IDR_MENU1。这个时候我们需要定义一个指向子对话框的指针,因为主对话框的菜单项的相关操作要调出子对话框Dialog1,于是在5_4Dlg.cpp中定义一个指向子对话框的指针如下:

Dialog1*diag;//子对话框指针由于这里引用来类Dialog1,因此需要对话框定义一个类Dialog1#include"Dialog1.h"60所添加的上述五个函数分别如下:voidCMy54Dlg::OnOpen(){MessageBox(L"文件已经打开!",L"文件打开",MB_OK);}voidCMy54Dlg::OnSave(){MessageBox(L"文件保存成功!",L"文件保存",MB_OK);}voidCMy54Dlg::OnExit(){SendMessage(WM_DESTROY,0,0);}这里用到了SendMessage函数,在MFC中,该函数原型如下:SendMessage(UINTMsg,WPARAMwParam,LPARAMIParam);参数Msg是指定被发送的消息,前缀是“WM_”,下面是几个常用的消息:WM_DESTROY:销毁窗口WM_MOVE:移动窗口WM_SIZE:改变窗口的大小WM_ACTIVATE:窗口被激活或失去激活状态WM_SETFOCUS:窗口获得焦点WM_KILLFOCUS:窗口失去焦点WM_ENABLE:窗口改变成Enable状态WM_SETTEXT:应用程序发送此消息来设置窗口的文本WM_CLOSE:关闭窗口或应用程序WM_QUIT:结束程序运行

参数wParam和IParam不用的时候可以赋0。61voidCMy54Dlg::OnModal(){ //TODO:在此添加命令处理程序代码diag=newDialog1(this,false);//this参数表示将父窗口指针传递给子窗口,false表示该窗口为模态diag->DoModal();}

voidCMy54Dlg::OnModalless() //创建非模态对话框{ //TODO:在此添加命令处理程序代码 diag=newDialog1(this,true); diag->Create(IDD_DIALOG1,this); //创建非模太对话框IDD_DIALOG1 diag->ShowWindow(SW_SHOWNORMAL);}62(6)内容刷新由于在子对话框中有一个编辑框输入的内容需要显示出来,这里就需要进行刷新操作,刷新函数代码如下:voidCMy54Dlg::OnPaint(){CPaintDCdc(this); //用于绘制的设备上下文hDC=GetDC(); //获取DCif(diag!=NULL) hDC->TextOut(0,0,diag->str,(i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论