友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
VC语言6.0程序设计从入门到精通-第11部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
骤:
o 构建一个 CStatusBar 对象;
o 调用 CStatusBar::Create 创建状态栏窗口;
o 调用 CStatusBar::SetIndicators 函数分配窗格,并将状态栏的每一个窗格与一个字符串
ID 相联系。
if (!m_wndStatusBar。Create(this) ||
!m_wndStatusBar。SetIndicators(indicators; sizeof(indicators)/sizeof(UINT)))
{
TRACE0(〃Failed to create status barn〃);
return …1; // fail to create
}
实例 2…7 :电子时钟。源代码在光盘中“02实例 2…7EClock ”目录下。
下面将通过一个电子时钟(在状态栏中嵌入一个电子时钟 )的例程来向读者详细讲述工
具栏的使用。
首先在 indicators 数组的 ID_SEPARATOR 项之后插入一个名为 ID_INDICATOR_CLOCK
的 ID,然后找到并双击字符串资源,打开字符串资源编辑窗口,接着在编辑窗口内按 Insert
键以插入一个新的字符串,指定字符串的 ID 为 ID_INDICATOR_CLOCK,内容为 00:00:00 。
由于状态栏将根据字符串的长度来确定相应窗格的默认宽度,所以指定为 00:00:00 就为时间
的显示预留了空间。添加该字符串资源的结果如图 2…27 所示。
·36 ·
…………………………………………………………Page 46……………………………………………………………
第 2 章 应用程序基本框架
时间窗格显示的时间必须每隔一秒钟更新一次。更新时间窗格的正文可调用 CStatusBar::
SetPaneText 函数,要定时更新,则应利用定时器消息(WM_TIMER )。在 Windows 中用户可
以安装一个或多个计时器,计时器每隔一定的时间间隔就会自动发出一个 WM_TIMER 消息,
而这个时间间隔可由用户指定。MFC 的 Window 类提供了 WM_TIMER 消息处理函数
OnTimer,可以在该函数内进行更新时间窗格的工作。
图 2…27 添加 ID_INDICATOR_CLOCK 字符串资源的结果
可以利用 ClassWizard 工具给 CMainFrame 类加入 WM_TIMER 的消息处理函数 OnTimer
和 WM_CLOSE 消息的处理函数 OnClose 。具体方法是在 Class name 栏中选择 CMainFrame,
在 Object IDs 栏中选择 CMainFrame,在 Messages 栏中找到 WM_TIMER 和 WM_CLOSE 项,
分别双击之然后单击“OK ”按钮退出 ClassWizard 。CMainFrame::OnClose 函数是在关闭主框
架窗口是被调用的,程序可以在该函数中做一些清除工作。部分核心代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == …1)
return …1;
if (!m_wndToolBar。CreateEx(this; TBSTYLE_FLAT; WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar。LoadToolBar(IDR_MAINFRAME))
{
TRACE0(〃Failed to create toolbarn〃);
return …1; // fail to create
}
if (!m_wndStatusBar。Create(this) ||
!m_wndStatusBar。SetIndicators(indicators;
sizeof(indicators)/sizeof(UINT)))
{
TRACE0(〃Failed to create status barn〃);
return …1; // fail to create
}
·37 ·
…………………………………………………………Page 47……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
SetTimer(1;1000;NULL); //设置时钟定时器
return 0;
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CTime time;
time=CTime::GetCurrentTime(); //得到当前时间
CString s=time。Format(〃%H:%M:%S〃);//格式化时间显示格式
m_wndStatusBar。SetPaneText(m_wndStatusBar。mandToIndex(ID_INDICATOR_CLOCK);s);
CFrameWnd::OnTimer(nIDEvent);
}
void CMainFrame::OnClose()
{
// TODO: Add your message handler code here and/or call default
KillTimer(1); //删除定时器
CFrameWnd::OnClose();
}
在 CMainFrame::OnCreate 函数内调用了 CWnd::SetTimer 以设置一个计时器,SetTimer
的第一个参数指定计时器 ID 为 1,第二个参数则规定了计时器的时间间隔为 1000 毫秒即 1
秒,这样,每隔 1 秒 OnTimer 函数就会被调用一次。在 OnTimer 函数中,首先构建了一个
CTime 对象,接着调用 CTime 的静态成员函数 GetCurrentTime 以获得当前的系统时间,然后
利用 CTime::Format 函数返回一个按“时:分:秒”的格式表示的字符串,最后调用
CStatusBar::SetPaneText 来更新时间窗格显示的正文。SetPaneText 的第一个参数是窗格的索
引,对于某一个窗格 ID,可调用 CStatusBar::mandToIndex 来获得索引。在撤销主框架窗
口时应关闭计时器,因此在 CMainFrame::OnClose 函数内调用了 KillTimer 函数。
电子时钟运行结果如图 2…28 所示,在框架底部的状态栏的右方可以看到当前时间。
图 2…28 电子时钟示例程序运行结果
·38 ·
…………………………………………………………Page 48……………………………………………………………
第 2 章 应用程序基本框架
在调试程序的时候,可能常会碰到程序存在 bug 或运行错误的情况,下面将介绍处理错
误信息的一般方法。在电子时钟程序中,运行程序时可能提示如图 2…29 的错误信息。
图 2…29 电子时钟 Debug 错误信息
为了查明导致 Debug Assertion Failed 的错误代码,选择“Build|Debug|Go ”菜单命令进入
调试状态,这时通过运行时的异常可以判断出代码的大概错误位置,在 Debug 模式下的界面
如图 2…30 所示。也可以在对程序出错代码的大概估计的基础上在“可疑”代码附近设置断点
到进行调试,界面如图 2…31 所示。
图 2…30 电子时钟调试信息
图 2…31 电子时钟断点调试信息
·39 ·
…………………………………………………………Page 49……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
在断点附近处通过按键 F10 (Step Over)或 F11 (Step Into )键可以找到存在 bug 的代码。
通过观察和分析知道,在下面的这行代码中,由于 ID_INDICATOR_NUM 没有在 indicators
数组中被定义,才会导致错误。通过更改 ID_INDICATOR_NUM 为 ID_INDICATOR_CLOCK,
电子时钟运行便正常。
m_wndStatusBar。SetPaneText(m_wndStatusBar。mandToIndex(ID_INDICATOR_NUM);s);
2。6 应用程序框架中各类对象间的关系
通过从 2。1 节到 2。5 节的学习,相信读者对于利用 AppWizard 生成的应用程序框架有了
一定的了解。下面以单文档(SDI )应用程序 HelloMFC 为例对应用程序框架中各主要对象的
构造以及各对象之间的访问情况等方面进行介绍。
在 HelloMFC 应用程序中,AppWizard 生成了 4 个主要的类,这些类都是 MFC 类的派生
类,分别包含在对应的头文件以及实现文件中,这些类的对象构成了框架的核心。
1.框架窗口类及其相关的文件
框架窗口类对应应用程序的主窗口,明白这一点后就可以建立一个对这个类的感性认识
了,其定义是在头文件 MainFrm。h 中,而实现则是在 MainFrm。cpp 文件中。所有与框架窗口
向光的功能都是在这里定义和实现的。
2 .文档类及其相关的文件
文档类在应用程序中没有直观的对应关系,但是,应该明白的一点就是 MFC 框架的一
个特点就是文档视图结构 。这里可以抽象一点地来理解,比如说在 Word 中打开了一个文件,
其实,这个文件就是文档,而看到的只不过是这个文件一个视图,所以说文档提供了应用程
序显示的支持,但是真正看到的应用程序显示的则是一个视图,文档类的定义是在
“HelloMFCDoc。h ”中,而其实现则是在“HelloMFCDoc。cpp ”文件中。
3 .视图类及其相关的文件
视图类是用来显示文档对象内容的,在 Word 程序中所看到的界面就是一个视图,要修
改、画图,首先操作的对象就是视图,所以,视图类就如其名称所指出的那样,提供了从用
户角度能看到的东西。视图类的定义在“HelloMFCView。h ”中,实现是在文件“Hello
MFCView。h ”中。
4 .应用程序类及其相关的文件
MFC 应用程序的初始化,启动运行和结束都是由应用程序对象完成的 。他对应的文件是”
HelloMFC。cpp ”和”HelloMFC。h ”。
从上面的陈述中可以大致看出 MFC 应用程序对象之间的关系了。应用程序一开始生成
应用程序对象,然后,在 InitInstance 中将会创建文档模板对象(通过 CSingleDocTemplate 管
理),这样一来,应用程序就可以通过建立的模板对象来管理文档、视图、和框架窗口。
在基于文档视图结构的 Windows 程序在不同的调用环境常常需要得到各种对象的指针,
·40 ·
…………………………………………………………Page 50……………………………………………………………
第 2 章 应用程序基本框架
以实现对象间数据的交互。实现各对象之间的相互访问有如下几种方法:
o 全局函数 AfxGetApp 可以得到 CWinApp 应用类指针;
o AfxGetApp()…》m_pMainWnd 为框架窗口指针;
o 在框架窗口中 CFrameWnd::GetActiveDocument 得到当前活动文档指针;
o 在框架窗口中 CFrameWnd::GetActiveView 得到当前活动视指针;
o 在视图中 CView::GetDocument 得到对应的文档指针;
o 在文档中 CDocument::GetFirstViewPosition,CDocument::GetNextView 用来遍历所有和
文档关联的视;
o 在文档中 CDocument::GetDocTemplate 得到文档模板指针;
o 在多文档界面中:CMDIFrameWnd::MDIGetActive 得到当前活动的 MDI 子窗口。
2。7 本章小结
本章主要对通过 MFC 应用程序向导(AppWizard )创建的应用程序框架作了介绍。由于
读者是可能第一次接触到 MFC 编程,因此首先对工程及工作区的概念及创建方法进行了介
绍。在此基础上通过 AppWizard 工具一步步地创建出的基于单文档(SDI )的 HelloMFC 应
用程序,并对其工程文件的组成及作用进行了说明。针对 HelloMFC 应用程序,介绍了类向
导(ClassWizard )工具的基本用法,接着对程序的运行过程以及应用类(CWinApp )的几个
主要的成员函数进行了解释。由于 HelloMFC 是基于文档视图结构的,接下来对该结构的文
档类和视图类的各自作用及相互之间的关系分别进行了说明,同时对经常用到的单文档
SDI)和多文档(MDI )结构进行了对比。针对框架结构中不可缺少主窗口类(CMainFrame )
(
和子窗口类(CChildFrame ),本章也对它们的功能和使用方法进行了介绍,同时介绍了在框
架窗口使用频率很高的工具栏(Toolbar )和状态栏(StatusBar)也介绍了创建过程和使用方
法,电子时钟(在状态栏中创建一个电子时钟 )例程演示了自定义状态栏的使用方法。最后,
对应用程序框架中的主要对象的关系及相互访问情况进行了总结。
本章阐述的应用程序框架是对话框、控件、文件操作及 Visual C++高级编程的基础,希
望读者能够仔细阅读推敲,并在后面章节的学习过程
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!