MFC应用程序中的对象通信

发表于:2007-07-04来源:作者:点击数: 标签:
湖南商检局 扶忠践 使用MFC AppWizard 构造的应用程序框架,主要包括以下几个对象:应用程序对象、文档模板、主框架窗口对象、文档对象、视口对象等,它们各自的任务见表1,它们之间的关系见图1。 图1 应用程序、文档模板、文档、框架窗口及视口对象之间的相
湖南商检局 扶忠践

  使用MFC AppWizard 构造的应用程序框架,主要包括以下几个对象:应用程序对象、文档模板、主框架窗口对象、文档对象、视口对象等,它们各自的任务见表1,它们之间的关系见图1。
http://www.ltesting.net/uploads/2007/07/1_200707042008571.jpg (20770 字节)
http://www.ltesting.net/uploads/2007/07/1_200707042008572.jpg (12492 字节)
图1 应用程序、文档模板、文档、框架窗口及视口对象之间的相互关系

  应用程序用对象分工的方式,将程序的主要任务分布在这些对象中。这些对象通过用其他对象成员函数和发送消息来相互通信协同工作。

  当我们没有弄清MFC 应用程序的这种对象分工机制和这些对象之间的通信方法时,我们就总感慨MFC 编程的困难,一头雾水,无法领略到MFC 编程的魅力。

  由此看来,MFC 编程中一个经常遇到的问题就是如何访问应用程序的其他对象,以利用属于这些对象的函数,也就是对象通信的问题。当我们用AppWizard 产生一个应用程序后,在视类中就自动加入了成员函数GetDocument(),有了这个函数,视类就可以完成从视类到文档对象的通信,就可以操作文档类的成员函数和成员变量。但这是不够的,下表列出了MFC 应用程序的对象之间的通信方法。
http://www.ltesting.net/uploads/2007/07/1_200707042008573.jpg (31748 字节)
  下面我们给出一个实例,当双击视窗时,它将实现以下功能:

  改变原来视窗显示的内容和变量的值;
  改变主框架窗口和子框架窗口的标题;
  改变状态条的内容;
  增加一个菜单的选项;
  变化工具条图标;
  运行AppWizard,产生一个多文档的名称为Test 的工程;
  为工程加入ID 号为ID_MY_MENU 的资源;
  为CTestDoc 类增加成员变量CString TestText。

class CTestDoc : public Cdocument
{
public:
      CString TestText;
};

BOOL CTestDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
 return FALSE;
  TestText=" 初次进入,
   未有双击事件!";// 初始化TestText;
      return TRUE;
}

void CTestView::OnDraw(CDC *pDC)
{
      CTestDoc *pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      pDC ->TextOut(5,5,pDoc ->TestText);
}
  用ClassWizard 为CTestView 类增加处理鼠标左键双击事件的函数;

void CTestView::OnLButtonDblClk
(UINT nFlags, CPoint point)
{
    CView::OnLButtonDblClk(nFlags, point);
    //CTestDoc 的成员变量
      TestText 被重新赋值!
      CTestDoc *pDoc = GetDocument();
      pDoc ->TestText=" 双击事件发生,
       变量TestText 被重新赋值!";
      InvalidateRect(NULL,TRUE);

// 变化子框架窗口的标题
      CWnd *pParent= GetParentFrame();
      pParent ->SetWindowText
   (" 双击事件发生,变量TestText
       被重新赋值!这是在子窗口!!");

     // 变化主框架窗口的标题
     AfxGetApp() ->m_pMainWnd ->
     SetWindowText(" 双击事件发生,
     变量TestText 被重新赋值!
     这是在主窗口!!");

    // 变化状态条的内容
    CStatusBar *pStatus=(CStatusBar *)
   AfxGetApp() ->m_pMainWnd ->
    GetDescendantWindow(AFX_IDW_STATUS_BAR);
    if (pStatus) pStatus ->SetPaneText
    (0," 双击事件发生,变量TestText
      被重新赋值!这是在状态条!!");

    // 插入新的菜单项目ID_MY_MENU,
          标题为新菜单
      CMenu *pMenu;
      pMenu=AfxGetApp() ->m_pMainWnd ->GetMenu();
      pMenu ->InsertMenu
         ( -1,MF_BYCOMMAND,ID_MY_MENU," 新菜单");
   AfxGetApp() ->m_pMainWnd ->DrawMenuBar();

// 变化工具条
CToolBar *pTool=(CToolBar *)AfxGetApp() ->
m_pMainWnd ->GetDescendantWindow
(AFX_IDW_ TOOLBAR);
pTool ->SetButtons(NULL,8);
pTool ->SetButtonInfo
(0,ID_FILE_NEW,TBBS_BUTTON,0);
pTool ->SetButtonInfo
(1,ID_FILE_OPEN,TBBS_BUTTON,1);
pTool ->SetButtonInfo
(2,ID_FILE_SAVE,TBBS_BUTTON,2);
pTool ->SetButtonInfo
(3,ID_SEPARATOR,TBBS_SEPARATOR,4);
pTool ->SetButtonInfo
(4,ID_EDIT_CUT,TBBS_BUTTON,4);
pTool ->SetButtonInfo
(5,ID_EDIT_COPY,TBBS_BUTTON,5);
pTool ->SetButtonInfo
(6,ID_EDIT_PASTE,TBBS_BUTTON,6);
pTool ->SetButtonInfo
(7,ID_SEPARATOR,TBBS_SEPARATOR,4);
}   

原文转自:http://www.ltesting.net