vc学习教程界面设计.ppt

上传人:cn****1 文档编号:568552762 上传时间:2024-07-25 格式:PPT 页数:58 大小:1.27MB
返回 下载 相关 举报
vc学习教程界面设计.ppt_第1页
第1页 / 共58页
vc学习教程界面设计.ppt_第2页
第2页 / 共58页
vc学习教程界面设计.ppt_第3页
第3页 / 共58页
vc学习教程界面设计.ppt_第4页
第4页 / 共58页
vc学习教程界面设计.ppt_第5页
第5页 / 共58页
点击查看更多>>
资源描述

《vc学习教程界面设计.ppt》由会员分享,可在线阅读,更多相关《vc学习教程界面设计.ppt(58页珍藏版)》请在金锄头文库上搜索。

1、第第6章框架窗口界面设计章框架窗口界面设计 6.16.1框架窗口框架窗口 6.26.2菜单菜单 6.36.3工具栏工具栏 6.46.4状态栏状态栏 6.56.5交互对象的动态更新交互对象的动态更新 6.66.6图标和光标图标和光标 6.16.1框架窗口框架窗口 6.1.1单文档和多文档程序框架窗口单文档和多文档程序框架窗口 文档应用程序的文档应用程序的MFC类结构类结构 如图是单文档应用程序Ex_SDI和多文档应用程序Ex_MDI的MFC类结构。 CAboutDlg是每一个应用程序框架都有的,用来显示本程序的有关信息。CEx_SDIApp和CEx_MDIApp是应用程序类,是从CWinApp类

2、派生而来,负责应用程序创建、运行和终止,每一个应用程序都需要这样的类。CEx_SDIDoc和CEx_MDIDoc是文档类,它们是从CDocument类派生而来,负责应用程序文档数据管理。CEx_SDIView和CEx_MDIView是视图类,它们既可以从基类CView派生,也可以从CView派生类派生,负责数据的显示、绘制和其他用户交互。CMainFrame类是用来负责主框架窗口的显示和管理,包括工具栏和状态栏等界面元素的初始化。对于单文档应用程序来说,主框架窗口类是从CFrameWnd派生而来的,而对于多文档应用程序程序,主框架窗口是从CMDIFrameWnd派生的。 6.16.1框架窗口框

3、架窗口CChildFrame类是从CMDIChildWnd派生而来,专门用来管理多文档应用程序中的 文 档 窗 口 。 无 论 是 CMDIChildWnd还 是 CMDIFrameWnd类 , 它 们 都 是 从CFrameWnd派生而来的。对于基于对话框的应用程序,一般有CAboutDlg类、应用程序类和对话框类。上述MFC类之间的继承和派生关系如图6.2所示。 图6.2MFC类的基本层次结构CCmdTargetCWndCDocumentCFrameWndCObjectCWinTreadCWinAppCViewCDialog及控件CMDIChildWndCMDIFrameWndCMiniF

4、rameWnd6.16.1框架窗口框架窗口项目的文件组织项目的文件组织 项目中源文件都是采用文件夹的方式进行管理的,将项目名作为文件夹名,此文件夹下包含源程序代码文件、项目文件以及项目工作区文件等。每一个类的源代码均保存同名的h和cpp文件。其他一些文件类型的含义:.opt 关于开发环境的参数文件,如工具条位置等信息 .aps(AppStudio File)资源辅助文件,二进制格式.clw ClassWizard信息文件.dsp(DeveloperStudio Project)项目文件.plg 编译信息文件.mdp(Microsoft DevStudio Project)旧版本的项目文件.bs

5、c 用于浏览项目信息.map 执行文件的映像信息纪录文件.pch(Pre-Compiled File)预编译文件,可以加快编译速度,但是文件非常大.pdb(Program Database)记录程序有关的一些数据和调试信息.ncb 无编译浏览文件(no compile browser) 还有相应的Debug(调试)、Res(资源)等子文件夹。用应用程序向导创建项目时,系统自动为项目创建Win32 Debug版本的运行程序,并使用相应的默认配置。程序编连后,用于该项目的可执行文件以及其他调试的信息文件都安放在Debug文件夹中。 程序项目有一个Win32 Release版本,与Release的区

6、别在于:Debug版本的运行程序有相应的调试信息码,Release版本的运行程序没有,但Release版本的运行程序经过代码的优化,其程序的运行效率被最大提升。 选择“编译”“配置”菜单命令,在“配置”对话框将项目设置成Win32 Release版本。 6.16.1框架窗口框架窗口主框架窗口和文档窗口主框架窗口和文档窗口 主框架窗口是直接放置在桌面(DeskTop)上的那个窗口,每个应用程序只能有一个主框架窗口。主框架窗口负责管理各个用户交互对象并根据用户操作相应地创建或更新文档窗口及其视图。 文档窗口对SDI程序来说,和主框架窗口是一致的,主框架窗口就是文档窗口;对于MDI程序,文档窗口是主

7、框架窗口的子窗口,如图。 文档窗口一般都有相应的可见边框,它的客户区(除了窗口标题栏、边框外的区域)是由相应的视图来构成的,因此可以说视图是文档窗口内的子窗口。文档窗口时刻跟踪当前处于活动状态的视图的变化,并将用户或系统产生的消息传递给当前活动视图。 6.16.1框架窗口框架窗口6.1.2窗口状态的改变窗口状态的改变MFC AppWizard为每个窗口设置了相应的大小和位置。运行程序时,会自动调用框架内部的WinMain函数,并自动查找该应用程序类的全局变量theApp,然后自动调用用户应用程序类的虚函数InitInstance,该函数会进一步调用相应的函数来完成主窗口的构造和显示工作,代码:

8、BOOL CEx_SDIApp:InitInstance()m_pMainWnd-ShowWindow(SW_SHOW);/ 显示窗口m_pMainWnd-UpdateWindow();/ 更新窗口return TRUE; m_pMainWnd是主框架窗口指针变量,ShowWindow是CWnd类的成员函数,用来按指定的参数显示窗口。 6.16.1框架窗口框架窗口通过指定ShowWindow函数的参数值可以改变改变窗口显示状态。例如下面的代码是将窗口的初始状态设置为“最小化”:BOOL CEx_SDIApp:InitInstance().m_pMainWnd-ShowWindow(SW_SHO

9、WMINIMIZEDSW_SHOWMINIMIZED);m_pMainWnd-UpdateWindow();return TRUE; 6.16.1框架窗口框架窗口6.1.3窗口风格的设置窗口风格的设置 窗口风格窗口风格 通常有一般和扩展两种形式。可在函数CWnd:Create或CWnd:CreateEx参数中指定,CreateEx函数可同时支持以上两种风格,CWnd:Create只能指定窗口的一般风格。控件和对话框的窗口风格可直接通过其属性对话框来设置。 除了上述风格外,框架窗口还有以下三个自己的风格。它们都可以在PreCreateWindow重载函数的CREATESTRUCT结构中指定。 F

10、WS_ADDTOTITLE该风格指定相关的信息如文档名添加到框架窗口标题的后面。 FWS_PREFIXTITLE 该风格使得框架窗口标题中的文档名显示在应用程序名之前。 FWS_SNAPTOBARS 该风格用来调整窗口的大小,使它刚好包含了框架窗口中的控制栏。 6.16.1框架窗口框架窗口在在MFC AppWizard中进行修改中进行修改 例例Ex_SDI 在向导中修改窗口风格。 (1)(1)选择“文件”“新建”,选择“工程”,选择MFC AppWizard(exe)的项目类型,指定项目工作文件夹位置,输入项目名Ex_SDI,单击确定按钮。(2)(2)在向导的第一步中,将应用程序类型选为“单个

11、文档”(SDI)。(3) (3) 单击下一个,如图,可以选择程序中是否加入数据库的支持。(4)(4)单击下一个,出现向导的第三步对话框,如图,允许在程序中加入复合文档、自动化、ActiveX控件的支持。 6.16.1框架窗口框架窗口(5)(5)单击下一个,如图,对话框的前几项依次确定对浮动工具条、打印与预览以及通信网络等特性的支持。对话框的最后两项是最近文件列表数目的设置(默认时为4)和一个高级按钮 。6.16.1框架窗口框架窗口(6)(6)在第四步对话框中,单击高级,如图,分别用于文档模板字串资源内容和窗口风格的修改。 6.16.1框架窗口框架窗口(7)(7)单击关闭,单击下一个,如图。可选

12、择:应用程序的主窗口是MFC标准风格还是窗口左边有切分窗口的浏览器风格,在源文件中是否加入注释用来引导用户编写程序代码,是使用动态链接库(DLL)还是静态链接库。(8)(8)单击下一个按钮,出现如图6.9所示的对话框。在这里,用户可以对MFC AppWizard提供的默认类名、基类名、各个源文件名进行修改。 6.16.1框架窗口框架窗口(9)(9)单击完成,单击确定,回到主界面。在向导中作出的选择,有部分内容反映在CEx_SDIApp:InitInstance函数中,代码:BOOL CEx_SDIApp:InitInstance()/ 若用户在MFC AppWizard的第三步中,选中了“Ac

13、tiveX Controls”,/ 则表示所创建的应用程序支持ActiveX控件AfxEnableControlContainer(); / 若用户在MFC AppWizard的第四步中,选中了“3D controls”/ 则表示所创建的应用程序支持3D控件风格#ifdef _AFXDLLEnable3dControls();/ 使用MFC动态链接库的3D控件#elseEnable3dControlsStatic();/ 使用MFC静态链接库的3D控件#endif/ 在Windows系统注册表中登记应用程序的主键值,以便将一些与应用程序/ 相关的参数存放在该主键值下SetRegistryKey

14、(_T(Local MFC AppWizard-Generated Applications);/ 从注册表中调入应用程序的一些标准参数值,其中包括最近文件列表的文件名LoadStdProfileSettings(); return TRUE; 6.16.1框架窗口框架窗口修改修改CREATESTRUCT结构结构 窗口创建前,自动调用PreCreateWindow虚函数。用MFC AppWizard创建文档应用程序结构时,MFC已为主窗口或文档窗口类自动重载了该虚函数。可以在此函数中通过修改CREATESTRUCT结构来设置窗口的绝大多数风格。对于多文档应用程序,文档窗口的风格可用下列的代码更

15、改:BOOL CChildFrame:PreCreateWindow(CREATESTRUCT& cs) / 创建不含有最大化按钮的子窗口cs.style &= WS_MAXIMIZEBOX; / 调用基类的PreCreateWindow函数return CMDIChildWnd:PreCreateWindow(cs); 6.16.1框架窗口框架窗口使用使用ModifyStyle和和ModifyStyleEx ModifyStyleEx可更改窗口的扩展风格。两个函数具有相同的参数,含义。BOOL ModifyXXXX( DWORD dwRemove, DWORD dwAdd, UINT nFl

16、ags = 0 );参数dwRemove指定需要删除的风格,dwAdd指定需要增加的风格,nFlags表示SetWindowPos的标志。 框架窗口设定扩展风格只能通过调用ModifyStyle函数来进行。例如用MFC ClassWizard为一个多文档应用程序Ex_MDI的子文档窗口类CChildFrame添加OnCreateClient消息处理,并增加下列代码:BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) ModifyStyle(0, WS_VSCROLL, 0);return

17、CMDIChildWnd:OnCreateClient(lpcs, pContext); 6.16.1框架窗口框架窗口6.1.4改变窗口的大小和位置改变窗口的大小和位置CWnd类 的 成 员 函 数 SetWindowPos或 MoveWindow可 以 改 变 窗 口 的 大 小 和 位 置 。SetWindowPos可以改变窗口的大小、位置,还可以改变所有窗口在堆栈排列的次序(Z次序),这个次序是根据它们在屏幕出现的先后来确定的。BOOL BOOL SetWindowPosSetWindowPos( const const CWndCWnd* * pWndInsertAfter, inti

18、nt x, intint y, intint cx, intint cy, UINTUINT nFlags );参数pWndInsertAfter表示窗口对象指针,下列预定义窗口对象的地址:wndBottom将窗口放置在Z次序中的底层wndTop 将窗口放置在Z次序中的顶层wndTopMost 设置最顶窗口wndNoTopMost 将窗口放置在所有最顶层的后面,若此窗口不是最顶窗口,则此标志无效。x和y表示窗口新的左上角坐标,cx和cy分别表示表示窗口新的宽度和高度,nFlags表示窗口新的大小和位置方式。 6.16.1框架窗口框架窗口 函 数 CWnd:MoveWindow也 可 用 来 改

19、 变 窗 口 的 大 小 和 位 置 , 必 须 在MoveWindow函数中指定窗口的大小。void void MoveWindowMoveWindow( intint x, intint y, intint nWidth, intint nHeight, BOOLBOOL bRepaint = TRUE = TRUE );void void MoveWindowMoveWindow( LPCRECTLPCRECT lpRect, BOOLBOOL bRepaint = TRUE= TRUE );参数x和y表示 窗口新的左上角坐标,nWidth和nHeight表示窗口新的宽度和高度,bRep

20、aint用于指定窗口是否重绘,lpRect表示窗口新的大小和位置。 例如,在CEx_SDIApp:InitInstance中return TRUE语句之前添加下列代码,可以使主框架窗口移动到屏幕的(100,100)处:/ 若使用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,r

21、cWindow.Width(),rcWindow.Height(),TRUE);CRect是一个矩形类,GetWindowRect是一个CWnd类的成员函数,用来获取窗口在屏幕的位置和大小。 6.2菜单菜单 许多程序员对于菜单的设计都遵循下列一些规则:l若选择某菜单项会弹出一对话框,那么在该菜单项文本后有“”。l若某项菜单有子菜单,那么在该菜单项文本后有“”。l若菜单项需要助记符,用括号将带下划线的字母括起来。助记符与Alt构成一个组合键,当按住“Alt”键不放,敲击该字母时,对应的菜单项就会被选中。l 若某项菜单需要快捷键的支持,则一般将其列在相应菜单项文本之后。所谓“快捷键”是一个组合键,

22、如Ctrl+N,使用时是先按下“Ctrl”健不放,然后再按“N”键。任何时候按下快捷键,相应的菜单命令都会被执行。 图6.11菜单样例子6.2菜单菜单6.2.1更改应用程序菜单更改应用程序菜单 菜单“文件”“打开工作区”。在工作区中选择ResourceView页面,双击资 源 “Menu”中 的 IDR_MAINFRAME, 通 过 菜 单 编 辑 器 修 改 菜 单 资 源IDR_MAINFRAME ,可以为程序重新指定一个菜单,下面的示例过程:(1)(1)打开前面的单文档应用程序Ex_SDI。(2) (2) 按快捷键Ctrl+R,在资源类型中选定“Menu”,如图。 (3) (3) 单击新

23、建,如图。 6.2菜单菜单(4)(4)在Menu的ID_MENU1上右击鼠标,选择“Properties”命令,如图,可以重新指定菜单资源ID,设置菜单资源的语言和条件,这个条件用来决定菜单资源包含到哪个环境中,例如当指定条件为_DEBUG,则菜单资源只存在于Debug编译环境中。 (5)(5)菜单ID_MENU1添加一个顶层弹出菜单项“测试(&T)”,并在该菜单下添加一个子菜单项“返回(&R)”,ID设为ID_TEST_RETURN,如图。 (6)(6)打开Ex_SDI程序菜单资源IDR_MAINFRAME,在“查看”菜单的最后添加一个子菜单项“显示测试菜单(&M)”,ID设为ID_VIEW

24、_TEST。(7)(7)为CMainFrame类添加一个CMenu类型的成员变量m_NewMenu,CMenu类是用来处理菜单的一个MFC类。 6.2菜单菜单(8)(8)按快捷键Ctrl+W,切换到Message Maps页面,从“Class name”列表中选择CMainFrame,分别为菜单项ID_VIEW_TEST和ID_TEST_RETURN添加COMMAND消息映射,使用默认的消息映射函数名,并添中下列代码:void CMainFrame:OnViewTest() m_NewMenu.Detach();/ 使菜单对象和菜单句柄分离m_NewMenu.LoadMenu( IDR_MEN

25、U1 ); SetMenu(NULL); / 清除应用程序菜单SetMenu( &m_NewMenu ); / 设置应用程序菜单void CMainFrame:OnTestReturn() m_NewMenu.Detach();m_NewMenu.LoadMenu( IDR_MAINFRAME );SetMenu(NULL);SetMenu( &m_NewMenu ); LoadMenu装载菜单资源,Detach使菜单对象与菜单句柄分离。调用LoadMenu后,菜单对象m_NewMenu就拥有一个菜单句柄,再次调用LoadMenu时,发生运行时错误,当菜单对象与菜单句柄分离后,就可以再创建菜单

26、。SetMenu是CWnd类的一个成员函数,用来设置应用程序的菜单。(9)(9)编译运行并测试。 6.2菜单菜单6.2.2使用键盘快捷键使用键盘快捷键 通过上述的菜单系统,可以选择几乎所有可用的命令和选项,保证了菜单命令系统的完整性,菜单系统操作效率不高。对于那些反复使用的命令,有必要进一步提高效率,于是加速键应运而生。 一个加速键就是一个按键或几个按键的组合,用于激活特定的命令。加速键也是一种资源。 例如:为前面两个菜单ID_VIEW_TEST和ID_TEST_RETURN定义键盘快捷键:(1)(1)打开上例的工作区窗口中Accelerator的资源项,双击IDR_MAINFRAME,如图。

27、 6.2菜单菜单(2)(2)建立一新的加速键,双击加速键列表的最下端的空行,弹出如图的“Accel Properities”(加速键属性)对话框,可设置的属性如表。 6.2菜单菜单(3)(3)选择Ex_SDI添加的“显示测试菜单”菜单项ID_VIEW_TEST作为要联用的加速键的ID号,然后单击下一键按钮,并按下Ctrl+1作为此加速键的键值。(4)(4)按同样的方法,为菜单项ID_TEST_RETURN添加加速键Ctrl+2。需要说明的是,为了使其他用户能查看并使用该加速键,还需在相应的菜单项文本后面添加加速键内容。例如,可将ID_VIEW_TEST菜单项的标题改成“显示测试菜单(&M)tC

28、trl+1”,其中“t”是将后面的“Ctrl+1”定位到一个水平制表位。(5)(5)编译运行并测试。当程序运行后,按“Ctrl+1”和“Ctrl+2”将执行相应的菜单命令。 6.2菜单菜单6.2.3菜单的编程控制菜单的编程控制 创建菜单创建菜单 CreateMenu和CreatePopupMenu用来创建一个菜单或子菜单框架,原型:BOOL CreateMenu( );/ 产生一个空菜单BOOL CreatePopupMenu( );/ 产生一个空的弹出式子菜单 装入菜单资源装入菜单资源 需调用CMenu成员函数LoadMenu,再用SetMenu对应用程序菜单进行重新设置。BOOL Load

29、Menu( LPCTSTR lpszResourceName );BOOL BOOL LoadMenuLoadMenu( UINT ( UINT nIDResource ); );lpszResourceName为菜单资源名称,nIDResource为菜单资源ID号。 添加菜单项添加菜单项 可以调用AppendMenu或InsertMenu函数来添加菜单项。AppendMenu是将菜单项添加在菜单的末尾处,InsertMenu在指定位置处插入菜单项,将后面的菜单项依次下移。BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lps

30、zNewItem = NULL );BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );nIDNewItem表示新菜单项的ID号,lpszNewItem

31、表示新菜单项的内容,pBmp用于菜单项的位图指针,nPosition表示新菜单项要插入的菜单项位置。nFlags表示要增加的新菜单项的状态信息。 6.2菜单菜单注意:注意:l当nFlags为MF_BYPOSITION时,nPosition表示新菜单项要插入的具体位置,为0时表示第一个菜单项,为 -1时,将菜单项添加菜单的末尾处。lnFlags的标志中,可以用“|”(按位或)来组合。有些组合是不允许的,例如MF_DISABLED、MF_ENABLED和MF_GRAYED,MF_STRING、MF_OWNERDRAW、MF_SEPARATOR和位图,MF_CHECKED和MF_UNCHECKED

32、都不能组合在一起。l当菜单项增加后,不管菜单依附的窗口是否改变,都应调用CWnd:DrawMenuBar来更新菜单。 6.2菜单菜单删除菜单项删除菜单项 DeleteMenu函数可将菜单项删除,注注意意:调用该函数后,不管菜单依附的窗口是否改变,都应调用CWnd:DrawMenuBar使菜单更新。函数原型:BOOL BOOL DeleteMenuDeleteMenu( UINT ( UINT nPosition, UINT , UINT nFlags ); );nPosition表示要删除菜单项位置,由nFlags进行说明。nFlags为MF_BYCOMMAND时,nPosition表示菜单项

33、ID号,nFlags为MF_BYPOSITION时,nPosition表示菜单项的位置。 获取菜单项获取菜单项 下面四个CMenu成员函数分别获得菜单的项数、菜单项的ID号、菜单项的文本内容以及弹出式子菜单的句柄。UINT UINT GetMenuItemCountGetMenuItemCount( ) const;/( ) const;/用来获得菜单的菜单项数。UINT UINT GetMenuItemIDGetMenuItemID( ( intint nPos ) ) const;/const;/用来获得由nPos指定菜单项位置的菜单项的标识号。intint GetMenuStringGe

34、tMenuString( ( UINT UINT nIDItem, , CStringCString& & rString, , UINT UINT nFlags ) ) const;const;/获得由nIDItem指定菜单项位置的菜单项的文本内容,由rString参数返回,nFlags为MF_BYPOSITION时,nPosition表示菜单项的位置。CMenuCMenu* * GetSubMenuGetSubMenu( ( intint nPos ) const; ) const; /用来获得指定菜单的弹出式菜单的菜单句柄。 6.2菜单菜单示例示例 示例过程利用CMenu成员函数向应用程

35、序菜单中添加并处理一个菜单项:(1)(1)打开前面的单文档应用程序Ex_SDI或重新创建。(2) (2) “查看”菜单“Resource Symbols”,如图。(3) 单击新建,如图。在名字框中输入标识符ID_NEW_MENUITEM。在值框中输入ID的值,单击确定。 6.2菜单菜单(4)(4)关闭“资源符号”对话框,在CMainFrame:OnCreate函数中添加下列代码。int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct).CMenu* pSysMenu = GetMenu();/ 获得程序菜单指针CMenu* pSubMenu

36、= pSysMenu-GetSubMenu(1);/ 获得第二个子菜单的指针CString StrMenuItem(新的菜单项);pSubMenu-AppendMenu(MF_SEPARATOR);/ 增加一水平分隔线pSubMenu-AppendMenu(MF_STRING,ID_NEW_MENUITEM,StrMenuItem);/ 在子菜单中增加一菜单项/ 允许使用ON_UPDATE_COMMAND_UI或ON_COMMAND的菜单项m_bAutoMenuEnable = FALSE; / 关闭系统自动更新菜单状态pSysMenu-EnableMenuItem(ID_NEW_MENUIT

37、EM,MF_BYCOMMAND|MF_ENABLED);/ 激活菜单项DrawMenuBar();/ 更新菜单return 0; 6.2菜单菜单(5)(5)用MFC ClassWizard处理OnCommand消息并检测用户菜单的nID参数。BOOL CMainFrame:OnCommand(WPARAM wParam, LPARAM lParam) / wParam的低字节表示菜单、控件、加速键的命令IDif (LOWORD(wParam) = ID_NEW_MENUITEM) MessageBox(你选中了新的菜单项);return CFrameWnd:OnCommand(wParam,

38、lParam);(6)(6)编译运行并测试。这样当选择菜单“编辑”“新的菜单项”命令后,就会弹一个对话框,显示“你选中了新的菜单项”消息。 6.2菜单菜单6.2.4使用快捷菜单使用快捷菜单 快捷菜单实现函数快捷菜单实现函数 用资源编辑器和MFC库的CMenu:TrackPopupMenu函数可以创建这样的菜单,CMenu:TrackPopupMenu函数原型:BOOL BOOL TrackPopupMenuTrackPopupMenu( ( UINT UINT nFlags, , intint x, , intint y, , CWndCWnd* * pWnd, , LPCRECT LPCRE

39、CT lpRect = NULL ); = NULL );用来显示一个浮动的弹出式菜单。nFlags表示菜单在屏幕显示的位置以及鼠标按钮标志,如表。x和y表示菜单的水平坐标和菜单的顶端的垂直坐标。pWnd表示弹出菜单的窗口,此窗口将收到菜单全部的WM_COMMAND消息。lpRect是一个RECT结构或CRect对象指针,表示一个矩形区域,单击这个区域时,弹出菜单不消失。lpRect为NULL时,在菜单外面单击鼠标,菜单立刻消失。 6.2菜单菜单示例示例 显示主菜单IDR_MAINFRAME时,右击鼠标弹出“查看”菜单的子菜单,显示菜单IDR_MENU1时,右击鼠标弹出“测试”菜单的子菜单。具

40、体步骤:(1)(1)打开前面的单文档应用程序Ex_SDI。(2)(2)在CMainFrame类添加WM_CONTEXTMENU消息映射,函数代码。void CMainFrame:OnContextMenu(CWnd* pWnd, CPoint point) CMenu* pSysMenu = GetMenu();/ 获得程序菜单指针int nCount = pSysMenu-GetMenuItemCount();/ 获得顶层菜单个数int nSubMenuPos = -1;for (int i=0; iGetMenuString(i, str, MF_BYPOSITION);if (str.L

41、eft(4) = “查看”) | (str.Left(4) = “测试”)nSubMenuPos = i;break;if (nSubMenuPosGetSubMenu( nSubMenuPos) -TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);(3)(3)编译运行并测试。 6.36.3工具栏工具栏 6.3.1使用工具栏编辑器使用工具栏编辑器 创建一个新的工具栏按钮创建一个新的工具栏按钮 双击新建的工具栏中最右端的空按钮弹出属性框,在ID框中输入名称,右端出现一个空按钮。单击该按钮,在资源编辑器的工具

42、按钮设计窗口内进行编辑,这个编辑就是绘制一个工具按钮的位图。 移动一个按钮移动一个按钮鼠标左键点中它并拖动至相应位置。如果用户拖动它离开工具栏位置,则此按钮从工具栏中消失。若在移动一个按钮的同时,按下Ctrl键,则在新位置复制一个按钮,新位置可以是同一个工具栏中的其他位置,也可以在不同的工具栏中。 删除一个按钮删除一个按钮 将选取中的按钮拖离工具栏就消失了。若选中按钮,Delete键不能删除,将按钮中的图形全部以背景色填充。 在工具栏中插入空格在工具栏中插入空格 如果按扭前没有任何空格,拖动该按钮向右移动并当覆盖相邻按钮的一半以上时,释放鼠标键,则此按钮前出现空格。如果按钮前有空格而按钮后没有

43、空格,拖动该按钮向左移动并当按钮的左边界接触到前面按钮时,释放鼠标键,则此按钮后将出现空格。 如果按钮前后均有空格,拖动该按钮向右移动并当接触到相邻按钮时,则此按钮前的空格保留,按钮后的空格消失。相反,拖动该按钮向左移动并当接触到前一个相邻按钮时,则此按钮前面的空格消失,后面的空格保留。 6.36.3工具栏工具栏工具栏按钮属性的设置工具栏按钮属性的设置 6.36.3工具栏工具栏6.3.2工具按钮和菜单项相结合工具按钮和菜单项相结合 指选择工具按钮或菜单命令时,操作结果是一样的。使它们结合的具体方法是在工具按钮的属性对话框中将按钮的ID号设置为相关联的菜单项ID。例例如如: :示例是在前面Ex_

44、SDI上进行的,通过两个工具按钮分别显示主菜单IDR_MAINFRAME和菜单IDR_MENU1。具体步骤:(1)(1)打开前面的单文档应用程序Ex_SDI。(2) (2) 利用工具栏编辑器设计两个工具按钮,如图。 6.36.3工具栏工具栏(3)(3)双击设计的第一个工具按钮,将工具按钮的ID号设为ID_TEST_RETURN,在提示框内键入“返回应用程序主菜单n返回主菜单”。(4)(4)双击设计的第二个工具按钮,将工具按钮的ID号设为ID_VEW_TEST,在提示框内键入“显示测试菜单n显示测试菜单”。(5) (5) 编译运行并测试。将鼠标移至设计的第一个工具按钮处,这时在状态栏上显示出“返

45、回应用程序主菜单”信息,若稍等片刻后,还会弹出提示小窗口,显示出“返回主菜单”字样,如图。单击新添加的这两个按钮,会执行相应的菜单命令。 6.36.3工具栏工具栏6.3.3多个工具栏的使用多个工具栏的使用操作步骤如下:(1)(1)打开前面的单文档应用程序Ex_SDI。(2)(2)将工作区切换到ResourceView,展开Toolbar(工具栏)资源,用鼠标单击IDR_MAINFRAME不松开,按Ctrl,将IDR_MAINFRAME拖到Toolbar资源名称上。(3)(3)右击工具栏资源IDR_MAINFRAME1,选择Properties命令,如图。(4)(4)双击IDR_TOOLBAR1

46、,按图删除不要的工具按钮。(5)(5)在CMainFrame类中添加一个成员变量m_wndTestBar,变量类型为CToolBar。CToolBar类封装了工具栏的操作。 6.36.3工具栏工具栏(6)(6)在CMainFrame:OnCreate函数中添加下面的工具栏创建代码:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;int nRes = m_wndTestBar.CreateEx(this, TBSTYLE_FLAT

47、, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,CRect(0,0,0,0),AFX_IDW_TOOLBAR + 10);if (!nRes | !m_wndTestBar.LoadToolBar(IDR_TOOLBAR1)TRACE0(Failed to create toolbarn);return -1; / fail to createm_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);m_wndTest

48、Bar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);DockControlBar(&m_wndTestBar);return 0; 6.36.3工具栏工具栏(7)(7)编译运行,如图。 (8)(8) 需要调用CFrameWnd类的成员函数ShowControlBar来使程序一开始运行时隐藏工具栏IDR_TOOLBAR1。在CMainFrame:OnCreate中添加代码:int CMainFrame:OnCreate(LPCREATESTRUCT lpCrea

49、teStruct)ShowControlBar( &m_wndTestBar, FALSE, FALSE );/ 关闭测试工具栏return 0;6.36.3工具栏工具栏(9)(9)在CMainFrame:OnViewTest和CMainFrame:OnTestReturn中添加代码:void CMainFrame:OnViewTest() ShowControlBar( &m_wndTestBar, TRUE, FALSE );/ 显示测试工具栏ShowControlBar( &m_wndToolBar, FALSE, FALSE );/ 关闭主工具栏void CMainFrame:OnTe

50、stReturn() ShowControlBar( &m_wndTestBar, FALSE, FALSE );/ 关闭测试工具栏ShowControlBar( &m_wndToolBar, TRUE, FALSE );/ 显示主工具栏(10)(10) 编译运行并测试,如图,左边开始运行的结果,右边是单击按钮运行的结果。 6.46.4状态栏状态栏 6.4.1状态栏的定义状态栏的定义 AppWizard创建的SDI或MDI应用程序框架中,有一个静态的indicator数组,是在MainFrm.cpp文件中定义的,被MFC用作状态栏的定义。 数组中的元素是一些标识常量或是字串资源的ID号。图列出

51、了indicators数组元素与标准状态栏窗格的关系。 StaticUINTindicators=ID_SEPARATOR,ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,图6.28indicators数组的定义6.46.4状态栏状态栏6.4.2状态栏的常用操作状态栏的常用操作 增加和减少窗格增加和减少窗格 在状态栏中增加信息行窗格,在indicators数组中增加一个ID_SEPARATOR标识;在状态栏中增加指示器窗格,在indicators数组中增加一个在字符串表中定义过的资源ID。状态栏减少一个窗格,只需减少indicators

52、数组元素。 在状态栏上显示文本在状态栏上显示文本 调用CStatusBar:SetPaneText函数更新任何窗格中的文本。函数原型:BOOL BOOL SetPaneTextSetPaneText( ( intint nIndex, , LPCTSTRLPCTSTR lpszNewText, , BOOLBOOL bUpdate = TRUE );TRUE );示例示例 (1)(1)创建一个默认的单文档应用程序Ex_SDIMouse。(2)(2)将工作区切换到ClassView页面,展开CMainFrame,双击CMainFrame,在文档窗口中出现该函数的定义,在它的前面就是状态栏数组的定

53、义。(3)(3)将状态栏indicators数组的定义改为下列代码:static UINT indicators =ID_SEPARATOR, ID_SEPARATOR, ; 6.46.4状态栏状态栏(4)(4)在CEx_SDIMouseView类中添加CMainFrame类的代码。CEx_SDIMouseView:OnMouseMove代码:void CEx_SDIMouseView:OnMouseMove(UINT nFlags, CPoint point) CString str;CMainFrame* pFrame=(CMainFrame*)AfxGetApp()-m_pMainWnd

54、; / 获得主窗口指针CStatusBar* pStatus=&pFrame-m_wndStatusBar; / 获得主窗口中的状态栏指针if (pStatus) str.Format(X=%d, Y=%d,point.x, point.y);/ 格式化文本pStatus-SetPaneText(1,str);/ 更新第二个窗格的文本CView:OnMouseMove(nFlags, point); 6.46.4状态栏状态栏(5)(5)将MainFrm.h文件中的受保护变量m_wndStatusBar变成公共变量。(6)(6)在Ex_SDIMouseView.cpp文件的开始处增加下列语句:#

55、include Ex_SDIMouseView.h#include MainFrm.h“(7)(7)编译并运行,如图。 6.46.4状态栏状态栏6.4.3改变状态栏的风格改变状态栏的风格 在MFC的CStatusBar类中,有两个成员函数可以改变状态栏风格,它们是:void void SetPaneInfoSetPaneInfo( ( intint nIndex, UINT, UINT nID, UINT, UINT nStyle, , intint cxWidth ); );void void SetPaneStyleSetPaneStyle( ( intint nIndex, UINT,

56、UINT nStyle ); ); 参数nIndex表示要设置的状态栏窗格的索引,nID为状态栏窗格指定新的ID,cxWidth表示窗格的像素宽度,nStyle表示窗格的风格类型,指定窗格的外观,例如SBPS_POPOUT表示窗格是凸起来的,见表。 6.56.5交互对象的动态更新交互对象的动态更新 在前面Ex_SDI基础上,单击工具按钮,该按钮被按下,按钮弹起,单击工具按钮时,该按钮被按下,按钮弹起,如此反复。具体步骤: (1)(1)打开上例的单文档应用程序项目Ex_SDI。(2)(2)为CMainFrame添加一个BOOL型的成员变量m_bMainWork,将m_bMainWork的初值设为

57、TRUE。(3)(3)在CMainFrame类中添加工具按钮ID_VIEW_TEST和ID_TEST_RETURN的UPDATE_COMMAND_UI消息映射函数,添加代码:void CMainFrame:OnUpdateViewTest(CCmdUI* pCmdUI) pCmdUI-Enable( TRUE );pCmdUI-SetCheck( !m_bMainWork );void CMainFrame:OnUpdateTestReturn(CCmdUI* pCmdUI) pCmdUI-Enable( TRUE );pCmdUI-SetCheck( m_bMainWork ); 6.56.

58、5交互对象的动态更新交互对象的动态更新(4)(4)在CMainFrame:OnViewTest和CMainFrame:OnTestReturn添加代码:void CMainFrame:OnViewTest() m_bMainWork = FALSE;void CMainFrame:OnTestReturn() m_bMainWork = TRUE;(5)(5)编译运行并测试,如图。 6.6图标和光标图标和光标 6.6.1使用图形编辑器使用图形编辑器 创建一个新的图标或光标创建一个新的图标或光标 创建应用程序后,按快捷键Ctrl+R打开“插入资源”,选择Cursor(光标)或Icon(图标)资源

59、类型,单击新建。如图。创建新图标或光标的时,图形编辑器先创建的是一个适合于VGA环境中的图像,开始的时候它以屏幕色(透明方式)来填充。如表。 新设备按钮6.6图标和光标图标和光标选用和定制显示设备选用和定制显示设备 图形编辑器上,有一个New Device Image按钮,单击,如图。 单击定制,如图。设置光标热点设置光标热点 借助光标“热点”确定光标实际的位置。如图。 设置热点按钮6.6图标和光标图标和光标6.6.2图标图标 图标的调入和清除图标的调入和清除 CWinApp:LoadIcon可将一个图标资源调入并返回一个图标句柄。原型:HICON HICON LoadIconLoadIcon

60、( LPCTSTR ( LPCTSTR lpszResourceName ) const; ) const;HICON HICON LoadIconLoadIcon( UINT ( UINT nIDResource ) const; ) const; 不 想 创 建 新 的 图 标 资 源 , 可 使 用 预 定 义 的 标 准 图 标 , 调 用CWinApp:LoadStandardIcon ,原型:HICON LoadStandardIcon( LPCTSTR lpszIconName ) const;lpszIconName可以是下列值之一:IDI_APPLICATION 默认的应用程

61、序图标IDI_HAND 手形图标(用于严重警告)IDI_QUESTION 问号图标(用于提示消息)IDI_EXCLAMATION 警告消息图标(惊叹号)IDI_ASTERISK 消息图标DestroyIcon可以用来删除一个图标,释放为图标分配的内存,原型:BOOL BOOL DestroyIconDestroyIcon( HICON ( HICON hIcon ); );hIcon用来指定要删除的图标句柄。 图标的绘制图标的绘制 函数CDC:DrawIcon将一个图标绘制在指定的位置处,原型:BOOL BOOL DrawIconDrawIcon( ( intint x, , intint y

62、, HICON , HICON hIcon ); );BOOL DrawIcon( POINT point, HICON hIcon ); 6.6图标和光标图标和光标应用程序图标的改变应用程序图标的改变 使用GetClassLong和SetClassLong重新指定应用程序窗口的图标,原型:DWORD DWORD SetClassLongSetClassLong( HWND ( HWND hWnd, , intint nIndex, LONG , LONG dwNewLong););DWORD DWORD GetClassLongGetClassLong( HWND ( HWND hWnd,

63、, intint nIndex););hWnd用来指定窗口类句柄,dwNewLong 用来指定新的32位值。nIndex用来指定与WNDCLASSEX结构相关的索引,它可以是下列值之一:GCL_HBRBACKGROUND 窗口类的背景画刷句柄GCL_HCURSOR 窗口类的的光标句柄GCL_HICON窗口类的的图标句柄GCL_MENUNAME 窗口类的的菜单资源名称示例示例 例例Ex_Icon Ex_Icon 改变应用程序图标。(1)(1)用MFC AppWizard创建一个默认的单文档应用程序Ex_Icon。(2)(2) 新添四个图标资源,通过图像设备选择对话框(参见图6.32)。图标资源I

64、D号分别为默认的IDI_ICON1 IDI_ICON4。 6.6图标和光标图标和光标(3)(3)用图形编辑器绘制图标,如图。(4)(4)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);SetClassL

65、ong(m_hWnd, GCL_HICON, (long)hIconNew);RedrawWindow();/ 重绘窗口 6.6图标和光标图标和光标(5)(5)在CMainFrame:OnCreate函数的最后添加计时器设置代码:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;.SetTimer(1, 500, NULL);return 0; (6)(6)为CMainFrame类添加WM_TIMER的消息映射函数,增加代码: v

66、oid 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); 6.6图标和光标图标和光标(7)(7)为CMainFrame类添加WM_DESTROY的消息映射函数,增加代码:void CMainFrame:OnDestroy() CFrameWnd:OnDe

67、stroy();KillTimer(1);KillTimer函数是CWnd类成员函数,用来停止WM_TIMER消息的传送,其函数参数值用指定要停用的计时器标识值。(8)(8)编译并运行。可以看到任务栏上的按钮以及应用程序的标题栏上四个图标循环显示的动态效果,显示速度为每秒两帧。 6.6图标和光标图标和光标6.6.3光标光标 使用系统光标使用系统光标 标准光标可以使用CWinApp: LoadStandardCursor加载到程序中,函数:HCURSOR HCURSOR LoadStandardCursorLoadStandardCursor( LPCTSTR ( LPCTSTR lpszCur

68、sorName ) const; ) const;lpszCursorName用来指定一个标准光标名,可以是下列宏定义:IDC_ARROW 标准箭头光标IDC_IBEAM 标准文本输入光标IDC_WAIT 漏斗型计时等待光标IDC_CROSS 十字形光标IDC_UPARROW 垂直箭头光标IDC_SIZEALL 四向箭头光标IDC_SIZENWSE 左上至右下的双向箭头光标IDC_SIZENESW 左下至右上的双向箭头光标IDC_SIZEWE 左右双向箭头光标IDC_SIZENS 上下双向箭头光标 使用光标资源使用光标资源 用编辑器创建或从外部调入的光标资源,通过函数CWinApp:LoadC

69、ursor进行加载,原型:HCURSOR LoadCursor( LPCTSTR lpszResourceName ) const;HCURSOR LoadCursor( UINT nIDResource ) const; 6.6图标和光标图标和光标更改程序中的光标更改程序中的光标 更改程序中的光标最简单的方法是MFC ClassWizard映射WM_SETCURSOR消息,该消息是光标移动到一个窗口内并且还没有捕捉到鼠标时产生的。CWnd为此消息的映射函数定义这样的原型:afx_msg BOOL OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT mes

70、sage );pWnd表示拥有光标的窗口指针,nHitTest用来表示光标所处的位置。message用来表示鼠标消息。在OnSetCursor函数调用SetCursor来设置相应的光标,并将OnSetCursor函数返回TRUE,就可改变当前的光标了。 示例示例 (1)(1)打开前面的单文档应用程序Ex_Icon。(2)(2)按Ctrl+R,打开“插入资源”对话框,选择“Cursor”类型后,单击新建。(3)(3)图形编辑器工作窗口的控制条上,单击“New Device Image”,单击定制。(4)(4)在弹出的“定制图像”对话框中,保留默认的大小和颜色数,单击确定。(5)(5)选择“32

71、x 32, 16 colors”设备类型,单击确定按钮。(6)(6)在“Device”组合框中,选择“Monochrome 32 x 32 ”,选择“Delete Device Image”命令,删除“Monochrome 32 x 32 ”类型。6.6图标和光标图标和光标(7)(7)用图形编辑器绘制光标图形,指定光标热点位置为(15, 15),如图。 6.6图标和光标图标和光标(8)(8)为CMainFrame类添加成员变量m_hCursor,变量类型为光标句柄HCURSOR。(9)(9)为CMainFrame类添加WM_SETCURSOR的消息映射函数,增加代码:BOOL CMainFra

72、me:OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) BOOL bRes = CFrameWnd:OnSetCursor(pWnd, nHitTest, message);if (nHitTest = HTCAPTION ) m_hCursor = LoadCursorFromFile(c:windowscursorsglobe.ani);SetCursor(m_hCursor);bRes = TRUE;else if (nHitTest = HTCLIENT ) m_hCursor = AfxGetApp()-LoadCursor(IDC_CURSOR1);SetCursor(m_hCursor);bRes = TRUE;return bRes;(10)(10)编译运行并测试。当鼠标移动到标题栏时,光标变成了globe.ani的动画光标,而当移动到客户区时,光标变成了IDC_CURSOR1定义的形状。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号