第7章框架窗口、文档和视图 71框架窗旦 7.2文档及其序列化 作业1 73视图及视图类 74文档视图结构 作业2
第7章 框架窗口、文档和视图 7.1框架窗口 7.2文档及其序列化 作业1 7.3视图及视图类 7.4文档视图结构 作业2
7.1框架窗口 7.1.1主窗口和文档窗口 主窗口是应用程序直接放置在桌面上的那个窗口,每个应用程序只能有一个 主窗口,主窗口的标题栏上往往显示应用程序的名称 文档窗口对于SDI程序来说,它和主窗口是一致的,即主窗口就是文档窗口 而对于MDI程序,文档窗口是主窗口的子窗口,如图。文档窗口一般都有相 应的可见边框,它的客户区是由相应的视图来构成的,因此可以说视图是文 档窗口内的子窗口。文档窗口时刻跟踪当前处于活动状态的视图的变化,并 将用户或系统产生的命令消息传递给当前活动视图。而主窗口负责管理各个 用户交互对象并根据用户操作相应地创建或更新文档窗口及其视图。 文件Q)编暗)查看00留口①帮助0 文档窗口 主窗口 图71MD应用程序的框架窗口
7.1框架窗口 7.1.1主窗口和文档窗口 主窗口是应用程序直接放置在桌面上的那个窗口,每个应用程序只能有一个 主窗口,主窗口的标题栏上往往显示应用程序的名称。 文档窗口对于SDI程序来说,它和主窗口是一致的,即主窗口就是文档窗口; 而对于MDI程序,文档窗口是主窗口的子窗口,如图。文档窗口一般都有相 应的可见边框,它的客户区是由相应的视图来构成的,因此可以说视图是文 档窗口内的子窗口。文档窗口时刻跟踪当前处于活动状态的视图的变化,并 将用户或系统产生的命令消息传递给当前活动视图。而主窗口负责管理各个 用户交互对象并根据用户操作相应地创建或更新文档窗口及其视图。 图7.1 MDI应用程序的框架窗口 文档窗口 主窗口
71框架窗口 7.1.2窗口风格的设置 窗口风格 窗口风格通常有一般和扩展两种形式。这两种形式的窗口风格可在函数 CWnd: Create或CWnd: CreateEx参数中指定, CreateEx函数可同时支持以 上两种风格,而CWnd: Create只能指定窗口的一般风格。需要说明的是, 对于控件和对话框这样的窗口来说,它们的窗口风格可直接通过其属性对话 框来设置。 需要说明的是,除了上述风格外,框架窗口还有以下三个自己的风格。它们 都可以在 Precreate Window重载函数中指定 FWS ADDTOTITLE 该风格指定相关的信息如文档名添加到框架窗口标题的后面。 FWS PREFIXTITLE 该风格使得框架窗口标题中的文档名显示在应用程序名之前。 FWS SNAPTOBARS 该风格用来调整窗口的大小,使它刚好包含了框架窗口中的控制栏
7.1框架窗口 7.1.2窗口风格的设置 ➢ 窗口风格 窗口风格通常有一般和扩展两种形式。这两种形式的窗口风格可在函数 CWnd::Create或CWnd::CreateEx参数中指定,CreateEx函数可同时支持以 上两种风格,而CWnd::Create只能指定窗口的一般风格。需要说明的是, 对于控件和对话框这样的窗口来说,它们的窗口风格可直接通过其属性对话 框来设置。 需要说明的是,除了上述风格外,框架窗口还有以下三个自己的风格。它们 都可以在PreCreateWindow重载函数中指定。 ◆ FWS_ADDTOTITLE 该风格指定相关的信息如文档名添加到框架窗口标题的后面。 ◆ FWS_PREFIXTITLE 该风格使得框架窗口标题中的文档名显示在应用程序名之前。 ◆ FWS_SNAPTOBARS 该风格用来调整窗口的大小,使它刚好包含了框架窗口中的控制栏
71框架窗口 >用 MFC AppWizard设置 Document Template String r Use split window Main frame styles F Thick frame F System menu F Minimize box 厂 Minimized F Maximize box Maximized F Thick frame F Maximize box Close 图72 MFC AppWizard的窗口风格设置 表72“ Advanced@ptns”对话框窗口风格的各项含义 选顷 含义 Use split window 选中时,将程序的文档窗口创建成“切分”窗口 Thick frame 选中时,设置窗口风格 WS THICKFRAME 选中时,设置窗口风格 WS MINIMIZEBOX 选中时,设置窗口风格 WS MAXIMIZEBOX System menu 选中时,设置窗口风格 WS SYSMENU Minimized 选中时,设置窗口风格 WS MINIMIZ Maximized 选中时,设置窗口风格 WS MAXIMIZ
7.1框架窗口 ➢ 用MFC AppWizard设置 图7.2 MFC AppWizard的窗口风格设置
71框架窗口 修改 CREATESTRUCT结构 窗口创建之前,系统自动调用 PrecreateWindow虚函数。在用 MFC AppWizard创建 SDI/MDI应用程序结构时,MFC已为主窗口或文档窗口类自动重载了该虚函数。可以 在此函数中通过修改 CREATESTRUCT结构来设置窗口的绝大多数风格 例如,在SD程序中,框架窗口默认的风格是WS_ OVERLAPPEDWINDOW和 FWS ADDTOTITLE的组合,更改风格代码 BOOL CMainFrame: PreCreateWindow(CREATESTRUCT& CS) {∥新窗口不带有[最大化]按钮 cs style & NWS_MAXIMIZEBOX ∥/将窗口的大小设为1/3屏幕并居中 y=: GetSystem Metrics(SM_CYSCREEN)/ CS. CX=: GetSystemMetrics(SM_CXSCREEN)/ Cs.y=((CS. cy *3)-CScy)/2 CS.X=((CS. CX*3)-CS CX)/2 ∥/调用基类的 PrecreateWindow函数 return CFrameWnd: PreCreateWindow(cs) 对于MD程序,文档窗口的风格可用下列的代码更改 BOOL CChildFrame: PreCreateWindow(CREATESTRUCT& cs) {∥/创建不含有[最大化]按钮的子窗口 csstyle & NWS MAXIMIZEBOX ∥/调用基类的 PreCreate Window函数 return CMDIChildWnd: PreCreateWindow(cs)i
7.1框架窗口 ➢ 修改CREATESTRUCT结构 窗口创建之前,系统自动调用PreCreateWindow虚函数。在用MFC AppWizard创建 SDI/MDI应用程序结构时,MFC已为主窗口或文档窗口类自动重载了该虚函数。可以 在此函数中通过修改CREATESTRUCT结构来设置窗口的绝大多数风格。 例如,在SDI程序中,框架窗口默认的风格是WS_OVERLAPPEDWINDOW和 FWS_ADDTOTITLE的组合,更改风格代码: BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { // 新窗口不带有[最大化]按钮 cs.style &= ~WS_MAXIMIZEBOX; // 将窗口的大小设为1/3屏幕并居中 cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3; cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3; cs.y = ((cs.cy * 3) - cs.cy) / 2; cs.x = ((cs.cx * 3) - cs.cx) / 2; // 调用基类的PreCreateWindow函数 return CFrameWnd::PreCreateWindow(cs); } 对于MDI程序,文档窗口的风格可用下列的代码更改: BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs) { // 创建不含有[最大化]按钮的子窗口 cs.style &= ~WS_MAXIMIZEBOX; // 调用基类的PreCreateWindow函数 return CMDIChildWnd::PreCreateWindow(cs); }
71框架窗口 >使用 Modify style和 ModifystyleEX CWnd类中的成员函数 Modify Style和 Modify styleE也可用来更改窗口的风格, 其中 ModifystyleEX还可更改窗口的扩展风格。这两个函数具有相同的参数 其含义如下 BOOL ModifyXXXX( dWord dwRemove, dWORD dwAdd, UINT nFlags=0) 参数 dw remove用来指定需要删除的风格, daDd用来指定需要增加的 风格, nFlags表示 SetWindow Pos的标志,0(默认)表示更改风格的同时不调 用 SetWindowPos函数。 由于框架窗口在创建时不能直接设定其扩展风格,因此只能通过调用 Modify Style函数来进行
7.1框架窗口 ➢ 使用ModifyStyle和ModifyStyleEx CWnd类中的成员函数ModifyStyle和ModifyStyleEx也可用来更改窗口的风格, 其中ModifyStyleEx还可更改窗口的扩展风格。这两个函数具有相同的参数, 其含义如下。 BOOL ModifyXXXX( DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 ); 参数dwRemove用来 指定需要删除的风格,dwAdd用来指定需要增加的 风格,nFlags表示SetWindowPos的标志,0(默认)表示更改风格的同时不调 用SetWindowPos函数。 由于框架窗口在创建时不能直接设定其扩展风格,因此只能通过调用 ModifyStyle函数来进行
71框架窗口 [例 Ex Vscrol多文档(MDI)的子文档窗口增加垂直滚动条 (1)用 MFC AppWizard创建一个多文档应用程序 (2)用 ClassWizard为子文档窗口类 CChildframe添加 On Create client消息处 理,并增加下列代码 BOOL CChildFrame: OnCreate Client(LPCREATESTRUCT lpcs CReate* cOntext) t Modify style(O, WS_VSCROLL, 0) return CMDIChildWnd: On CreateClient(pcs, cOntext) (3)编译并运行,如图。②回? 口x 就绪 数字 图73为文档子窗口添加垂直滚动条
7.1框架窗口 [例Ex_Vscroll] 多文档(MDI)的子文档窗口增加垂直滚动条。 (1)用MFC AppWizard创建一个多文档应用程序。 (2)用ClassWizard为子文档窗口类CChildFrame添加OnCreateClient消息处 理,并增加下列代码: BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { ModifyStyle(0, WS_VSCROLL, 0); return CMDIChildWnd::OnCreateClient(lpcs, pContext); } (3)编译并运行,如图。 图7.3 为文档子窗口添加垂直滚动条
71框架窗口 >设置 TopMost窗口风格 最顶( TopMost)窗口是指那些始终出现在桌面的最前方且不会被其他窗口覆 盖的窗口。如果要创建这样的一个最顶窗口,则在运行时必须指定 WS_ EX TOPMOST扩展窗口风格。此风格的设置是在CWnd: Setwindow pos 函数中进行;作为技巧,我们可以先调用CWnd: GetExStyle函数来确定是 否已经设置了 WS EX TOPMOST风格。例如下面的代码 void SetWindow TopMost(CWnd* pWnd) ASSERT_ VALID(pWnd); pWnd->SetWindowPos((pWnd->GetEXStyle(&Ws_EX_TOPMOST)? &wndNo TopMost: &wnd TopMost, 0,0,0,0 SWP_ NOSIZE SWP_NOMOVE; } 函数 SetWindow Pos具体的使用方法将在下一节中介绍
7.1框架窗口 ➢ 设置TopMost窗口风格 最顶(TopMost)窗口是指那些始终出现在桌面的最前方且不会被其他窗口覆 盖的窗口。如果要创建这样的一个最顶窗口,则在运行时必须指定 WS_EX_TOPMOST扩展窗口风格。此风格的设置是在CWnd::SetWindowPos 函数中进行;作为技巧,我们可以先调用CWnd::GetExStyle函数来确定是 否已经设置了WS_EX_TOPMOST风格。例如下面的代码: void SetWindowTopMost(CWnd* pWnd) { ASSERT_VALID(pWnd); pWnd->SetWindowPos((pWnd->GetExStyle()&WS_EX_TOPMOST)? &wndNoTopMost:&wndTopMost,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE); } 函数SetWindowPos具体的使用方法将在下一节中介绍
71框架窗口 7.1.3窗口状态的改变 >用 Showwindow改变窗口的显示状态 当一个新的应用程序创建之后, InitInstance函数总会调用 Show Window函 数来显示窗口 想要改变改变窗口显示状态,只需根据上表选择所需的参数值,调用 Show Window函数就可达到目的。当然,也可对 CWinAppl的公有型( public 成员变量 m ncmdshow进行赋值,同样能达到效果。下面的代码是将窗口 的初始状态设置为“最小化” BOOL CEx_ SdiApp: InitInstanceo m ncmdshow= SW SHOWMINIMIZED ∥/由于 CEx_ SdiApp类继承了基类 CWinAppl的特性,因此也可在派生类 ∥ CEx_ SdiApp'使用这个公有型成员变量 m ncmdshow。 m_pMainWnd->Show Window(mnCmdshow) m_pMainWnd->UpdateWindowo return TRUe
7.1框架窗口 7.1.3窗口状态的改变 ➢ 用ShowWindow改变窗口的显示状态 当一个新的应用程序创建之后,InitInstance函数总会调用ShowWindow函 数来显示窗口 想要改变改变窗口显示状态,只需根据上表选择所需的参数值,调用 ShowWindow函数就可达到目的。当然,也可对CWinApp的公有型(public) 成员变量m_nCmdShow进行赋值,同样能达到效果。下面的代码是将窗口 的初始状态设置为“最小化” : BOOL CEx_SdiApp::InitInstance() { ... m_nCmdShow = SW_SHOWMINIMIZED; // 由于CEx_SdiApp类继承了基类CWinApp的特性,因此也可在派生类 // CEx_SdiApp使用这个公有型成员变量m_nCmdShow。 m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; }
71框架窗口 用 SetwindowPos或 Movewindow改变窗口的大小和位置 SetWindow Pos不仅可以改变窗口的大小、位置,还可以改变所有窗口在堆栈排列的 次序(Z次序),这个次序是根据它们在屏幕出现的先后来确定的 函数CWnd: MoveWindow也可用来改变窗口的大小和位置,用户必须在 MoveWindow 函数中指定窗口的大小 void MoveWindow( int x, int y, int nwidth, int nHeight, BOOL rEpaint TRUE void MoveWindow( LPCRECT pRect, BOOL bRepaint TRUE 参数x和y表示窗口新的左上角坐标, n Width和 nHeight表示窗口新的宽度和高度, rEpaint用于指定窗口是否重绘, PrEci表示窗口新的大小和位置 使用上述两个函数把主窗口移动到屏幕的(100,100)处(代码添在 CEx_ SdiApp: InitInstance中[ return TRUE]语句之前)。 ∥/使用 SetWindow Pos函数的示例 m_pMainWnd-SetWindowPos(NULL, 100, 100,0,0,SWP_ NOSIZE SWP_ NOZORDER); CRect rcWindow: ∥/使用 MoveWindow函数的示例 m_ pMainWnd->GetWindowRect(rcWindow) m_pMainWnd->MoveWindow(100, 100, rcWindow Width, rcWindow Height, TRUE); 改变窗口的大小和位置的CWnd成员函数还不止以上两个。例如 enter Window函数是 使窗口居于父窗口中央,就像下面的代码 Center Window(CWnd: GetDesktop Window);∥/将窗口置于屏幕中央 AfXGetMainWndo->CenterWindowo ∥/将主框架窗口居中
7.1框架窗口 ➢ 用SetWindowPos或MoveWindow改变窗口的大小和位置 ◆ SetWindowPos不仅可以改变窗口的大小、位置,还可以改变所有窗口在堆栈排列的 次序(Z次序),这个次序是根据它们在屏幕出现的先后来确定的。 ◆ 函数CWnd::MoveWindow也可用来改变窗口的大小和位置,用户必须在MoveWindow 函数中指定窗口的大小。 void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE ); void MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE ); 参数x和y表示 窗口新的左上角坐标,nWidth和nHeight表示窗口新的宽度和高度, bRepaint用于指定窗口是否重绘,lpRect表示窗口新的大小和位置。 ◆ 使用上述两个函数把主窗口移动到屏幕的(100,100)处(代码添在 CEx_SdiApp::InitInstance中[return TRUE]语句之前)。 // 使用SetWindowPos函数的示例 m_pMainWnd->SetWindowPos(NULL,100,100,0,0,SWP_NOSIZE|SWP_NOZORDER); CRect rcWindow; // 使用MoveWindow函数的示例 m_pMainWnd->GetWindowRect(rcWindow); m_pMainWnd->MoveWindow(100,100,rcWindow.Width(),rcWindow.Height(),TRUE); ◆ 改变窗口的大小和位置的CWnd成员函数还不止以上两个。例如CenterWindow函数是 使窗口居于父窗口中央,就像下面的代码: CenterWindow(CWnd::GetDesktopWindow()); // 将窗口置于屏幕中央 AfxGetMainWnd()->CenterWindow(); // 将主框架窗口居中