友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第125章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






       它们。 



                                                                                    493 


…………………………………………………………Page 556……………………………………………………………

                  第篇    深入  MFC  程式設計 



                  我们来看看CView 之中居最重要地位的OnDraw,面对Scribble Document 的数据结构, 



                  将如何进行绘图动作。为了获得资料,OnDraw 一开始先以GetDocument 取得Document 



                  对象指针;然后以while 循环一一取得各线条,再调用CStroke::DrawStroke  绘图。想象 



                   中绘图函数应该放在View 类别之内(绘图不正是View  的责任吗),但是DrawStroke  却 



                   否!原因是把线条的资料和绘图动作一并放在CStroke 中是最好的包装方式。 



                  void CScribbleView::OnDraw(CDC* pDC) 

                  { 

                      CScribbleDoc* pDoc = GetDocument(); 

                      ASSERT_VALID(pDoc); 



                      // The view delegates the drawing of individual strokes to 

                      // CStroke::DrawStroke()。 

                      CTypedPtrList& strokeList = pDoc…》m_strokeList; 

                      POSITION pos = strokeList。GetHeadPosition (); 

                      while (pos != NULL) 

                      { 

                          CStroke* pStroke = strokeList。GetNext (pos); 

                          pStroke…》DrawStroke(pDC); 

                      } 

                  } 



                   其中用到两个CObList 成员函数: 



                   

                     GetNext:取得下一个元素。 



                     GetHeadPosition:传回串行之第一个元素的「位置」。传回来的「位置」是一 

                   



                    个类型为POSITION  的数值,这个数值可以被使用于CObList 的其它成员函数 



                    中,例如GetAt 或SetAt 。你可以把「位置」想象是串行中用以标示某个节点 



                      node )的指针。当然,它并不真正是指针。 

                     ( 



494 


…………………………………………………………Page 557……………………………………………………………

                                                  第8章    Document…View  深入探討 



View 与使用者的交谈 (鼠标消息处理实例) 



    为了实现「以鼠代笔」的功能,CScribbleView 必须接受并处理三个消息: 



    BEGIN_MESSAGE_MAP(CScribbleView; CView) 

            ON_WM_LBUTTONDOWN() 

            ON_WM_LBUTTONUP() 

            ON_WM_MOUSEMOVE() 

            。。。 

    END_MESSAGE_MAP() 



    三个消息处理例程的的内容总括来说就是追踪鼠标轨迹、在窗口上绘图、以及调用CStroke 



    成员函数以修正线条内容……包括产生一个新的线条空间以及不断把坐标点加上去。三 



    个函数的重要动作摘记于下。这些函数的骨干及其在Messape Map 中的映射项目,不劳 



    我们动手,有ClassWizard 代劳。下一个小节我会介绍其操作方法。 



   void CScribbleView::OnLButtonDown(UINT nFlags; CPoint point) 



   { 



   // 当鼠标左键按下, 



   // 利用CScribbleDoc::NewStroke 产生一个新的线条空间; 



   // 利用CArray::Add 把这个点加到线条上去; 



   // 调用SetCapture 取得鼠标捕捉权(mouse capture); 



   // 把这个点记录为「上一点」(m_ptPrev); 



    } 



   void CScribbleView::OnMouseMove(UINT; CPoint point) 



    { 



   // 当鼠标左键按住并开始移动, 



   // 利用CArray::Add 把新坐标点加到线条上; 



   // 在上一点(m_ptPrev)和这一点之间画直线; 



   // 把这个点记录为「上一点」(m_ptPrev); 



    } 



   void CScribbleView::OnLButtonUp(UINT; CPoint point) 



    { 



   // 当鼠标左键放开, 



   // 在上一点(m_ptPrev)和这一点之间画直线; 



   // 利用CArray::Add 把新的点加到线条上; 

                                                                                 495 

   // 调用ReleaseCapture() 释放鼠标捕捉权(mouse capture)。 

    } 


…………………………………………………………Page 558……………………………………………………………

               第篇    深入  MFC  程式設計 



            ClassWizard 的辅佐 



                前述三个CScribbleView 成员函数(OnLButtonDown,OnLButtonUp,OnMouseMove)是 



                Message Map 的一部份,ClassWizard 可以很方便地帮助我们完成相关的Message Map 设 



                定工作。 



                首先,选按【View/ClassWizard 】激活ClassWizard,选择其【Message Map 】附页: 



               在图右上侧的【Class Name 】清单中选择CScribbleView,然后在图左侧的【Object IDs 】 



               清单中选择CScribbleView,再在图右侧的【Messages 】清单中选择WM_LBUTTONDOWN , 



               然后选按图右的【Add Function 】钮,于是图下侧的【Member functions 】清单中出现一 



               笔新项目。 



               然后,选按【Edit Code 】钮,文字编辑器会跳出来,你获得了一个OnLButtonDown 函数 



               空壳,请在这里键入你的程序代码: 



496 


…………………………………………………………Page 559……………………………………………………………

                                                   第8章    Document…View  深入探討 



另两个消息处理例程的实作作法雷同。 



Message Map 因此有什么变化呢?ClassWizard 为我们自动加上了三笔映射项目: 



BEGIN_MESSAGE_MAP(CScribbleView; CView) 

        //{{AFX_MSG_MAP(CScribbleView) 

        ON_WM_LBUTTONDOWN() 

        ON_WM_LBUTTONUP() 

        ON_WM_MOUSEMOVE() 

        //}}AFX_MSG_MAP 

        // Standard printing mands 

        ON_MAND(ID_FILE_PRINT; CView::OnFilePrint) 

        ON_MAND(ID_FILE_PRINT_DIRECT; CView::OnFilePrint) 

        ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview) 

END_MESSAGE_MAP() 



此外ScribbleView 的类别声明中也自动有了三个成员函数的声明: 



class CScribbleView : public CView 

 { 

 。。。 

// Generated message map functions 

protected: 

        //{{AFX_MSG(CScribbleView) 

        afx_msg void OnLButtonDown(UINT nFlags; CPoint point); 

        afx_msg void OnLButtonUp(UINT nFlags; CPoint point); 

        afx_msg void OnMouseMove(UINT nFlags; CPoint point); 

        //}}AFX_MSG 

 。。。 

 }; 



                                                                                    497 


…………………………………………………………Page 560……………………………………………………………

               第篇    深入  MFC  程式設計 



            WizardBar 的辅佐 



                WizardBar 是Visual C++ 4。0 之后的新增工具,也就是文字编辑器上方那个有着【Object 



                IDs 】和【Messages 】清单的横杆。关于修改Message Map 这件事,WizardBar 可以取代 



                ClassWizard 这个大家伙。 



                首先,进入ScribbleViwe。cpp  (因为我们确定要在这里加入三个鼠标消息处理例程),选 



                择WizardBar 上的【Object IDs  】为CScribbleView , 再选择【Messages  】为 

                  _ 

                WM LBUTTONDOWN ,出现以下画面: 



                回答Yes ,于是你获得一个OnLButtonDown 函数空壳,一如在ClassWizard  中所得。请 



                在函数空壳中输入你的程序代码。 



            Serialize :对象的文件读写 



                你可能对Serialization 这个名词感觉陌生,事实上它就是对象导向世界里的Persistence         (永 



                续生存),只是后者比较抽象一些。对象必须能够永续生存,也就是它们必须能够在程 



                式结束时储存到文件中,并且在程序重新激活时再恢复回来。储存和恢复对象的过程在 



                MFC 之中就称为serialization。负责这件重要任务的,是MFC CObject 类别中一个名为 



                Serialize  的虚拟函数,文件的「读」「写」动作均透过它。 



498 


…………………………………………………………Page 561……………………………………………………………

                                                       第8章    Document…View  深入探討 



      如果文件内容是借着层层类别向下管理(一如本例),那么只要每一层把自己份内的工 



      作做好,层层交待下来就可以完成整份资料的文件动作。 



Serialization 以外的文件读写动作 



      其实有时候我们希望在重重包装之中返璞归真一下,感受一些质朴的动作。在介绍 



      Serialization 的重重包装之前,这里给你一览文件实际读写动作的机会。 



      文件I/O 服务是任何操作系统的主要服务。Win32 提供了许多文件相关APIs :开档、 



      关文件、读文件、写文件、搜寻资料。。。。MFC 把这些操作都包装在CFile 之中。可想而知,它 
返回目录 上一页 下一页 回到顶部 0 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!