21.4.6 实现对话框切换(2)
该函数首先获得指向该视图的父框架(应用程序的CMainFrame对象)的指针,然后使用该指针调用SelectView()函数,选择新订单处理对话框。源文件中必须添加嵌入MainFrm.h的#include指令,以获得CMainFrame的定义。MainFrm.h文件中还需要有嵌入ViewConstants.h头文件的#include指令,使NEW_ORDER在此处也可用。
CCustomerView类中的Select Products按钮的处理程序使屏幕切换到CProductsView的对话框:
- void CCustomerView::OnSelectproducts()
- {
- static_cast<CMainFrame*>(GetParentFrame())->SelectView(SELECT_PRODUCT);
- }
同一个类中Cancel按钮的处理程序只是切换到前一个视图:
- void CCustomerView::OnCancelorder()
- {
- static_cast<CMainFrame*>(GetParentFrame())->SelectView(ORDER_DETAILS);
- }
不要忘记在CustomerView.cpp文件中添加嵌入MainFrm.h头文件的#include指令。
最后要实现的切换操作在CProductView类的OnDone()处理程序中:
- void CProductView::OnDone()
- {
- static_cast<CMainFrame*>(GetParentFrame())->SelectView(ORDER_DETAILS);
- }
该函数切换到原来的允许浏览和编辑订单细节的应用程序视图。如果愿意,也可以切换到CCustomerView对话框继续录入新订单。再次提醒一下,不要忘记添加嵌入MainFrm.h头文件的#include指令。
从最初允许浏览订单细节的对话框到编辑订单细节对话框的切换操作,现在必须控制New Order按钮的可见性;否则Cancel按钮在编辑对话框中将藏在New Order按钮下面。在COrderDetailsView类中添加一个对应于IDC_NEWORDER ID的控件变量m_NewOrderCtrl,然后将OnEditorder()处理程序修改成:
- void COrderDetailsView::OnEditorder()
- {
- if(m_pSet->CanUpdate())
- {
- try
- {
- if(m_Mode == UPDATE)
- { // When button was clicked we were in update
- // Disable input to edit controls
- m_QuantityCtrl.SetReadOnly();
- m_DiscountCtrl.SetReadOnly();
-
- // Change the Update button text to Edit Order
- m_EditOrderCtrl.SetWindowText(_T("Edit Order"));
-
- // Make the Cancel button invisible
- m_CancelEditCtrl.ShowWindow(SW_HIDE);
-
- // Show the new order button
- m_NewOrderCtrl.ShowWindow(SW_SHOW);
-
- // Complete the update
- m_pSet->Update();
- m_Mode = READ_ONLY; // Change to read-only mode
- }
- else
- { // When button was clicked we were in read-only mode
-
- // Enable input to edit controls
- m_QuantityCtrl.SetReadOnly(FALSE);
- m_DiscountCtrl.SetReadOnly(FALSE);
-
- // Change the Edit Order button text to Update
- m_EditOrderCtrl.SetWindowText(_T("Update"));
-
- // Hide the new order button
- m_NewOrderCtrl.ShowWindow(SW_HIDE);
-
- // Make the Cancel button visible
- m_CancelEditCtrl.ShowWindow(SW_SHOW);
-
- // Start the update
- m_pSet->Edit();
- m_Mode = UPDATE; // Switch to update mode
- }
- }
- catch(CException* pEx)
- {
- pEx->ReportError(); // Display the error message
- }
- }
- else
- AfxMessageBox(_T("Recordset is not updatable."));
- }
现在,根据m_UpdateMode存储的值是READ_ONLY还是UPDATE,相应地隐藏或显示New Order按钮。还必须在OnCancel()处理程序中使该按钮可见:
- void COrderDetailsView::OnCancel()
- {
- m_pSet->CancelUpdate(); // Cancel the update operation
- m_EditOrderCtrl.SetWindowText(_T("Edit")); // Switch button text
- m_CancelEditCtrl.ShowWindow(SW_HIDE); // Hide the Cancel button
- m_NewOrderCtrl.ShowWindow(SW_SHOW); // Show the New Order button
- m_QuantityCtrl.SetReadOnly(TRUE); // Set state of quantity edit control
- m_DiscountCtrl.SetReadOnly(TRUE); // Set state of discount edit control
- m_UpdateMode = !m_UpdateMode; // Switch the mode
- }
我们迄今所做的事情是为了实现基本的视图切换机制。还需要回头添加处理数据库更新操作的代码;但此刻应该尝试编译并运行一下已有的代码,以消除任何引入的打字错误或其他错误。在程序可以工作之后,应该能够滚动客户和产品记录。一定要确保检查了所有切换路径。