21.4.8 存储订单数据
我们不希望在新订单连一条Product Details记录也没有之前,就在Orders表中创建新记录。因此,需要某种方法将CCustomerView对象中累积的数据传递给CProductView对象。做这件事的简单方法是定义一个表示订单的新类。这个类只需要有对应所希望存储的各个数据值的数据成员即可。除了新订单中显然不应该有的发货日期字段以外,这些数据成员与对应COrderSet类中各个字段的数据成员相同。在项目中创建一个新的头文件Order.h,然后添加下面的代码:
- // Stores the data for a new order
- #pragma once
-
- class COrder
- {
- public:
- // Data members same as fields in COrderSet
- long m_OrderID;
- CString m_CustomerID;
- long m_EmployeeID;
- CTime m_OrderDate;
- CTime m_RequiredDate;
- long m_ShipVia;
- double m_Freight;
- CString m_ShipName;
- CString m_ShipAddress;
- CString m_ShipCity;
- CString m_ShipRegion;
- CString m_ShipPostalCode;
- CString m_ShipCountry;
-
- // Default constructor
- COrder():
- m_OrderID(0), // Will be set by CCustomerView object
- m_EmployeeID(1), // Arbitrary employee ID assigned
- m_ShipVia(3), // Arbitrary shipping company
- m_CustomerID(_T("")), m_Freight(0.0), m_ShipName(_T("")),
- m_ShipAddress(_T("")), m_ShipCity(_T("")), m_ShipRegion(_T("")),
- m_ShipPostalCode(_T("")), m_ShipCountry(_T(""))
- {
- SYSTEMTIME Now;
- GetLocalTime(&Now); // Get current time
- m_OrderDate = m_RequiredDate = CTime(Now); // Set time as today
- }
- };
通常,像上面这样使类的所有数据成员都成为public成员不是什么好习惯,但由于Class Wizard生成的记录集类都有public成员,那么在上面的类中使它们成为private成员也得不到多大的好处。
如果给CDBSimpleUpdateDoc类添加一个COrder类型的数据成员m_Order,就能使用该成员给CProductView对象传递订单数据。必须做的就是在Select Products按钮被按下时,使CCustomerView对象加载该数据成员,从而为CProductView对象的挑选做好准备。可以在CCustomerView类中像下面这样实现Select Products按钮的处理程序:
- void CCustomerView::OnSelectproducts()
- {
- // Get a pointer to the document
- CDBSimpleUpdateDoc* pDoc =
- static_cast<CDBSimpleUpdateDoc*>(GetDocument());
-
- // Set up order field values from CCustomerSet object
- pDoc->m_Order.m_CustomerID = m_pSet->m_CustomerID;
- pDoc->m_Order.m_ShipAddress = m_pSet->m_Address;
- pDoc-> m_Order.m_ShipCity = m_pSet->m_City;
- pDoc-> m_Order.m_ShipCountry = m_pSet->m_Country;
- pDoc-> m_Order.m_ShipName = m_pSet->m_CompanyName;
- pDoc-> m_Order.m_ShipPostalCode = m_pSet->m_PostalCode;
- pDoc-> m_Order.m_ShipRegion = m_pSet->m_Region;
-
- // Set up order field values from CCustomerView dialog input
- pDoc-> m_Order.m_OrderID = m_NewOrderID; // Generated new ID
- pDoc-> m_Order.m_OrderDate = m_OrderDate;// From order date control
- pDoc-> m_Order.m_RequiredDate = m_RequiredDate;
- // From required date control
-
- static_cast<CMainFrame*>(GetParentFrame())->SelectView(SELECT_PRODUCT);
- }
这部分代码很简单。只是在从记录集和记录视图对象向Order对象(是文档对象的成员)复制数值而已。
设置日期
CCustomerView对话框上的日期采集器控件有个小问题:对应这两个控件的m_OrderDate和m_RequiredDate变量此刻还没有初始化,因此相应控件一开始不会显示有意义的数值。我们希望最初显示当前日期,因此应该在最初创建视图对象时调用的OnInitialUpdate()成员的末尾,添加一些初始化这两个变量的代码:
- void CCustomerView::OnInitialUpdate()
- {
- BeginWaitCursor();
- GetRecordset();
- CRecordView::OnInitialUpdate();
- if (m_pSet->IsOpen())
- {
- CString strTitle = m_pSet->m_pDatabase->GetDatabaseName();
- CString strTable = m_pSet->GetTableName();
- if(!strTable.IsEmpty())
- strTitle += _T(":") + strTable;
- GetDocument()->SetTitle(strTitle);
- }
- EndWaitCursor();
-
- // Initialize time values
- SYSTEMTIME Now;
- GetLocalTime(&Now); // Get current time
- m_OrderDate = m_RequiredDate = CTime(Now); // Set time as today
- }
就像在COrder类的构造函数中那样,在这里把两个CTime变量都设置成了当前时间。
现在,CCustomerView对象已经较为完整。该对象可以显示正确的日期,而且可以存储Orders表中某行内所有字段的值,因此下面来解决产品选择问题。