Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14517756
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:01:32

下载本文示例代码
  从前文可知,在MFC中,文档是真正的数据载体,视图是文档的显示界面,对应同一个文档,可能存在多个视图界面,我们需要另外一种东东来将这些界面管理起来,这个东东就是框架。  MFC创造框架类的初衷在于:把界面管理工作独立出来!框架窗口为应用程序的用户界面提供结构框架,它是应用程序的主窗口,负责管理其包容的窗口。一个应用程序启动时会创建一个最顶层的框架窗口。  MFC提供二种类型的框架窗口:单文档窗口SDI和多文档窗口MDI(你可以认为对话框是另一种框架窗口)。单文档窗口一次只能打开一个文档框架窗口,而多文档窗口应用程序中可以打开多个文档框架窗口,即子窗口(Child Window)。这些子窗口中的文档可以为同种类型,也可以为不同类型。  在Visual C AppWizard的第一个对话框中,会让用户选择应用程序是基于单文档、多文档还是基于对话框的,如图5.1。 图5.1 在AppWizard中选择框架窗口  MFC提供了三个类CFrameWnd、CMDIFrameWnd、CMDIChildWnd用于支持单文档窗口和多文档窗口,这些类的层次结构如图5.2。 图5.2 CFrameWnd、CMDIFrameWnd、CMDIChildWnd类的层次  (1)CFrameWnd类用于SDI应用程序的框架窗口,SDI框架窗口既是应用程序的主框架窗口,也是当前文档对应的视图的边框;CFrameWnd类也作为CMDIFrameWnd和CMDIChildWnd类的父类,而在基于SDI的应用程序中,AppWizard会自动为我们添加一个继承自CFrameWnd类的CMainFrame类。  CFrameWnd类中重要的函数有Create(用于创建窗口)、LoadFrame(用于从资源文件中创建窗口)、PreCreateWindow(用于注册窗口类)等。Create函数第一个参数为窗口注册类名,第二个参数为窗口标题,其余几个参数指定了窗口的风格、大小、父窗口、菜单名等,其源代码如下: BOOL CFrameWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, LPCTSTR lpszMenuName, DWORD dwExStyle, CCreateContext *pContext){ HMENU hMenu = NULL; if (lpszMenuName != NULL) {  // load in a menu that will get destroyed when window gets destroyed  HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);  if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)  {   TRACE0("Warning: failed to load menu for CFrameWnd.\n");   PostNcDestroy(); // perhaps delete the C object   return FALSE;  } }  m_strTitle = lpszWindowName; // save title for later if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, rect.left,rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)) {  TRACE0("Warning: failed to create CFrameWnd.\n");  if (hMenu != NULL)   DestroyMenu(hMenu);  return FALSE; } return TRUE;}  LoadFrame函数用于从资源文件中创建窗口,我们通常只需要给其指定一个参数,LoadFrame使用该参数从资源中获取主边框窗口的标题、图标、菜单、加速键等,其源代码为: BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd*pParentWnd, CCreateContext *pContext){ // only do this once ASSERT_VALID_IDR(nIDResource); ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource); m_nIDHelp = nIDResource; // ID for help context ( HID_BASE_RESOURCE) CString strFullString; if (strFullString.LoadString(nIDResource))  AfxExtractSubString(m_strTitle, strFullString, 0);  // first sub-string VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); // attempt to create the window LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource); LPCTSTR lpszTitle = m_strTitle; if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault, pParentWnd,MAKEINTRESOURCE(nIDResource), 0L, pContext)) {  return FALSE; // will self destruct on failure normally } // save the default menu handle ASSERT(m_hWnd != NULL); m_hMenuDefault = ::GetMenu(m_hWnd); // load accelerator resource LoadAccelTable(MAKEINTRESOURCE(nIDResource)); if (pContext == NULL)  // send initial update  SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); return TRUE;}  在SDI程序中,如果需要修改窗口的默认风格,程序员需要修改CMainFrame类的PreCreateWindow函数,因为AppWizard给我们生成的CMainFrame::PreCreateWindow仅对其基类的PreCreateWindow函数进行调用,CFrameWnd::PreCreateWindow的源代码如下: BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT &cs){ if (cs.lpszClass == NULL) {  VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));  cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background } if ((cs.style &FWS_ADDTOTITLE) && afxData.bWin4)cs.style |= FWS_PREFIXTITLE; if (afxData.bWin4)  cs.dwExStyle |= WS_EX_CLIENTEDGE; return TRUE;}共2页。 1 2 :   从前文可知,在MFC中,文档是真正的数据载体,视图是文档的显示界面,对应同一个文档,可能存在多个视图界面,我们需要另外一种东东来将这些界面管理起来,这个东东就是框架。  MFC创造框架类的初衷在于:把界面管理工作独立出来!框架窗口为应用程序的用户界面提供结构框架,它是应用程序的主窗口,负责管理其包容的窗口。一个应用程序启动时会创建一个最顶层的框架窗口。  MFC提供二种类型的框架窗口:单文档窗口SDI和多文档窗口MDI(你可以认为对话框是另一种框架窗口)。单文档窗口一次只能打开一个文档框架窗口,而多文档窗口应用程序中可以打开多个文档框架窗口,即子窗口(Child Window)。这些子窗口中的文档可以为同种类型,也可以为不同类型。  在Visual C AppWizard的第一个对话框中,会让用户选择应用程序是基于单文档、多文档还是基于对话框的,如图5.1。 图5.1 在AppWizard中选择框架窗口  MFC提供了三个类CFrameWnd、CMDIFrameWnd、CMDIChildWnd用于支持单文档窗口和多文档窗口,这些类的层次结构如图5.2。 图5.2 CFrameWnd、CMDIFrameWnd、CMDIChildWnd类的层次  (1)CFrameWnd类用于SDI应用程序的框架窗口,SDI框架窗口既是应用程序的主框架窗口,也是当前文档对应的视图的边框;CFrameWnd类也作为CMDIFrameWnd和CMDIChildWnd类的父类,而在基于SDI的应用程序中,AppWizard会自动为我们添加一个继承自CFrameWnd类的CMainFrame类。  CFrameWnd类中重要的函数有Create(用于创建窗口)、LoadFrame(用于从资源文件中创建窗口)、PreCreateWindow(用于注册窗口类)等。Create函数第一个参数为窗口注册类名,第二个参数为窗口标题,其余几个参数指定了窗口的风格、大小、父窗口、菜单名等,其源代码如下: BOOL CFrameWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, LPCTSTR lpszMenuName, DWORD dwExStyle, CCreateContext *pContext){ HMENU hMenu = NULL; if (lpszMenuName != NULL) {  // load in a menu that will get destroyed when window gets destroyed  HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);  if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)  {   TRACE0("Warning: failed to load menu for CFrameWnd.\n");   PostNcDestroy(); // perhaps delete the C object   return FALSE;  } }  m_strTitle = lpszWindowName; // save title for later if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, rect.left,rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)) {  TRACE0("Warning: failed to create CFrameWnd.\n");  if (hMenu != NULL)   DestroyMenu(hMenu);  return FALSE; } return TRUE;}  LoadFrame函数用于从资源文件中创建窗口,我们通常只需要给其指定一个参数,LoadFrame使用该参数从资源中获取主边框窗口的标题、图标、菜单、加速键等,其源代码为: BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd*pParentWnd, CCreateContext *pContext){ // only do this once ASSERT_VALID_IDR(nIDResource); ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource); m_nIDHelp = nIDResource; // ID for help context ( HID_BASE_RESOURCE) CString strFullString; if (strFullString.LoadString(nIDResource))  AfxExtractSubString(m_strTitle, strFullString, 0);  // first sub-string VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); // attempt to create the window LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource); LPCTSTR lpszTitle = m_strTitle; if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault, pParentWnd,MAKEINTRESOURCE(nIDResource), 0L, pContext)) {  return FALSE; // will self destruct on failure normally } // save the default menu handle ASSERT(m_hWnd != NULL); m_hMenuDefault = ::GetMenu(m_hWnd); // load accelerator resource LoadAccelTable(MAKEINTRESOURCE(nIDResource)); if (pContext == NULL)  // send initial update  SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); return TRUE;}  在SDI程序中,如果需要修改窗口的默认风格,程序员需要修改CMainFrame类的PreCreateWindow函数,因为AppWizard给我们生成的CMainFrame::PreCreateWindow仅对其基类的PreCreateWindow函数进行调用,CFrameWnd::PreCreateWindow的源代码如下: BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT &cs){ if (cs.lpszClass == NULL) {  VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));  cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background } if ((cs.style &FWS_ADDTOTITLE) && afxData.bWin4)cs.style |= FWS_PREFIXTITLE; if (afxData.bWin4)  cs.dwExStyle |= WS_EX_CLIENTEDGE; return TRUE;}共2页。 1 2 : 下载本文示例代码


深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架深入浅出MFC文档/视图架构之框架
阅读(214) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~