【C++】【MFC】CView和CDocument关联以及COMMAND消息走向

MFC编程中,CView类负责显示,CDocument负责数据管理,所以其之间的联系十分重要,包括COMMAND消息的流向

CView中的m_pDocument成员将存储和其关联的唯一的CDocument地址,而CDocument中的m_viewList链表将存储和其关联的所有CView地址,即一个CDocument可以有多个CView,但一个CView只能有一个CDocument。

关于COMMAND消息走向,其优先级分别是:CView -> CDocument -> CFrameWnd -> CWinApp。

Code:

  1 #include <afxwin.h>
  2 #include <afxext.h>
  3 #include "resource.h"
  4 
  5 // 文档类
  6 class CMyDoc : public CDocument {
  7     DECLARE_MESSAGE_MAP()                    // 消息映射—类内声名宏
  8 public:
  9     CString str;                            // 数据管理
 10     afx_msg void OnNew();                    // ID_FILE_NEW消息映射回调函数
 11 };
 12 BEGIN_MESSAGE_MAP(CMyDoc, CDocument)        // 消息映射—类外实现宏
 13     ON_COMMAND(ID_FILE_NEW, OnNew)            // 触发COMMAND消息的控件和回调函数
 14 END_MESSAGE_MAP()
 15 
 16 // 在CMyDoc中触发 ID_FILE_NEW 控件后执行该函数
 17 void CMyDoc::OnNew() {
 18     str = "HELLO, WORLD";                    
 19     POSITION pos = GetFirstViewPosition();    // 获取m_viewList链表头节点的前一个地址
 20     CView* pView = GetNextView(pos);        // 获取头节点地址
 21     UpdateAllViews(pView);                    // 更新除第一个View窗口以外的所有窗口
 22 }
 23 
 24 // 视图类
 25 class CMyView : public CView {
 26     DECLARE_DYNCREATE(CMyView)                // 动态创建—类内声名宏
 27     DECLARE_MESSAGE_MAP()                    
 28 public:
 29     virtual void OnDraw(CDC* pdc);            // 父类绘图函数
 30     afx_msg int OnCreate(LPCREATESTRUCT pcs);
 31     afx_msg void OnNew();
 32 };
 33 IMPLEMENT_DYNCREATE(CMyView, CView)            // 动态创建—类外实现宏
 34 BEGIN_MESSAGE_MAP(CMyView, CView)
 35     //ON_COMMAND(ID_FILE_NEW, OnNew)
 36     ON_WM_CREATE()
 37 END_MESSAGE_MAP()
 38 
 39 // 在 CMyView 中触发 ID_FILE_NEW 控件后执行该函数
 40 void CMyView::OnNew() {
 41     AfxMessageBox("View.");                    // 弹出消息框,内容为“View.”
 42 }
 43 
 44 int CMyView::OnCreate(LPCREATESTRUCT pcs) {
 45 
 46     return CView::OnCreate(pcs);
 47 }
 48 
 49 // 在 CView 客户区中绘制界面
 50 void CMyView::OnDraw(CDC* pdc) {
 51     //CMyDoc* pDoc = (CMyDoc*)m_pDocument;
 52     CMyDoc* pDoc = (CMyDoc*)GetDocument();    // 获取文档类地址
 53     pdc->TextOut(100, 100, pDoc->str);        // 将文档类中的str成员变量输出至View窗口中
 54 }
 55 
 56 // 框架窗口类
 57 class CMyFrameWnd : public CFrameWnd {
 58     DECLARE_MESSAGE_MAP()
 59 public:
 60     CSplitterWnd split;
 61 public:
 62     afx_msg int OnCreate(LPCREATESTRUCT pcs);
 63     afx_msg void OnPaint();
 64     virtual BOOL OnCreateClient(LPCREATESTRUCT psc, CCreateContext* pContext);
 65 };
 66 BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
 67     ON_WM_PAINT()
 68     ON_WM_CREATE()
 69 END_MESSAGE_MAP()
 70 
 71 BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT psc, CCreateContext* pContext) {
 72     // 划分为一个一行两列的两个View
 73     split.CreateStatic(this, 1, 2);
 74     // 创建第一个View
 75     split.CreateView(0, 0, pContext->m_pNewViewClass, CSize(100, 100), pContext);
 76     split.CreateView(0, 1, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
 77 
 78     // 设置第一个View为活动窗口
 79     m_pViewActive = (CView*)split.GetPane(0,0);  
 80     return TRUE;
 81 }
 82 
 83 void CMyFrameWnd::OnPaint() {
 84     PAINTSTRUCT ps = { 0 };
 85     HDC hdc = ::BeginPaint(m_hWnd, &ps);
 86     ::TextOut(hdc, 100, 100, "123", 3);
 87     ::EndPaint(m_hWnd, &ps);
 88 }
 89 
 90 int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) {
 91 
 92     return CFrameWnd::OnCreate(pcs);
 93     //return 0;
 94 }
 95 
 96 class CMyWinApp : public CWinApp {
 97 public:
 98     virtual BOOL InitInstance();
 99 };
100 
101 BOOL CMyWinApp::InitInstance() {
102     CMyFrameWnd* pFrame = new CMyFrameWnd;
103     CMyDoc* pDoc = new CMyDoc;
104     CCreateContext cct;
105     cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
106     cct.m_pCurrentDoc = pDoc;
107     pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
108     m_pMainWnd = pFrame;
109     pFrame->ShowWindow(SW_SHOW);
110     pFrame->UpdateWindow();
111 
112     return TRUE;
113 }
114 
115 CMyWinApp theApp;

 

posted @ 2024-06-21 09:31  VanGoghpeng  阅读(27)  评论(0编辑  收藏  举报