1 / 136

第四章 装饰应用程序的外观

第四章 装饰应用程序的外观. 创建友好 , 美观的 用户界面 是成功设计和编制一个 Windows 应 用程序的重要组成部分,程序 用户界面 的设计编程工作包括 菜单 、 控制栏 ( 其中包括 工具栏 、 状态栏 、 对话框栏 等) 创建和控制、 对话框 、 帮助信息 的制作和运行,以及 框架 、 视图窗口 的位置和大小控制等。其中对话框的制作和运行操作将在下一 章中作详细的描述。 在 AppWizard 创建的应用程序框架中, 菜单 , 工具栏 , 状态栏 和 视图窗口 均可以缺省隶属于 主框架窗口 ,并由 主框架窗口 管

Download Presentation

第四章 装饰应用程序的外观

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第四章 装饰应用程序的外观

  2. 创建友好, 美观的用户界面是成功设计和编制一个 Windows 应 用程序的重要组成部分,程序用户界面的设计编程工作包括菜单、控制栏( 其中包括工具栏、状态栏、对话框栏等) 创建和控制、对话框、帮助信息的制作和运行,以及框架、视图窗口的位置和大小控制等。其中对话框的制作和运行操作将在下一 章中作详细的描述。 在 AppWizard创建的应用程序框架中,菜单,工具栏, 状态栏 和视图窗口均可以缺省隶属于主框架窗口,并由主框架窗口管 理和控制。一个典型主框架窗口的组成以及与用户界面各个组 成部分的关系如下图所示:

  3. SDI主框架窗口 子窗口 ⑴SDI应用程序框架 标题栏 菜单栏 工具栏窗口 视图窗口 状态栏窗口

  4. MDI主框架窗口 MDI子框架窗口 子窗口 ⑵MDI应用程序框架 标题栏 菜单栏 工具栏窗口 标题栏 视图窗口 状态栏窗口

  5. MFC AppWizard 所生成的应用程序主框架窗口可以选择拥有缺 省的基本菜单、相应的工具栏、状态栏和由系统自动确定框架 窗口位置和尺寸,但在实际编程中往往需要在此基础上修改和 添加自定义的菜单、工具栏、状态栏以及由用户确定框架窗口 位置和尺寸,使应用程序外观满足特定的程序功能、特定的用 户和特定的使用环境的需要。 MFC 为工具栏,状态栏,菜单,主框架窗口提供了相应的基类,以便实现对这些程序外观组成部分的创建和各种操作。这些类在 MFC 中的派生层次结构如下:

  6. CCmdTarget CWnd CControlBar CToolBar CStatusBar CDialogBar CReBar ·工具栏和状态栏分别由 CToolBar和 CStatusBar 类描述, 它们都是控制栏类 CControlBar的派生类,而 CControlBar又是 CWnd 的派生类,因此,工具栏和状态栏本身也是一个能响 应消息的特定窗口,在主框架窗口中可以视为是子窗口。 CObject

  7. CMenu ·菜单是由 CMenu类描述, 它是直接从 CObject类派生的,因此该类的对象只能用于完 成菜单的创建、跟踪、修改、销毁和发送命令消息,而本身 不能响应消息;在主框架窗中可以视为用于发送命令消息的 一个特定区域。 CObject

  8. CCmdTarget CWnd CFrameWnd CMDIFrameWnd CMDIChildWnd ·主框架窗口是由 CFrameWnd(用于 SDI)或 CMDIFrameWnd 和 CMDIChildWnd(用于 MDI),它们都是 CWnd的直接或间接派 生类。 CObject

  9. AppWizard创建的文档视图结构的应用程序主框架窗口类 对象中缺省的工具栏被定义成名为 m_wndToolBar 的 CToolBar类 对象成员,而状态栏被定义成名为 m_wndStatusBar 的CStatusBar 类对象成员。创建和显示工具栏和状态栏的操作应在程序主框 架窗类 CMainFrame 对象所关联的窗口已经创建完成(窗口句柄已有效) 但还未显示时进行,即在窗口创建消息 WM_CREATE 的响应成员函数 OnCreate被调用中完成的。因此,需要在 CMainFrame类中重新定义 OnCreate 函数,以便在主框架窗口显 示之前添加任何需要附加的初始化工作,例如创建和显示工具 栏和状态栏、创建其他子窗口等。

  10. 与其它 Windows资源所对应的 MFC类一样,CMenu类也是将菜 单的句柄和属性和对菜单属性的各种操作等封装了起来,并且 只有当菜单句柄有效时,对菜单属性的操作才是合法的。通常 情况下,菜单总是主框架窗口的一个区域,所以当主框架窗口 的产生函数或 LoadFrame函数被调用时,与菜单资源相关联的 CMenu对象作为框架窗口的保护成员被创建。 因此,通常情况下,编程者只需要通过设计菜单的静态资 源,而且无须通过 CMenu类对象的调用对象的行为,就能满足 程序对主菜单的一般设计编程需求。但在程序需要动态创建新 菜单或修改已有菜单时,则必须调用 CMenu对象的行为。

  11. 如果你需要修改主框架窗口的菜单,你可能需要通过窗口类 CWnd的成员函数 GetMenu获取保护成员 CMenu对象的指针, 并通过该指针对该菜单对象进行各种需要的访问和操作,以便 满足特殊的菜单设计编程需求,例如: ·动态切换不同菜单; ·动态隐藏和显示菜单; ·动态添加和删除菜单项; ·动态禁止和激活菜单项; ·动态为菜单项添加图形标签; ·动态创建浮动的弹出式环境菜单。

  12. 对框架和视图窗口的外观操作,就是对它们的位置、大小、状对框架和视图窗口的外观操作,就是对它们的位置、大小、状 态的控制,称之为放置(Placement)操作。视图窗口是包含在 框架窗口中的,它随着框架窗口的变化而变化,换句话说,对 视图窗口的放置操作是通过对框架窗口的放置操作实现的。虽 然用户可以方便地通过框架窗口提供的最大化、最小化等窗口 操作界面对框架和视图窗口的放置进行动态交互控制,但在不 少情况下,还是需要在程序中通过代码对框架和视图窗口的放 置进行定制操作。例如,希望程序在运行开始时能保持最近一 次运行的框架和视图窗口的位置、大小、状态。实现这些放置 操作是窗口创建过程中完成的,这对于 SDI和 MDI应用程序是 不完全一样的,对于 MDI,不仅要考虑主框架窗口的放置,还 要考虑子框架窗口的放置。

  13. 本章将通过 5类实例程序分别讲述如何实现上述外观设计: ·第 1类实例讲解工具栏和状态栏编程; ·第 2类实例讲解 CDialogBar编程; ·第 3类实例讲解 CReBar编程; ·第 4类实例讲解菜单编程; ·第 5类实例讲解具有持续特性的定制框架窗口类编程。

  14. 4.1 创建浮动工具栏 4.1.1 利用 AppWizard自动创建工具栏 在 MFC中,工具栏资源和工具栏类 CToolBar是实现工具栏的 两个要素。创建工具栏对象的基本步骤为: ·创建工具栏资源; ·创建一个 CToolBar对象; ·调用 CToolBar::Create函数创建工具栏窗口; ·调用 CToolBar::LoadToolBar载入工具栏资源。

  15. 在使用 AppWizard生成的默认配置的应用程序框架中包括了 能创建一个缺省工具栏的四步操作的所有代码,因此修改工具 栏中的按钮只需要修改缺省工具栏资源就可以实现。而如果需 要创建缺省工具栏以外的工具栏,则必须在 AppWizard生成的框 架基础上,效仿上述缺省资源和代码添加相应的自定义资源和 代码。为此,分析创建缺省工具栏的代码是十分必要的。 创建一个 SDI 应用程序项目 “Default” (使用 AppWizard 的缺 省选择),查询所创建的应用程序框架的代码,可以发现与工 具栏有关的资源和代码有:

  16. 1 在资源中添加了工具栏资源 IDR_MAINFRAME: 2 在 CMainWnd的定义中添加了定义工具栏对象成员的代码: CToolBar m_wndToolBar; 3 在重新定义的 CMainWnd::OnCreate中添加了创建工具栏, 装 载工具资源和初始化工具栏的缺省代码。 分析 CMainWnd::OnCreate,该虚函数首先调用了基类中定义 的版本 CFrameWnd::OnCreate进行基类部分的初始化工作, 然后可以添加主框架窗口所需要的任何初始化代码,其中包 括了对工具栏的创建和初始化操作:

  17. ⑴创建工具栏窗口 创建工具栏窗口的函数是 CToolBar::Create 或CToolBar::CreateEx 它们的原型分别为: BOOL Create( CWnd *pParentWnd, // 父窗口指针 DWORD dwStyle = WS_CHILD| WS_VISIBLE|CBRS_TOP, // 风格 UINT nID=AFX_IDW_TOOLBAR /* 工具栏子窗口 ID */ ); BOOL CreateEx(CWnd* pParentWnd, //父窗口指针 DWORD dwCtrlStyle = TBSTYLE_FLAT, // 工具栏控件风格 DWORD dwStyle = WS_CHILD| WS_VISIBLE|CBRS_ALIGN_TOP, CRect rcBorders=CRect(0,0,0,0),// 工具栏的矩形边界 UINT nID=AFX_IDW_TOOLBAR /* 工具栏子窗口 ID */ );

  18. 其中: ·pParentWnd是指向工具栏的父窗口,即主框架窗口对象的 指针。 ·dwCtrlStyle和 dwStyle的设置是决定所创建的工具栏的外观 和状态的重要因素,可设置的样式值包括 CWnd的样式和 CToolBar 的样式两部分(祥见 MSDN的有关部分)。 ·如果创建成功,返回真实的;否则返回错误的。 例如,在本例中实现创建工具栏窗口的缺省代码为: m_wndToolBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE| CBRS_TOP|CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY|CBRS_SIZE_DYNAMIC ); 注意,该调用中第 4参数 rcBorders和第 5参数 nID使用了缺省 值 CRect(0,0,0,0)和AFX_IDW_TOOLBAR 。

  19. ⑵加载工具栏资源 为工具栏对象加载资源的函数为 CToolBar::LoadToolBar,其 原型为: BOOL LoadToolBar ( LPCTSTR lpszResourceName /*资源名 */ ); BOOL LoadToolBar ( UINT nIDResource /* 资源 ID */ ); 本例中实现加载工具栏资源的代码为: m_wndToolBar.LoadToolBar ( IDR_MAINFRAME ); IDR_MAINFRAME 是工具栏资源的 ID。如果资源加载成功,则 返回 TRUE的;否则返回 FALSE的。

  20. ⑶设置工具栏停靠特性 实现设置的函数为 CControlBar::EnableDocking,其原型为: void EnableDocking ( DWORD dwStyle ); 参数为停靠样式,种类和取值参考 MSDN中的相关部分。 本例中实现设置的代码为: m_wndToolBar.EnableDocking ( CBRS_ALIGN_ANY ); 参数 CBRS_ALIGN_ANY 所指示的停靠样式是允许工具栏停靠 到主框架窗口中的任何一边。

  21. ⑷设置主框架窗口的工具栏停靠特性 实现该设置的函数为 CFrameWnd::EnableDocking,其原型: void EnableDocking ( DWORD dwdocStyle ); 参数为停靠样式,种类和取值参考 MSDN中的相关部分。 本例中实现设置的代码为: EnableDocking ( CBRS_ALIGN_ANY ); 参数 CBRS_ALIGN_ANY 所指示的停靠样式是使框架窗口的任 何一边都可以停放控制栏。在拥有多个控制栏的框架窗口中 该函数只需调用一次。

  22. ⑸把工具栏停靠在主框架窗口中的确定位置 实现停靠操作的函数为 CFrameWnd::DockControlBar,原型: void DockControlBar ( CControlBar*pBar, UINT nDockBarID=0, LPCRECT lpRect=NULL ); 本例中实现停靠的代码为: DockControlBar (&m_wndToolBar); 使工具栏按照创建工具栏窗口时的默认位置(框架窗口工作 区的顶部),实现停靠操作。

  23. 4.1.2 添加自定义工具栏 创建一个名为 "Tb" 的 SDI应用程序项目,参照由 AppWizard 缺省创建的工具栏添加自定义工具栏。 1 自定义工具栏资源 使用资源编辑器添加一个标识为 ID_TOOLBAR1的工具栏资源 其中包括两个按钮: 2. 添加自定义工具栏的程序代码 ⑴ 在 CMainFrame类中增加一个 CToolBar类的保护成员对象: CToolBar m_wndToolBar1; ⑵ 在 CMainFrame::OnCreate添加对应于 m_wndToolBar1的创建、 加载资源和初始化代码:

  24. if ( !m_wndToolBar1.CreateEx ( this,TBSTYLE_FLAT,WS_CHILD | WS_VISIBLE | CBRS_TOP|CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar1.LoadToolBar ( IDR_TOOLBAR1 ) ) { TRACE0 (" Failed to create toolbar\n "); return -1; // fail to create } … m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY); … DockControlBar (&m_wndToolBar1); 此时编译运行应用程序,可以看到新增加的自定义工具栏, 但工具栏中的按钮是灰色的,即不能对它进行任何操作。

  25. 4.1.3 自定义工具栏的命令响应及其用户界面更新 在 CTbView 类中,添加工具栏按钮 ID_LINE和 ID_CIRCLE的 命令消息和界面更新命令消息的响应。 1 为 CTbView类增加保护数据成员和枚举: int m_nDraw; // 指示当前的绘图类别。 enum{LINE,CIRCLE}; // 定义可以使用的绘图类别。 2 在 CTbView的构造函数中对 m_nDraw进行初始化: m_nDraw = LINE; 3. 使用 ClassWizard为命令消息 ID_LINE和 ID_CIRCLE定义命令 响应函数和用户界面更新函数。 在类定义文件中添加了这些成员函数的原型:

  26. afx_msg void OnLine (); afx_msg void OnCircle (); afx_msg void OnUpdateLine (CCmdUI*pCmdUI); afx_msg void OnUpdateCircle (CCmdUI*pCmdUI); 在类实现文件中添加了上述成员函数的操作定义如下: void CTbView::OnLine() { m_nDraw = LINE; }

  27. void CTbView::OnCircle() { m_nDraw = CIRCLE; } void CTbView::OnUpdateLine (CCmdUI*pCmdUI) { pCmdUI->SetCheck(m_nDraw == LINE); } void CTbView::OnUpdateCircle(CCmdUI*pCmdUI) { pCmdUI->SetCheck(m_nDraw == CIRCLE); } 4 编译运行 "Tb"

  28. 4.1.4 自定义工具栏的隐藏/显示 要使自定义的工具栏能像缺省工具栏那样具有隐藏和显示操 作功能必须添加以下资源和代码: 1 在主菜单 IDR_MAINFRAME的“查看”弹出菜单中增加新的菜单 项 "自定义工具栏" ,其标识值为 ID_VIEW_TOOLBAR1 2 在主框架窗口类 CMainFrame 中,为 ID_VIEW_TOOLBAR1定义 命令响应函数和用户界面更新函数 在类定义文件中添加这些成员函数的原型: afx_msg voidOnViewToolbar1(); afx_msg voidOnUpdateViewToolbar1( CCmdUI* pCmdUI );

  29. 在类实现文件中添加上述成员函数的操作定义:在类实现文件中添加上述成员函数的操作定义: void CMainFrame::OnViewToolbar1() { ShowControlBar( &m_wndToolBar1, m_wndToolBar1.IsWindowVisible() ? FALSE : TRUE, FALSE ); } void CMainFrame::OnUpdateViewToolbar1( CCmdUI* pCmdUI ) { pCmdUI->SetCheck( m_wndToolBar1.IsWindowVisible( ) ); } 3 编译运行"Tb"

  30. 4.1.5 动态删除和添加工具栏中按钮 如果希望通过程序动态地从已经创建的工具栏中删除一些按 钮或向工具栏中添加一些按钮,则需要使用CToolBar类对象中 的 CToolBarCtrl类对象成员来实现,而这个对象成员可以通过 调用 CToolBar::GetToolBarCtrl函数获得实例 "Tb1" 是在实例 "Tb" 的基础上增加了通过程序代码对工具栏中的按钮进行动态删除 和添加的功能: 1 在 CMainFrame类定义中增加下列保护数据成员: // for saving buttons of the m_wndToolBar TBBUTTON m_tbButtons[11]; // for saving the most and least count of buttons int m_nMost, m_nLeast;

  31. 2 在 CMainFrame::OnCreate中增加下列初始化代码: // Save some TBBUTTONs for restoring later m_nMost = m_wndToolBar.GetToolBarCtrl().GetButtonCount(); // Save the most count of buttons for(int I = 2; I < m_nMost - 1; i++) m_wndToolBar.GetToolBarCtrl().GetButton(i, &m_tbButtons[i]); // Delete some buttons from m_wndToolBar. DeleteTBButtons(2,m_nMost - 3); // Save the least count of buttons m_nLeast = m_wndToolBar.GetToolBarCtrl().GetButtonCount();

  32. 3 为 CMainFrame定义删除和恢复工具栏按钮的保护成员函数: 在定义文件中增加这两个函数的原型声明: void RecoverTBButtons ( int index,int count ); void DeleteTBButtons ( int index, int count ); 在实现文件中增加这两个函数的定义代码: void CMainFrame::DeleteTBButtons( int index,int count) { for ( int I = index; I < index + count; i++) m_wndToolBar.GetToolBarCtrl().DeleteButton(index); //从工具栏中顺序删除索引为 index 的按钮。 ShowControlBar(&m_wndToolBar,TRUE, TRUE); //重新显示变化后的工具栏。 }

  33. void CMainFrame::RecoverTBButtons(int index, int count) { for (int I = index; I < index + count; i++) // 将删除的按钮顺序恢复插入到工具栏中。 m_wndToolBar.GetToolBarCtrl().InsertButton(i, &m_tbButtons[i]); //重新显示变化后的工具栏。 ShowControlBar(&m_wndToolBar, TRUE, TRUE); } 4 在主菜单资源 IDR_MAINFRAME的“查看”菜单中增加菜单项: “删除工具栏中的按钮”和“恢复工具栏中的按钮”,它们的标识 为:ID_DELETE_BUTTONS和 ID_RECOVER_BUTTONS。

  34. 5 使用 ClassWizard 在 CMainFrame类中为 ID_DELETE_BUTTONS 和 ID_INSERT_BUTTONS 添加命令消息响应和用户界面更新函数。 在类定义文件中增加了: afx_msg void OnDeleteButtons (); afx_msg void OnRecoverButtons (); afx_msg void OnUpdateDeleteButtons (CCmdUI* pCmdUI); afx_msg void OnUpdateRecoverButtons (CCmdUI* pCmdUI); 在类实现文件中增加了命令映射项和消息响应函数: ON_COMMAND(ID_DELETE_BUTTONS, OnDeleteButtons) ON_COMMAND(ID_INSERT_BUTTONS, OnRecoverButtons)

  35. ON_UPDATE_COMMAND_UI(ID_DELETE_BUTTONS, OnUpdateDeleteButtons) ON_UPDATE_COMMAND_UI(ID_INSERT_BUTTONS, OnUpdateRecoverButtons) void CMainFrame::OnDeleteButtons() { DeleteTBButtons(2, m_nMost - 3); } void CMainFrame::OnRecoverButtons() { RecoverTBButtons(2, m_nMost - 3); }

  36. void CMainFrame::OnUpdateDeleteButtons(CCmdUI* pCmdUI) { pCmdUI->Enable( m_wndToolBar.GetToolBarCtrl().GetButtonCount() == m_nMost ); } void CMainFrame::OnUpdateRecoverButtons(CCmdUI* pCmdUI) { pCmdUI->Enable( m_wndToolBar.GetToolBarCtrl().GetButtonCount() == m_nLeast ); } 6 编译运行"Tb1"

  37. 4.2 创建自定义状态栏 分析 “Default” 项目中关于状态栏的代码。不难发现状态栏也 是窗口,该窗口一般分成几个窗格,在每个窗格中可以显示不 同的信息。自动创建的缺省状态栏包括了四个窗格,分别显示 菜单命令提示和键盘的大写、数字、滚屏锁定状态。 状态栏是由 CStatusBar类实现的。状态栏的典型创建步骤: ·定义一个 CStatusBar对象; ·为状态栏的每个窗格定义 ID,并为每个窗格定义了标题字符 串资源(字符串资源和窗格的 ID相同); ·调用CStatusBar::Create创建状态栏窗口; ·调用CStatusBar::SetIndicators 函数分配窗格,并将状态栏的每 个窗格与对应的字符串资源绑定。

  38. 4.2.1 利用 AppWizard 自动创建状态栏 使用 AppWizard的缺省选择创建的程序框架能自动创建一个 缺省状态栏。分析程序中与状态栏有关的代码,对于修改原有 的状态栏和创建自定义状态栏都是十分必要的。与缺省状态栏 有关的资源和代码包括: 1CMainFrame类中定义中添加了状态栏对象保护成员: protected: CStatusBarm_wndStatusBar; …

  39. 2在 CMainFrame类实现文件中添加了把状态栏分割为窗格的全 程静态数组定义 static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; 其中: ·ID_SEPARATOR对应的窗格用于显示菜单命令提示。 ·其他三项用于显示键盘相应的键状态,它们所对应的字符 串在资源 String Table 中被定义为:

  40. STRINGTABLE DISCARDABLE BEGIN … ID_INDICATOR_CAPS "CAP" ID_INDICATOR_NUM "NUM" ID_INDICATOR_SCRL "SCRL" … END ·确定状态栏窗格数目和内容的 indicators由几个和哪些 ID组 成取决于程序的需要。 ·如果 indicators中加入新元素,则要为新元素指定 ID,还要 根据需要,在字符串资源中定义 ID标识的描述字符串。

  41. 3创建状态栏窗口 与工具栏一样,状态栏创建操作也是在 CMainFrame::OnCreate 完成的。实现该操作的代码: if ( !m_wndStatusBar.Create( this ) || !m_wndStatusBar.SetIndicators( indicators, sizeof( indicators ) / sizeof( UINT ) ) ) { TRACE0( "Failed to create status bar\n" ); return -1; // fail to create } 其中 Create和 SetIndicators函数的原型:

  42. BOOL Create( CWnd*pParentWnd,// 父窗口指针 DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR /* 状态栏 ID */ ); 其中状态栏样式参数包括如下三种: ·CBRS_TOP    Control bar is at top of frame window. ·CBRS_BOTTOM    Control bar is at bottom of frame window. ·CBRS_NOALIGN  Control bar is not repositioned when the parent is resized. 注意:状态栏不支持浮动。 BOOL SetIndicators( const UINT* lpIDArray, int nIDCount ); 这两个成员函数调用成功,返回 TRUE,否则返回 FALSE。由 于状态栏不支持浮动,所以就不必设置其停靠特性。

  43. 4.2.2自定义状态栏 实例 “Sb” 是在实例 “Default” 的基础上对状态栏 m_wndStatusBar 进行了如下修改: ·第一个窗格在保持原有功能的基础上,使它能够显示鼠标在 窗口工作区中移动时的位置信息。 ·将第四个窗格中显示的键状态修改为显示键盘的 <Shift> 键的 状态,即按下 <Shift>键,窗格显示文本信息 “SHIFT”,释放 <Shift> 键,窗格中的文本信息 “SHIFT” 消失。 ·增加第五个窗格用于显示当前时间(时:分:秒)。

  44. 1 在 indicators数组中删除 ID_INDICATOR_SCRL,并添加新元素 ID_INDICATOR_SHIFT 和 ID_INDICATOR_CLOCK: static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SHIFT, ID_INDICATOR_CLOCK, }; 2 选择菜单命令 View->Resource Symbols,在资源符号对话框中 为 ID_INDICATOR_SHIFT和 ID_INDICATOR_CLOCK定义 ID值。

  45. 3 在资源 String Table 中为新增的 ID添加字符串: 4更新时间窗格 实现该功能首先要利用系统定时器产生变化的当前时间,并 将产生的时间转换成格式为“时:分:秒” 的字符串;然后通过调用 CStatusBar::SetPaneText函数将时间字符串显示在第五窗格中。 SetPaneText 的原型如下: BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE );

  46. ⑴动态地获取当前时间可以通过定时读取系统当前时间实现,⑴动态地获取当前时间可以通过定时读取系统当前时间实现, 为此可以使用 ClassWizard为 CMainFrame增加系统定时器窗口消 息 WM_TIMER的映射项、响应函数 OnTimer的声明和定义。 ⑵ 在 OnTimer函数中添加操作代码: void CMainFrame::OnTimer( UINT nIDEvent ) { CTime time; time = CTime::GetCurrentTime(); CString s = time.Format( "%H:%M:%S" ); m_wndStatusBar.SetPaneText( m_wndStatusBar.CommandToIndex(ID_INDICATOR_CLOCK), s); CFrameWnd::OnTimer( nIDEvent ); }

  47. ⑶ 设置系统定时器 为了使系统能按照要求的时间间隔发出时间中断,需要在 CMainFame构造函数或 OnCreate中调用 CWnd::SetTimer设置能指 定时间间隔发出中断的定时器。 SetTimer 的原型: UINT SetTimer( UINTnIDEvent, UINTnElapse, void (CALLBACK EXPORT* lpfnTimer ) ( HWND, UINT, UINT, DWORD) ); 参数: nIDEvent定时事件标识,一个程序中可以有多个定时器。 nElapse定时器的定时间隔。 lpfnTimer指向自定义定时器设置函数,NULL 表示使用系统 定时器设置函数。

  48. 返回: 如果设置成功,返回定时事件标识;否则返回 0。 本例中在 CMainFrame::OnCreate 中添加了如下设置代码: m_nTimer = SetTimer(1, 1000, NULL); // 定时间隔为1000ms 其中 m_nTimer是在 CMainFrame 中添加的数据成员: class CMainFrame public CFrameWnd { … private: UINT m_nTimer; // 用于保存定时器标识。 }

  49. 已经设置成功的定时器在其所属窗口关闭撤消时,应该调用 CWnd::KillTimer 同时撤消,为此使用 ClassWizard为 CMainFrame增 加主框架窗口关闭消息 WM_CLOSE的映射项、响应函数 OnClose 的声明和定义。 ⑸ 为 OnClose函数添加操作代码: void CMainFrame::OnClose() { KillTimer(m_nTimer); CFrameWnd::OnClose(); }

  50. 5 更新 <Shift> 按键状态对应的窗格 该功能是通过添加 ID_INDICATOR_SHIFT的用户界面更新消息 的映射项、响应函数 OnUpdateShift的声明和定义实现的。 完成这些编程只能手工进行,而不能使用 ClassWizard。 ⑴ 在 CMainFrame中加入消息处理函数 OnUpdateShift的原型: //}}AFX_MSG afx_msg void OnUpdateShift(CCmdUI* pCmdUI); DECLARE_MESSAGE_MAP() ⑵ 在 CMainFrame类的消息映射表中加入映射条目: //}}AFX_MSG_MAP ON_UPDATE_COMMAND_UI( ID_INDICATOR_SHIFT, OnUpdateShift) END_MESSAGE_MAP()

More Related