21.4.6 实现对话框切换(1)
在图21-12中已经了解了该程序中切换对话框的基本逻辑。按钮单击是从一个对话框切换到下一个对话框的机制,因此按钮处理程序应该包含使切换发生的代码。首先定义视图ID来标识这3个对话框中的每一个,因此添加一个名为ViewConstants.h的头文件。这次可以尝试使用枚举声明来标识这些视图,因此该文件应该包含下面的代码:
- // Definition of constants identifying the record views
-
- #pragma once
-
- enum ViewID{ ORDER_DETAILS, NEW_ORDER, SELECT_PRODUCT};
在CMainFrame类中需要有一个ViewID类型的变量来记录当前视图的ID,因此通过在Class View中右击CMainFrame,并从弹出菜单中选择Add | Add Variable,添加变量m_CurrentViewID。需要初始化该变量,因此将CMainFrame类的构造函数修改成下面这样:
- CMainFrame::CMainFrame() : m_CurrentViewID(ORDER_DETAILS)
- {
- // TODO: add member initialization code here
- }
这样将确定应用程序开始时总是要显示的视图。ViewConstants.h头文件的#include指令被自动添加到MainFrm.h文件中,从而使视图ID的定义在MainFrm.cpp文件中可用。
现在可以给CMainFrame类添加执行对话框之间切换操作的成员函数SelectView()。其返回类型是void,单个形参的类型是ViewID,因为实参是枚举声明中定义的视图ID之一。SelectView()函数的实现如下所示:
- // Enables switching between views. The argument specifies the new view
- void CMainFrame::SelectView(ViewID viewID)
- {
- CView* pOldActiveView = GetActiveView(); // Get current view
-
- // Get pointer to new view if it exists
- // if it doesn't the pointer will be null
- CView* pNewActiveView = static_cast<CView*>(GetDlgItem(viewID));
-
- // If this is first time around for the new view, the new view
- // won't exist, so we must create it
- // The Order Details view is always created first so we don't need
- // to provide for creating that.
- if (pNewActiveView == NULL)
- {
- switch(viewID)
- {
- case NEW_ORDER: // Create view to add new order
- pNewActiveView = new CCustomerView;
- break;
- case SELECT_PRODUCT: // Create view to add product to order
- pNewActiveView = new CProductView;
- break;
- default:
- AfxMessageBox(_T("Invalid View ID"));
- return;
- }
-
- // Switching the views
- // Obtain the current view context to apply to the new view
- CCreateContext context;
- context.m_pCurrentDoc = pOldActiveView->GetDocument();
- pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault,
- this, viewID, &context);
- pNewActiveView->OnInitialUpdate();
- }
- SetActiveView(pNewActiveView); // Activate the new view
- pOldActiveView->ShowWindow(SW_HIDE); // Hide the old view
- pNewActiveView->ShowWindow(SW_SHOW); // Show the new view
- pOldActiveView->SetDlgCtrlID(m_CurrentViewID); // Set the old view ID
- pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
- m_CurrentViewID = viewID; // Save the new view ID
- RecalcLayout();
- }
这里的代码引用了CCustomerView和CProductView类,因此源文件中需要有嵌入CustomerView.h和ProductView.h的#include指令。
从订单细节对话框切换到开始新订单创建的对话框,该操作是在COrderDetailsView类的OnNeworder()处理程序中完成的:
- void COrderDetailsView::OnNeworder()
- {
- static_cast<CMainFrame*>(GetParentFrame())->SelectView(NEW_ORDER);
- }