• 六、MFC文档类(单文档和多文档)


    一、单文档视图架构程序

    1、单文档视图架构使用

    (1)参与架构的类

            CFrameWnd / CWinApp / CView / CDocument

    (2)使用到的类

            CDocTemplate(文档模板类)

                    CSingleDocTemplate(单文档模板类)

            CDocManager(文档管理类)

    (3)参与架构的四个类,除了应用程序类,其余单个类均支持动态创建机制

    2、创建项目

    (1)创建项目(MFCSdi)

    (2)编写程序

    1. #include
    2. #include "resource.h"
    3. class CMyDoc:public CDocument
    4. {
    5. DECLARE_DYNCREATE(CMyDoc)
    6. };
    7. IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
    8. class CMyView:public CView
    9. {
    10. DECLARE_DYNCREATE(CMyView)
    11. public:
    12. virtual void OnDraw(CDC* pDC);
    13. };
    14. IMPLEMENT_DYNCREATE(CMyView, CView)
    15. void CMyView::OnDraw(CDC* pDC)
    16. {
    17. pDC->TextOut(100, 100, "视图窗口");
    18. }
    19. class CMyFrameWnd:public CFrameWnd
    20. {
    21. DECLARE_DYNCREATE(CMyFrameWnd)
    22. };
    23. IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd)
    24. class CMyWinApp:public CWinApp
    25. {
    26. virtual BOOL InitInstance();
    27. };
    28. BOOL CMyWinApp::InitInstance()
    29. {
    30. CSingleDocTemplate* pTemplate = new CSingleDocTemplate(IDR_MENU1,
    31. RUNTIME_CLASS(CMyDoc),
    32. RUNTIME_CLASS(CMyFrameWnd),
    33. RUNTIME_CLASS(CMyView));
    34. AddDocTemplate(pTemplate);
    35. OnFileNew();
    36. m_pMainWnd->ShowWindow(SW_SHOW);
    37. m_pMainWnd->UpdateWindow();
    38. return TRUE;
    39. }
    40. CMyWinApp theApp;

    (3)创建资源(.rc文件)与菜单

    (4)创建字符串资源,创建(AFX_IDS_UNTITLED),否则程序无法运行

     

    3、执行过程

    1. //单文档模板类构造
    2. CSignleDocTemplate* pTmplate
    3. m_pOnlyDoc //唯一的文档类对象地址
    4. m_pDocClass // RUNTIME_CLASS(CMyDoc)
    5. m_pFrameClass // RUNTIME_CLASS(CMyFrameWnd)
    6. m_pViewClass // RUNTIME_CLASS(CMyView)
    7. //AddDocTemplate(pTmplate)
    8. theApp
    9. m_pDocManager=new CDocManager //文档管理类
    10. m_templateList.AddTail(pTmplate) //模板列表,保存单文档模板类
    11. //OnFileNew()
    12. OnFileNew()
    13. {
    14. m_pDocManager->OnFileNew() //文档管理类
    15. {
    16. CDocTemplate* pTemplate = m_templateList.GetHead();//取出单文档模板类对象地址
    17. pTemplate->OpenDocumentFile()//函数内部this为单文档模板类对象地址
    18. {
    19. OpenDocumentFile(..)//函数内部this为单文档模板类对象地址
    20. {
    21. pDocument = CreateNewDocument()//函数内部this为单文档模板类对象地址
    22. {
    23. CDocument* pDocument = m_pDocClass->CreateObject();
    24. //动态创建文档类对象,并返回对象地址
    25. AddDocument(pDocument)//函数内部this为单文档模板类对象地址
    26. {
    27. m_pOnlyDoc = pDocument;
    28. }
    29. }
    30. pFrame = CreateNewFrame(pDocument..)//函数内部this为单文档模板类对象地址
    31. {
    32. CCreateContext context;
    33. ...
    34. context.m_pCurrentDoc = pDocument;//文档类对象地址
    35. context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
    36. CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
    37. //动态创建框架类对象,并返回对象地址
    38. pFrame->LoadFrame(...., &context);//创建框架窗口
    39. }
    40. }
    41. }
    42. }
    43. }

    4、生成向导生成的单文档框架(参考第一篇文章)

     

    5、类向导(通过向导实现MFC部分功能)

    (1)选中项目右键,打开类向导

    (2)选择项目和类名称

    (3)添加一个处理鼠标消息的函数,双击消息、双击函数,即可创建处理函数

     

    二、多文档视图架构

             可以同时管理多个文档,可以有多个文档类对象

    1、多文档视图架构使用

    (1)参与架构的类

            CMDIFrameWnd / CMDIChileWnd / CWinApp / CView / CDocument

    (2)需要用到的类

            CDocTemplate(文档模板类)

                    CMultiDocTemplate(多文档模板类)

            CDocManager(文档管理类)

    2、创建项目

    (1)创建项目(MFCMdi)

    (2)编写程序

    1. #include
    2. #include "resource.h"
    3. class CMyDoc:public CDocument
    4. {
    5. DECLARE_DYNCREATE(CMyDoc)
    6. };
    7. IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
    8. class CMyView:public CView
    9. {
    10. DECLARE_DYNCREATE(CMyView)
    11. public:
    12. virtual void OnDraw(CDC* pDC);
    13. };
    14. IMPLEMENT_DYNCREATE(CMyView, CView)
    15. void CMyView::OnDraw(CDC* pDC)
    16. {
    17. pDC->TextOutA(100, 100, "视图窗口");
    18. }
    19. class CMyChild:public CMDIChildWnd
    20. {
    21. DECLARE_DYNCREATE(CMyChild)
    22. };
    23. IMPLEMENT_DYNCREATE(CMyChild, CMDIChildWnd)
    24. class CMyFrameWnd:public CMDIFrameWnd
    25. { //不支持动态创建
    26. };
    27. class CMyWinApp:public CWinApp
    28. {
    29. virtual BOOL InitInstance();
    30. };
    31. BOOL CMyWinApp::InitInstance()
    32. {
    33. CMyFrameWnd* pFrame = new CMyFrameWnd;
    34. pFrame->LoadFrame(IDR_MENU1);
    35. m_pMainWnd = pFrame;
    36. pFrame->ShowWindow(SW_SHOW);
    37. pFrame->UpdateWindow();
    38. CMultiDocTemplate* pTemplate = new CMultiDocTemplate(IDR_MENU2,
    39. RUNTIME_CLASS(CMyDoc),
    40. RUNTIME_CLASS(CMyChild),
    41. RUNTIME_CLASS(CMyView));
    42. AddDocTemplate(pTemplate);
    43. OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
    44. OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
    45. OnFileNew(); //创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
    46. return TRUE;
    47. }
    48. CMyWinApp theApp;

    (3)添加菜单项(IDR_MENU1, IDR_MENU2)

    (4)添加字符串资源(AFX_IDS_UNTITLED)

     3、创建流程

    1. CMultiDocTemplate* pTemplate //多文档模板类
    2. m_docList //保存多个文档对象地址
    3. m_DocClass // RUNTIME_CLASS(CMyDoc)
    4. m_pFrameClass // RUNTIME_CLASS(CMyChild)
    5. m_pViewClass // RUNTIME_CLASS(CMyView)
    6. theApp
    7. m_pDocManager=new CDocManager //文档管理类对象
    8. m_templateList.AddTail(pTemplate)
    9. CMyFrameWnd* pFrame = new CMyFrameWnd;
    10. pFrame->LoadFrame( IDR_MENU1 )//函数内部this为pFrame
    11. {
    12. CFrameWnd::LoadFrame(..)//函数内部this为pFrame
    13. {
    14. Create(..)//函数内部this为pFrame
    15. {
    16. CreateEx(..)//函数内部this为pFrame
    17. {
    18. //就会主框架窗口。
    19. }
    20. }
    21. }
    22. }
    23. OnFileNew( )//函数内部this为&theApp
    24. {
    25. m_pDocManager->OnFileNew()//函数内部this为文档管理类对象地址
    26. {
    27. CDocTemplate* pTemplate = m_templateList.GetHead();//取出多文档模板类对象地址
    28. pTemplate->OpenDocumentFile()//函数内部this为多文档模板类对象地址
    29. {
    30. OpenDocumentFile(..)//函数内部this为多文档模板类对象地址
    31. {
    32. pDocument = CreateNewDocument()//函数内部this为多文档模板类对象地址
    33. {
    34. CDocument* pDocument = m_pDocClass->CreateObject();
    35. //动态创建文档类对象,并返回对象地址
    36. AddDocument(pDocument)//函数内部this为多文档模板类对象地址
    37. {
    38. m_docList.AddTail(pDoument);//将文档类对象扔到多文档模板类的链表成员中
    39. }
    40. }
    41. pFrame = CreateNewFrame(pDocument..)//函数内部this为多文档模板类对象地址
    42. {
    43. CCreateContext context;
    44. ...
    45. context.m_pCurrentDoc = pDocument;//文档类对象地址
    46. context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
    47. CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
    48. //动态创建框子架类对象,并返回对象地址
    49. pFrame->LoadFrame(...., &context);//创建子框架窗口
    50. }
    51. }
    52. }
    53. }
    54. }

    三、MFC绘图

    1、绘图实现

    (1)WIN32

            绘图设备句柄(HDC)

    (2)MFC

            类对象(绑定了绘图设备句柄 HDC)

                    CDC类,绘图设备类,m_hDC,m_hAttribDC

                            CPaintDC类,CDC的子类,封装了WM_PAINT消息中绘图的绘图设备

                            CClientDC类,CDC的子类,封装了客户区绘图的绘图设备

    2、创建项目

    (1)创建项目(MFCDraw),MFC单文档架构程序

    (2)使用类向导,在视图类添加绘图消息处理函数

    3、通过CPaintDC在绘图处理函数绘图

    (1)在OnPaint处理函数绘图

    1. void CMFCDrawView::OnPaint()
    2. {
    3. CPaintDC dc(this); // device context for painting
    4. dc.Rectangle(100, 100, 200, 200); //绘制一个矩形
    5. }

     

    (2)CPaintDC构造过程

    1. CPaintDC dc(CWnd* pView)
    2. {
    3. Attach(::BeginPaint(pView->m_hWnd, &m_ps))//函数内部this为&dc
    4. {
    5. m_hDC = hDC;//将BeginPaint获取的绘图设备句柄 保存到dc对象的一个成员变量中
    6. SetAttribDC(m_hDC)//函数内部this为&dc
    7. {
    8. m_hAttribDC = m_hDC;//dc对象的另一个成员变量也保存了绘图设备句柄
    9. }
    10. }
    11. }

    3、使用CClientDC绘图

    (1)添加菜单项

     (2)使用类向导创建命令处理函数

     (3)在命令处理函数绘图,点击绘图命令就会绘制圆形(窗口大小改变会消失,改变窗口时会重绘)

    1. void CMFCDrawView::OnClient()
    2. {
    3. CClientDC dc(this);
    4. dc.Ellipse(200, 200, 300, 300); //画圆
    5. }
    1. CPaintDC dc(pView) === CPaintDC::CPaintDC(...)//函数内部this为&dc
    2. {
    3. Attach(::BeginPaint(pView->m_hWnd, &m_ps))//函数内部this为&dc
    4. {
    5. m_hDC = hDC;//将BeginPaint获取的绘图设备句柄 保存到dc对象的一个成员变量中
    6. SetAttribDC(m_hDC)//函数内部this为&dc
    7. {
    8. m_hAttribDC = m_hDC;//dc对象的另一个成员变量也保存了绘图设备句柄
    9. }
    10. }
    11. }

     4、绘图相关类

    CGdiObject类(绘图对象类),m_hObject

            CPen类(父类为CGdiObject),封装了画笔的操作

            CBrush类(父类为CGdiObject),封装了画刷的操作

            CFont类(父类为CGdiObject),封装了字体的操作

            CBitmap类(父类为CGdiObject),封装了为图的操作

    (1)添加菜单项

     (2)使用类向导创建目录处理函数

    1. void CMFCDrawView::OnPen()
    2. {
    3. // TODO: 在此添加命令处理程序代码
    4. CClientDC dc(this);
    5. CPen pen(PS_SOLID, 2, RGB(255,0,0));
    6. CPen* oldPen = dc.SelectObject(&pen);
    7. dc.Rectangle(100, 100, 200, 200);
    8. dc.SelectObject(oldPen);
    9. pen.DeleteObject();
    10. }
    1. CPen pen(PS_SOLID, 2, RGB(255,0,0)) === CPen::CPen(PS_SOLID, 2, RGB(255,0,0))
    2. //函数内部this &pen
    3. {
    4. Attach(::CreatePen(PS_SOLID, 2, RGB(255,0,0)))//函数内部this &pen
    5. {
    6. m_hObject = hObject;//将::CreatePen获取的画笔句柄,保存到pen对象的一个成员变量中
    7. }
    8. }

    1. void CMFCDrawView::OnBrush()
    2. {
    3. // TODO: 在此添加命令处理程序代码
    4. CClientDC dc(this);
    5. CBrush brush(RGB(0,255,0));
    6. CBrush* oldBrush = dc.SelectObject(&brush);
    7. dc.Ellipse(100, 100, 200, 200);
    8. dc.SelectObject(oldBrush);
    9. brush.DeleteObject();
    10. }

     void CMFCDrawView::OnFont()
    {
        // TODO: 在此添加命令处理程序代码
        CClientDC dc(this);
        CFont font;
        font.CreatePointFont(300,"黑体");
        CFont* oldBrush = dc.SelectObject(&font);
        dc.TextOut(100, 100, "你好");
        dc.SelectObject(oldBrush);
        font.DeleteObject();
    }

     位图绘制:

    创建位图资源 

     

     

     

    1. void CMFCDrawView::OnBmp()
    2. {
    3. //添加位图资源
    4. //创建一个当前DC相匹配的内存DC
    5. CClientDC dc(this);
    6. CDC memdc;
    7. memdc.CreateCompatibleDC(&dc);
    8. //将位图的数据送给内存DC
    9. CBitmap bmp;
    10. bmp.LoadBitmap(IDB_BITMAP1);
    11. CBitmap* oldBmp = memdc.SelectObject(&bmp);
    12. //成像
    13. dc.BitBlt(100, 100, 48, 48, &memdc, 0, 0, SRCCOPY);
    14. //将位图数据要回来
    15. memdc.SelectObject(oldBmp);
    16. //销毁位图
    17. bmp.DeleteObject();
    18. //销毁内存DC
    19. memdc.DeleteDC();
    20. }

     

     

  • 相关阅读:
    好用的PDF解密工具哪个好?
    基于多级适应方法的无人机(UAV)在发动机输出情况下的导航和路径规划(Matlab代码实现)
    浅尝Spring注解开发_Servlet3.0与SpringMVC
    海智算法训练营第三十一天 | 第八章 贪心算法 part02 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II
    在JavaScript中检查一个数字是否是另一个数字的倍数
    java毕业生设计学生选课咨询系统计算机源码+系统+mysql+调试部署+lw
    你对MongoDB和Mysql的差异性了解多少?
    ffmpeg的基本功能介绍
    linux挖矿病毒kthreaddk横行,如何灭掉它?
    [汇编语言]寄存器
  • 原文地址:https://blog.csdn.net/liutit/article/details/126043250