八宝书库 > 文学其他电子书 > VC语言6.0程序设计从入门到精通 >

第12部分

VC语言6.0程序设计从入门到精通-第12部分

小说: VC语言6.0程序设计从入门到精通 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 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  编程,因此首先

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的