学习指导图标光标和窗口

上传人:ll****x 文档编号:242865679 上传时间:2024-09-10 格式:PPT 页数:50 大小:451KB
返回 下载 相关 举报
学习指导图标光标和窗口_第1页
第1页 / 共50页
学习指导图标光标和窗口_第2页
第2页 / 共50页
学习指导图标光标和窗口_第3页
第3页 / 共50页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第5章图标、光标和窗口框架,5.1图像编辑器,5.2图标,5.3光标,5.4窗口样式和状态,5.5综合应用,1,5.1图像编辑器,5.1.1 图像编辑器,1. 创建一个新的图标或光标,在Visual C+ 6.0中,创建一个应用程序后,当按快捷键Ctrl+R就可打开“插入资源”对话框,从中选择Cursor(光标)或Icon(图标)资源类型,单击新建按钮后,系统为程序添加一个新的图标或光标资源,同时在开发环境右侧出现图像编辑器。图5.1是添加一个新的图标资源后出现的图像编辑器。,新设备按钮,图5.1 添加图标后的图像编辑器,2,5.1图像编辑器,在创建新图标或光标的时候,图像编辑器首先创建的是一个适合于VGA环境中的图像,开始的时候它以屏幕色(透明方式)来填充。对于创建的新光标,其“热点”被初始化为左上角的点,坐标为(0,0)。默认情况下,图像编辑器所支持的显示设备如表5.1所示。,表5.1 创建图标或光标时可选用的显示设备,设 备,颜色数目,宽 度,高 度,单显模式(Monochrome),2,32,32,小设备模式(Small),16,16,16,标准模式(Standard),16,32,32,大模式(Large),256,48,48,3,5.1图像编辑器,2. 选用和定制显示设备,在图像编辑器工作窗口的控制条上,有一个“新设备图像”(New Device Image)按钮,单击此按钮后,系统弹出相应的新设备列表,可以从中选取需要的显示设备,如图5.2所示。,图5.2 图像设备选择对话框图 图5.3 自定义设备图像,除了对话框列表框显示的设备外,还可以单击自定义按钮,在弹出的对话框中定制新的显示设备,如图5.3所示,在这里可指定新设备图像的大小和颜色。,4,5.1图像编辑器,3. 设置光标热点,Windows系统借助光标“热点”来确定光标实际的位置。在图像编辑器的控制条上或光标属性对话框中都可以看到当前的光标“热点”位置。图5.4是添加一个新的光标资源后出现的图像编辑器。,控制条,设置热点按钮,图5.4 添加光标后的图像编辑器,5,5.2图标,5.2.1 图标的调入、清除和显示,1. 图标的调入,在MFC中,当在应用程序中添加一个图标资源后,就可以使用CWinApp:LoadIcon函数可将其调入并返回一个图标句柄。函数原型如下:,HICON LoadIcon( LPCTSTR,lpszResourceName,) const;,HICON LoadIcon( UINT,nIDResource,) const;,其中,lpszResourceName和nIDResource分别表示图标资源的字符串名和标识。函数返回的是一个图标句柄。,如果不想使用新的图标资源,也可使用系统中预定义好的标准图标,这时需调用CWinApp:LoadStandardIcon 函数,其原型如下:,HICON LoadStandardIcon( LPCTSTR,lpszIconName,) const;,其中,lpszIconName可以是下列值之一:,IDI_APPLICATION 默认的应用程序图标,IDI_HAND 手形图标(用于严重警告),IDI_QUESTION 问号图标(用于提示消息),IDI_EXCLAMATION 警告消息图标(惊叹号),IDI_ASTERISK 消息图标,6,5.2图标,2. 图标的消除,图标装载后,可使用全局函数DestroyIcon来删除图标,并释放为图标分配的内存,其原型如下:,BOOL DestroyIcon( HICON,hIcon,);,其中,hIcon用来指定要删除的图标句柄。,3. 图标的显示,图标的显示一般有两种方法:一是通过静态图片控件来显示,或在其他(如按钮)控件设置显示;二是通过函数CDC:DrawIcon用来将一个图标绘制在指定设备的位置处(这一方法以后再讨论)。,4. 图标示例,下面来看一个示例,如图5.5所示,单击开始按钮,3个图标就会每隔100ms随机显示,且此时开始按钮变成停止。单击停止按钮,图标停止更新,按钮的名称变成“开始”,如果3个图标的图案都是一样的,则弹出消息对话框,显示“恭喜你!”,否则显示“失败!”。,7,5.2图标,图5.5 图标示例,分析和思考:,(1)从图5.5中可以看出,该示例是一个对话框应用程序。,(2)需要创建3个图标资源,且通过3个静态图片控件来显示。为了能在程序中动态地改变静态控件显示的图标,还需为控件添加CStatic类变量,然后通过CStatic:SetIcon来指定,该函数原型如下:,HICON SetIcon( HICON,hIcon,);,其中,hIcon用来指定要显示的图标句柄。函数成功调用后,将返回上一次图标的句柄。,(3)由于每隔100ms随机显示这些图标,因而需要启动计时器,并在WM_TIMER消息映射函数中添加相关代码,且还需用rand函数来产生随机序列。另外,为了避免每次所产生的随机序列相同,在产生随机数之前使用srand库函数来重新指定随机种子。,示例步骤如下:,8,5.2图标,例Ex_RandIcon 图标使用,(,1,)创建一个默认的基于对话框应用程序,Ex_RandIcon,。,(,2,)按,Ctrl+R,键,弹出“插入资源”对话框,选择“,Icon”,类型,单击,新建,按钮。这样,就为程序添加一个新的图标资源IDI_ICON1。保留默认的ID号和设备类型,再按此法添加2个图标资源,相应的默认ID号分别为IDI_ICON2和IDI_ICON3。,(,3,)按图,5.6,所示,依次打开图标资源IDI_ICON1、IDI_ICON2和IDI_ICON3,在图像编辑器中分别将它们设计成红色带圈的,A,、绿色带圈的,B,、蓝色带圈的,C,。,图5.6 添加并设计的图标,9,5.2图标,(,4,)在,ResourceView,页面中,双击“,Dialog”,下的,IDD_EX_RANDICON_DIALOG,,打开对话框资源模板。将对话框的标题设为“图标使用”。删除“,TODO:,在这里设置对话控制。”静态文本控件和,取消,按钮,将,确定,按钮标题改为“退出”。,(,5,)打开对话框网格,参照图,5.5,所示,调整对话框大小,分别依次添加,3,个静态图片控件,,ID,号分别设置为,IDC_STATIC_1,、,IDC_STATIC_2,和,IDC_STATIC_3,,类型选择为“图标”,图像依次选择为IDI_ICON1、IDI_ICON2和IDI_ICON3,在样式属性中,分别选中“图像居中”。,(,6,)添加一个按钮控件,,ID,号为,IDC_BUTTON_START,,标题为“开始”。,(,7,)按,Ctrl+W,键,打开,MFC ClassWizard,的,Member Variables,页面,依次为,IDC_STATIC_1,、,IDC_STATIC_2,和,IDC_STATIC_3,设置,CStatic,类的,Control,变量,m_wndIcon1,、,m_wndIcon2,和,m_wndIcon3,。,(,8,)切换到,Messsage Maps,页面,为按钮,IDC_BUTTON_START,添加,BN_CLICKED,消息映射,保留默认的映射函数名,添加,下列代码,:,(,9,)再次打开,MFC ClassWizard,的,Messsage Maps,页面,为CEx_RandIconDlg类添加WM_TIMER消息映射,并在映射函数中添加,下列代码,:,(,10,)编译运行并测试。,10,5.2图标,5.2.2 应用程序图标的改变,在用,MFC AppWizard,创建的应用程序中,图标资源,IDR_MAINFRAME,用来表示应用程序窗口的图标,通过图像编辑器可将其内容直接修改。实际上,程序中还可使用GetClassLong和SetClassLong函数重新指定应用程序窗口的图标,函数原型如下:,DWORD SetClassLong( HWND,hWnd, int,nIndex, LONG,dwNewLong,);,DWORD GetClassLong( HWND,hWnd, int,nIndex,);,其中,hWnd用来指定窗口类句柄,dwNewLong 用来指定新的32位值。nIndex用来指定与WNDCLASSEX结构相关的索引,它可以是下列值之一:,GCL_HBRBACKGROUND 窗口类的,背景画刷句柄,GCL_HCURSOR 窗口类的的光标句柄,GCL_HICON窗口类的的图标句柄,GCL_MENUNAME,窗口类的的菜单资源名称,下面来看一个示例,它是将应用程序的图标按一定的序列来显示,使其看起来具有动画效果。,11,5.2图标,例Ex_Icon 图标使用,(,1,)创建一个默认的单文档应用程序,Ex_Icon,。,(,2,)添加,4,个图标资源,单击“新建设备图像”按钮,选择“小的(,16 x 16,)”作为图标的设备类型,保留图标资源默认的,ID,号:,IDI_ICON1 IDI_ICON4,,制作如图,5.7,所示的图标。,图5.7 创建的四个图标,12,5.2图标,(,3,)为,CMainFrame,类添加一个成员函数,ChangeIcon,,用来切换应用程序的图标。该函数的代码如下:,void CMainFrame:ChangeIcon(UINT nIconID),HICON hIconNew = AfxGetApp()-LoadIcon(nIconID);,HICON hIconOld = (HICON)GetClassLong(m_hWnd, GCL_HICON);,if (hIconNew != hIconOld),DestroyIcon(hIconOld);,SetClassLong(m_hWnd, GCL_HICON, (long)hIconNew);,RedrawWindow();/ 重绘窗口,13,5.2图标,(,4,)在,CMainFrame:OnCreate,函数的最后添加计时器设置代码:,int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct),if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;,.,SetTimer(1, 500, NULL);,return 0;,(,5,)用,MFC ClassWizard,为,CMainFrame,类添加,WM_TIMER,的消息映射函数,并增加下列代码:,void CMainFrame:OnTimer(UINT nIDEvent),static int icons = IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4;,static int index = 0;,ChangeIcon(iconsindex);,index+;,if (index3) index = 0;,CFrameWnd:OnTimer(nIDEvent);,14,5.2图标,(,7,)编译并运行。可以看到任务栏上的按钮以及应用程序的标题栏上四个图标循环显示的动态效果,显示速度为每秒两帧。,5.2.3,获取系统文件图标,图标作为界面设计的一个常见元素,在Windows系统中早已标准化了。在应用程序中,常常为了界面的一致性,总要使用这些规范化的图标。虽然,Visual Studio 6.0中的安装光盘已有一些常用的这样图标,但都是Windows 95的标准。所以,在应用程序中,使用最新标准的图标,仍然需要通过相应的API函数来获取。SHGet就是其中一个这样的函数,它用来获取指定文件或文件的图标,其原型如下:,DWORD_PTR SHGet(,LPCTSTR,pszPath,/ 文件或路径名,DWORD,dw,/ 文件属性,SH FAR *,psfi,/ 返回SH结构数据的地址,UINT,cb,/ SH结构大小,UINT,uFlags,/ 返回标志,);,15,5.2图标,其中,uFlags用来指定返回内容的一些标志,如:SHGFI_DISPLAYNAME(返回文件的显示名称,保存在psfi中的szDisplayName成员)、SHGFI_ICON(返回文件图标的句柄或索引号,保存在psfi中的hIcon成员或iIcon成员)、SHGFI_ICON | SHGFI_LARGEICON(返回文件的大图标)、SHGFI_ICON | SHGFI_OPENICON(返回文件打开时的图标)、SHGFI_ICON | SHGFI_SELECTED(返回文件打开时的图标)、SHGFI_ICON | SHGFI_SMALLICON(返回文件的小图标)、SHGFI_TYPENAME(返回文件的类型名称,保存在psfi中的szTypeName成员)。,下面来看一个示例,它分别显示当前系统下的文件夹图标、文件夹打开时的图标、资源管理器的图标、记事本的图标。如图5.8所示。,图5.8 获取文件图标,16,5.2图标,例Ex_ 获取文件图标,(,1,)创建一个默认的基于对话框应用程序,Ex_,。,(,2,)将对话框的标题设为“文件图标”。删除“,TODO:,在这里设置对话控制。”静态文本控件和,取消,按钮,将,确定,按钮标题改为“退出”。,(,3,)打开对话框网格,参照图,5.8,所示,调整对话框大小,分别依次添加,4,个静态图片控件,,ID,号分别设置为,IDC_STATIC_1,、,IDC_STATIC_2,、,IDC_STATIC_3,和,IDC_STATIC_4,,类型选择为“图标”,在样式属性中,分别选中“图像居中”。,(,4,)按,Ctrl+W,键,打开,MFC ClassWizard,的,Member Variables,页面,依次为,IDC_STATIC_1,、,IDC_STATIC_2,、,IDC_STATIC_3,和,IDC_STATIC_4,设置,CStatic,类 的,Control,变量,m_wndIcon1,、,m_wndIcon2,、,m_wndIcon3,和,m_wndIcon4,。,17,5.2图标,(,5,)在,CEx_,函数中的“,return true;”,语句之前添加下列代码:,BOOL CEx_(),SH fi;,SHGet(C:windows,0,m_wndIcon1.SetIcon( fi.hIcon );,SHGet(C:windows,0,m_wndIcon2.SetIcon( fi.hIcon );,SHGet(C:windowsexplorer.exe,0,&fi,sizeof(SH),SHGFI_ICON );,m_wndIcon3.SetIcon( fi.hIcon );,SHGet(C:windowsnotepad.exe,0,&fi,sizeof(SH),SHGFI_ICON );,m_wndIcon4.SetIcon( fi.hIcon );,return TRUE; / return TRUE unless you set the focus to a control,(,6,)编译运行。,18,5.2图标,1. 添加或删除图标,Windows提供了任务栏相应的应用程序接口,从而通过Shell_NotifyIcon函数很容易地向任务栏的托盘添加或删除图标。Shell_NotifyIcon的,原型如下,:,2. 处理鼠标消息,当用户在图标所在的区域中进行鼠标操作时,,都会向窗口发送相应消息(该消息由添加托盘时在,NOTIFYICONDATA,结构的,uCallbackMessage,指定)。应用程序通过对这些消息的处理,便可执行相应的动作。,下面来看一个示例:在这个示例中,首先创建一个默认的基于对话框应用程序。当用户单击对话框的,最小化,按钮时,对话框消失,在任务栏的托盘上显示出应用程序的图标。若单击图标将恢复显示对话框,此时应用程序的图标从托盘中消失。,例Ex_Tray 托盘图标操作,(,1,)创建一个默认的基于对话框应用程序,Ex_Tray,。,(,2,)将对话框的标题设为“托盘图标使用”,选中“样式”页面中的“最小化框”选项。删除“,TODO: .”,静态文本控件和,取消,按钮,将,确定,按钮标题改为“退出”。,(,3,)向,CEx_TrayDlg,类中添加前面已列出的,AddTaskBarIcon,和,DeleteTaskBarIcon,两个成员函数。,19,5.2图标,(,4,)用,MFC ClassWizard,为,CEx_TrayDlg,类添加,WM_SIZE,的消息映射,保留默认的映射函数名,增加下列代码:,void CEx_TrayDlg:OnSize(UINT nType, int cx, int cy),CDialog:OnSize(nType, cx, cy);,if (nType=SIZE_MINIMIZED),AddTaskBarIcon( m_hWnd, IDR_MAINFRAME, m_hIcon, 托盘图标操作示例);,ShowWindow(SW_HIDE);/ 后面会讨论这个函数的用法, else,DeleteTaskBarIcon(m_hWnd, IDR_MAINFRAME);,20,5.2图标,(,5,)用,MFC ClassWizard,为,CEx_TrayDlg,类添加,WM_DESTROY,的消息映射,保留默认的映射函数名,增加下列代码:,void CEx_TrayDlg:OnDestroy(),CDialog:OnDestroy();,DeleteTaskBarIcon( m_hWnd, IDR_MAINFRAME );,(,6,)由于在,AddTaskBarIcon,成员函数中指定了用于托盘图标通知消息的,ID,号:“,tnid.uCallbackMessage = WM_ICON_NOTIFY;”,,因而为了能捕捉到,WM_ICON_NOTIFY,消息,还必要定义它并手动按,MFC,消息映射机制来添加该消息的消息映射。,(,7,)打开,Ex_TrayDlg.h,文件,在类声明语句“,class CEx_TrayDlg : public CDialog”,之前添加,WM_ICON_NOTIFY,的宏定义:,#define WM_ICON_NOTIFY(WM_USER+500),21,5.2图标,(8)在Ex_TrayDlg.h文件的DECLARE_MESSAGE_MAP前,添加 WM_ICON_NOTIFY的消息映射函数的声明:,/AFX_MSG(CEx_TrayDlg),/AFX_MSG,void OnTrayNotify(WPARAM wParam, LPARAM lParam);,DECLARE_MESSAGE_MAP(),(9)打开Ex_TrayDlg.cpp文件,在CEx_TrayDlg类的消息入口定义中添加消息宏指定,即将消息WM_ICON_NOTIFY与前面声明的消息函数OnTrayNotify相映射:,BEGIN_MESSAGE_MAP(CEx_TrayDlg, CDialog),/AFX_MSG_MAP(CEx_TrayDlg),ON_WM_SYSCOMMAND(),ON_WM_DESTROY(),/AFX_MSG_MAP,ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotify),END_MESSAGE_MAP(),22,5.2图标,(10)在Ex_TrayDlg.cpp文件中,添加CEx_TrayDlg类的消息函数OnTrayNotify的实现代码:,void CEx_TrayDlg:OnTrayNotify(WPARAM wParam, LPARAM lParam),UINT uID= (UINT) wParam;,UINT uMouseMsg = (UINT) lParam;,if (uID = IDR_MAINFRAME),if (uMouseMsg = WM_LBUTTONDOWN),ShowWindow(SW_SHOWNORMAL);,return;,(11)编译运行并测试。,23,5.3光标,1. 使用系统光标,Windows预定义了一些经常使用的标准光标,这些光标均可以使用函数 CWinApp: LoadStandardCursor加载到程序中,其函数原型如下:,HCURSOR LoadStandardCursor( LPCTSTR,lpszCursorName,) const;,其中,lpszCursorName用来指定一个标准光标名,它可以是下列宏定义:,IDC_ARROW 标准箭头光标,IDC_IBEAM 标准文本输入光标,IDC_WAIT 漏斗型计时等待光标,IDC_CROSS 十字形光标,IDC_UPARROW 垂直箭头光标,IDC_SIZEALL 四向箭头光标,IDC_SIZENWSE 向下的双向箭头光标,IDC_SIZENESW 向上双向箭头光标,IDC_SIZEWE 左右双向箭头光标,IDC_SIZENS 上下双向箭头光标,24,5.3光标,加载一个垂直箭头光标IDC_UPARROW的代码如下:,HCURSOR hCursor;,hCursor = AfxGetApp()-LoadStandardCursor(IDC_UPARROW);,2. 使用光标资源,用编辑器创建或从外部调入的光标资源,可通过函数CWinApp:LoadCursor进行加载,其原型如下:,HCURSOR LoadCursor( LPCTSTR,lpszResourceName,) const;,HCURSOR LoadCursor( UINT,nIDResource,) const;,其中,lpszResourceName和nIDResource分别用来指定光标资源的名称或ID号。例如,当光标资源为IDC_CURSOR1时,则可使用下列代码:,HCURSOR hCursor;,hCursor = AfxGetApp()-LoadCursor(IDC_CURSOR1);,需要说明的是,也可直接用全局函数LoadCursorFromFile加载一个外部光标文件,例如,HCURSOR hCursor;,hCursor = LoadCursorFromFile(“c:windowscursorsglobe.ani”);,25,5.3光标,3. 更改程序中的光标,更改应用程序中的光标除了可以使用GetClassLong和SetClassLong函数外,最简单的方法是用MFC ClassWizard映射WM_SETCURSOR消息,该消息是当光标移动到一个窗口内并且还没有捕捉到鼠标时产生的。CWnd为此消息的映射函数定义这样的原型:,afx_msg,BOOL,OnSetCursor(,CWnd*,pWnd,UINT,nHitTest,UINT,message,);,其中,pWnd表示拥有光标的窗口指针,nHitTest用来表示光标所处的位置,例如当为HTCLIENT时表示光标在窗口的客户区中,而为HTCAPTION 时表示光标在窗口的标题栏处,为HTMENU时表示光标在窗口的菜单栏区域等等。message用来表示鼠标消息。,在OnSetCursor函数调用SetCursor来设置相应的光标,并将OnSetCursor函数返回TRUE,就可改变当前的光标了。,例如,可根据当前鼠标所在的位置来确定单文档应用程序光标的类型,当处在标题栏时为一个动画光标,当处在客户区时为一个自定义光标。,26,5.3光标,例Ex_Cursor 改变应用程序光标,(,1,)创建一个默认的单文档应用程序,Ex_Cursor,。,(,2,)按快捷键,Ctrl+R,,打开“插入资源”对话框,选择“,Cursor”,类型后,单击,新建,按钮。,(,3,)在图像编辑器工作窗口的控制条上,单击“新建设备图像”按钮,从弹出的“新建设备图像”对话框中,单击,自定义,按钮。,(,4,)在弹出的“自定义图像”对话框中,保留默认的大小和颜色数,单击,确定,按钮。回到“新建设备图像”对话框。这样,“,32 x 32, 16,颜色”设备类型就被添加上了,单击,确定,按钮。,(,5,)在图像编辑器的“设备”组合框中,选择“单色,32 x 32 ”,,打开“图像”(,Image,)菜单,选择“删除设备图像”(,Delete Device Image,)命令,这样,就删除“单色,32 x 32 ”,设备类型。如果不这样做,加载后的光标不会采用“,32 x 32, 16,颜色”设备类型。,(,6,)保留默认的,ID,号,IDC_CURSOR1,,用图像编辑器绘制光标图形,指定光标热点位置为(,15, 15,),结果如图,5.9,所示。,27,5.3光标,图5.9 创建的光标,(,7,)为,CMainFrame,类添加一个成员变量,m_hCursor,,变量类型为光标句柄,HCURSOR,。,28,5.3光标,(,8,)用,MFC ClassWizard,为,CMainFrame,类添加WM_SETCURSOR的消息映射函数,并增加下列代码:,BOOL CMainFrame:OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message),BOOL bRes = CFrameWnd:OnSetCursor(pWnd, nHitTest, message);,if (nHitTest = HTCAPTION ),m_hCursor = LoadCursorFromFile(c:windowscursors,hand.ani);,SetCursor(m_hCursor);,bRes = TRUE;,else if (nHitTest = HTCLIENT ),m_hCursor = AfxGetApp()-LoadCursor(IDC_CURSOR1);,SetCursor(m_hCursor);,bRes = TRUE;,return bRes;,29,5.3光标,(,9,)编译运行并测试。当鼠标移动到标题栏时,光标变成了hand.ani的动画光标,而当移动到客户区时,光标变成了IDC_CURSOR1定义的形状。,需要说明的是,Visual C+6.0中还提供BeginWaitCursor和EndWaitCursor函数来启动和终止动画沙漏光标。,30,5.4窗口样式和状态,5.4.1 窗口样式,窗口样式通常有一般(以WS_为前缀)和扩展(以WS_EX_为前缀)两种形式。这两种形式的窗口样式可在函数CWnd:Create或CWnd:CreateEx参数中指定,其中CreateEx函数可同时支持以上两种样式,而CWnd:Create只能指定窗口的一般样式。需要说明的是,对于控件和对话框这样的窗口来说,它们的窗口样式可直接通过其属性对话框来设置。常见的一般窗口样式如,表5.2,所示。,需要说明的是,除了上述样式外,框架窗口还有以下3个自己的样式。它们都可以在PreCreateWindow重载函数中指定。,(1)FWS_ADDTOTITLE,。该样式指定一个文档名添加到框架窗口标题中,例如“Ex_MDI Ex_MDI1”中,Ex_MDI1是文档名。对于单文档应用程序来说,默认的文档名是“无标题”。,(2)FWS_PREFIXTITLE,。该样式使得框架窗口标题中的文档名显示在应用程序名之前。例如,若未指定该样式时的窗口标题为“Ex_MDI Ex_MDI1”,当指定该样式后就变成了“Ex_MDI1 Ex_MDI”。,(3)FWS_SNAPTOBARS,。该样式用来调整窗口的大小,使它刚好包含了框架窗口中的控制栏(如工具栏)。,31,5.4窗口样式和状态,5.4.1 窗口样式设置,1. 在MFC AppWizard中设置,MFC AppWizard 有一个高级按扭(在创建单文档或多文档应用程序过程的第四步中),允许用户指定有关SDI和MDI框架窗口的属性,图5.10表示了单文档应用程序创建时的“高级选项”(Advanced Options)对话框的“窗口样式”(Window Styles)页面,其中的选项含义见表5.3。但在该对话框中,用户只能设定少数几种窗口样式。,表5.3 高级选项对话框窗口样式的各项含义,选 项,含 义,使用可拆分窗口(Use split window),选中时,将程序的文档窗口创建成“切分”(或称拆分)窗口,厚边框(Thick frame),选中时,设置窗口样式WS_THICKFRAME,最小化边框(Minimize box),选中时,设置窗口样式WS_MINIMIZEBOX,标题右侧含有最小化按钮,最大化边框(Maximize box),选中时,设置窗口样式WS_MAXIMIZEBOX,标题右侧含有最大化按钮,系统菜单(System menu),选中时,设置窗口样式WS_SYSMENU,标题左侧有系统菜单,最小化(Minimized),选中时,设置窗口样式WS_MINIMIZE,最大化(Maximized),选中时,设置窗口样式WS_MAXIMIZE,32,5.4窗口样式和状态,修改CREATESTRUCT结构,当窗口创建之前,系统自动调用PreCreateWindow虚函数。在用MFC AppWizard创建文档应用程序结构时,MFC已为主窗口或文档窗口类自动重载了该虚函数。用户可以在此函数中通过修改CREATESTRUCT结构来设置窗口的绝大多数样式。,例如,在单文档应用程序中,框架窗口默认的样式是WS_OVERLAPPEDWINDOW和FWS_ADDTOTITLE的组合,更改其样式可如下列的代码:,图5.10 高级选项对话框,BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs),/ 新窗口不带有最大化按钮,cs.style ,/ 将窗口的大小设为1/3屏幕并居中,cs.cy = :GetSystemMetrics(SM_CYSCREEN) / 3;,cs.cx = :GetSystemMetrics(SM_CXSCREEN) / 3;,cs.y = (cs.cy * 3) - cs.cy) / 2; cs.x = (cs.cx * 3) - cs.cx) / 2;,return CFrameWnd:PreCreateWindow(cs);,33,5.4窗口样式和状态,代码中,前面有“:”作用域符号的函数是指全局函数,一般都是一些API函数。“cs.style ”中的“”是按位取“反”运算符,它将WS_MAXIMIZEBOX的值按位取反后,再和cs.style值按位“与”,其结果是将cs.style值中的WS_MAXIMIZEBOX标志位清零。,再如,对于多文档应用程序,文档窗口的样式可用下列的代码更改:,BOOL CChildFrame:PreCreateWindow(CREATESTRUCT& cs),cs.style / 创建不含有最大化按钮的子窗口,return CMDIChildWnd:PreCreateWindow(cs);,3. 使用ModifyStyle和ModifyStyleEx,CWnd类中的成员函数ModifyStyle和ModifyStyleEx也可用来更改窗口的样式,其中ModifyStyleEx还可更改窗口的扩展样式。这两个函数具有相同的参数,其含义如下。,BOOL ModifyXXXX( DWORD,dwRemove, DWORD,dwAdd, UINT,nFlags,= 0 );,其中,参数dwRemove用来指定需要删除的样式,dwAdd用来指定需要增加的样式,nFlags表示SetWindowPos的标志,0(默认)表示更改样式的同时不调用SetWindowPos函数。,34,5.4窗口样式和状态,由于框架窗口在创建时不能直接设定其扩展样式,因此只能通过调用ModifyStyle函数来进行。例如用MFC ClassWizard为一个多文档应用程序Ex_MDI的子文档窗口类CChildFrame添加OnCreateClient消息处理,并增加下列代码:,BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext),ModifyStyle(0, WS_VSCROLL, 0);,return CMDIChildWnd:OnCreateClient(lpcs, pContext);,这样,当窗口创建客户区时就会调用虚函数OnCreateClient。运行结果如图5.11所示。,添加的滚动条,图5.11 为文档子窗口添加垂直滚动条,35,5.4窗口样式和状态,5.4.3 窗口状态改变,MFC AppWizard为每个窗口设置了相应的大小和位置,但默认的窗口状态有时并不那么令人满意,这时就需要对窗口状态进行适当的改变。,1. 用ShowWindow改变窗口的显示状态,当应用程序运行时,Windows会自动调用应用程序框架内部的WinMain函数,并自动查找该应用程序类的全局变量theApp,然后自动调用用户应用程序类的虚函数InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作,如下面的代码(以单文档应用程序项目Ex_SDI为例):,BOOL CEx_SDIApp:InitInstance(),m_pMainWnd-ShowWindow(SW_SHOW);/ 显示窗口,m_pMainWnd-UpdateWindow();/ 更新窗口,return TRUE;,代码中,m_pMainWnd是主框架窗口指针变量,ShowWindow是CWnd类的成员函数,用来按指定的参数显示窗口,该参数的值如表5.4所示。,36,5.4窗口样式和状态,通过指定ShowWindow函数的参数值可以改变改变窗口显示状态。例如下面的代码是将窗口的初始状态设置为“最小化”:,BOOL CEx_SDIApp:InitInstance(),.,m_pMainWnd-ShowWindow(,SW_SHOWMINIMIZED,);,m_pMainWnd-UpdateWindow();,return TRUE;,表5.4 ShowWindow函数的参数值,参数值,含 义,SW_HIDE,隐藏此窗口并将激活状态移交给其它窗口,SW_MINIMIZE,将窗口最小化并激活系统中的顶层窗口,SW_RESTORE,激活并显示窗口。若窗口是最小或最大状态时,则恢复到原来的大小和位置。,SW_SHOW,用当前的大小和位置激活并显示窗口,SW_SHOWMAXIMIZED,激活窗口并使之最大化,SW_SHOWMINIMIZED,激活窗口并使之最小化,SW_SHOWMINNOACTIVE,窗口显示成为一个图标并保留其激活状态(即原来是激活的,仍然是激活),SW_SHOWNA,用当前状态显示窗口,SW_SHOWNOACTIVATE,用最近的大小和位置状态显示窗口并保留其激活状态,SW_SHOWNORMAL,激活并显示窗口,37,5.4窗口样式和状态,需要说明的是,由于用户应用程序类继承了基类CWinApp的特性,因此也可在用户应用程序类中使用公有型(public)成员变量m_nCmdShow,通过对其进行赋值,同样能达到效果。例如上述代码可改写为:,BOOL CEx_SDIApp:InitInstance(),.,m_nCmdShow = SW_SHOWMINIMIZED;,m_pMainWnd-ShowWindow(m_nCmdShow);,m_pMainWnd-UpdateWindow();,return TRUE;,2. 用SetWindowPos或MoveWindow改变窗口的大小和位置,CWnd中的SetWindowPos是一个非常有用的函数;它不仅可以改变窗口的大小、位置,而且还可以改变所有窗口在堆栈排列的次序(Z次序),这个次序是根据它们在屏幕出现的先后来确定的。,38,5.4窗口样式和状态,BOOL SetWindowPos,(,const CWnd*,pWndInsertAfter,int,x,int,y,int,cx,int,cy,UINT,nFlags,);,其中,参数pWndInsertAfter表示窗口对象指针,它可以下列预定义窗口对象的地址:,wndBottom 将窗口放置在Z次序中的底层,wndTop 将窗口放置在Z次序中的顶层,wndTopMost 设置最顶窗口,wndNoTopMost 将窗口放置在所有最顶层的后面,若此窗口不是最顶窗口,则此标志无效,x和y表示窗口新的左上角坐标,cx和cy分别表示表示窗口新的宽度和高度,nFlags表示窗口新的大小和位置方式,如表5.5所示。,函数CWnd:MoveWindow也可用来改变窗口的大小和位置,与SetWindowPos函数 不同的是,用户必须在MoveWindow函数中指定窗口的大小。,void MoveWindow,(,int,x,int,y,int,nWidth,int,nHeight,BOOL,bRepaint,= TRUE,);,void MoveWindow,(,LPCRECT,lpRect,BOOL,bRepaint,= TRUE,);,其中,参数x和y表示窗口新的左上角坐标,nWidth和nHeight表示窗口新的宽度和高度,bRepaint用于指定窗口是否重绘,lpRect表示窗口新的大小和位置。,39,5.4窗口样式和状态,表5.5 常用nFlags值及其含义,nFlags值,含 义,SWP_HIDEWINDOW,隐藏窗口,SWP_NOACTIVATE,不激活窗口。如该标志没有被指定,则依赖pWndInsertAfter 参数,SWP_NOMOVE,不改变当前的窗口位置(忽略x和y参数),SWP_NOOWNERZORDER,不改变父窗口的Z次序,SWP_NOREDRAW,不重新绘制窗口,SWP_NOSIZE,不改变当前的窗口大小(忽略cx和cy参数),SWP_NOZORDER,不改变当前的窗口Z次序(忽略pWndInsertAfter参数),SWP_SHOWWINDOW,显示窗口,40,5.4窗口样式和状态,作为示例,这里将使用上述两个函数把主窗口移动到屏幕的(100,100)处(代码添在CEx_SDIApp:InitInstance中return TRUE语句之前)。,/ 使用SetWindowPos函数的示例,m_pMainWnd- SetWindowPos(NULL,100,100,0,0,SWP_NOSIZE|SWP_NOZORDER);,/ 使用MoveWindow函数的示例,CRect rcWindow;,m_pMainWnd-GetWindowRect(rcWindow);,m_pMainWnd-MoveWindow(100,100,rcWindow.Width(),rcWindow.Height(),TRUE);,当然,改变窗口的大小和位置的CWnd成员函数还不止以上两个。例如CenterWindow函数是使窗口居于父窗口中央,就像下面的代码:,CenterWindow(CWnd:GetDesktopWindow();/ 将窗口置于屏幕中央,AfxGetMainWnd()-CenterWindow();/ 将主框架窗口居中,41,5.5综合应用,创建一个默认的单文档应用程序Ex_A5,去除应用程序标题栏的“无标题”显示以及最大和最小框按钮,将框架窗口标题设置为“第5章综合应用”。程序开始运行时,使其显示大小指定为400 x 300,且在屏幕中居中显示。如图5.12所示。双击应用程序窗口的客户区,窗口消失,在系统托盘中显示一个空心圆圈图标,并每隔500ms在与MFC应用程序默认图标进行切换,单击托盘的图标,窗口恢复显示,托盘中的图标消失。,图5.12 综合应用,42,5.5综合应用,例Ex_A5 第五章综合应用,(,1,)创建一个默认的单文档应用程序,Ex_A5,。,(,2,)在,CMainFrame:OnCreate,中添加下列代码(用来设置框架窗口标题):,int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct), .,this-SetWindowText( 第5章综合应用 );,return 0;,(,3,)在,CMainFrame:PreCreateWindow,中修改,cs,风格,如下所示:,BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs),if( !CFrameWnd:PreCreateWindow(cs) ),return FALSE;,cs.style,cs.style,cs.style,return TRUE;,43,5.5综合应用,(,4,)在,CEx_A5App:InitInstance,中添加下列代码:,BOOL CEx_A5App:InitInstance(), ,m_pMainWnd-ShowWindow(SW_SHOW);,m_pMainWnd-UpdateWindow();,m_pMainWnd-SetWindowPos( NULL,0,0,400,300, SWP_NOZORDER );,m_pMainWnd-CenterWindow( );,return TRUE;,(,5,)编译运行。,(,6,)添加,1,个图标资源,打开“图像”(,Image,)菜单,选择“删除设备图像”(,Delete Device Image,)命令,这样,就删除“标准,32 x 32 ”,设备类型。,(,7,)单击“新建设备图像”按钮,选择“小的(,16 x 16,)”作为图标的设备类型,保留图标资源默认的,ID,号,IDI_ICON1,,制作如图,5.13,所示的空心圆圈图标。,44,5.5综合应用,图5.13 设计的图标,(,8,)由于框架窗口包含菜单、工具栏和状态栏等,用,MFC ClassWizard,为,CMainFrame,类添加,WM_LBUTTONDBLCLK,(双击鼠标消息)的消息映射是不会执行的(已被其菜单、工具栏和状态栏等子类对象获取)。因此,必须为,CMainFrame,类添加,PreTranslateMessage,重载来拦截,WM_LBUTTONDBLCLK,消息,,代码如下,:,45,5.5综合应用,(,9,)向,CMainFrame,类添加,DeleteTaskBarIcon,成员函数,其代码如下:,BOOL CMainFrame:DeleteTaskBarIcon(HWND hwnd, UINT uID),NOTIFYICONDATA tnid;,tnid.cbSize = sizeof(NOTIFYICONDATA);,tnid.hWnd = hwnd;,return Shell_NotifyIcon(NIM_DELETE, ,(,10,)用,MFC ClassWizard,为,CMainFrame,类添加,WM_DESTROY,消息映射,并添加下列代码:,void CMainFrame:OnDestroy(),CFrameWnd:OnDestroy();,KillTimer( 1 );,DeleteTaskBarIcon( m_hWnd, IDR_MAINFRAME );,46,5.5综合应用,(,11,)打开,MainFrm.h,文件,在类声明语句“,class CMainFrame : public CFrameWnd”,之前添加,WM_ICON_NOTIFY,的宏定义:,#define WM_ICON_NOTIFY(WM_USER+500),class CMainFrame : public CFrameWnd,(,12,)在,MainFrm.h,文件的,DECLARE_MESSAGE_MAP,前,添加,WM_ICON_NOTIFY,的消息映射函数的声明:,/AFX_MSG(CMainFrame),afx_msg void OnDestroy();,/AFX_MSG,void OnTrayNotify(WPARAM wParam, LPARAM lParam);,DECLARE_MESSAGE_MAP(),(,13,)打开,MainFrm.cpp,文件,在,CMainFrame,类的消息入口定义中添加消息宏指定,即将消息,WM_ICON_NOTIFY,与前面声明的消息函数,OnTrayNotify,相映射:,47,5.5综合应用,BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd),/AFX_MSG_MAP
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!