21.4.7 创建订单ID(2)
除这里使用的移动函数以外,记录集对象还提供了另外3个移动函数,见表21-6。
表 21-6
|
MoveLast()< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
移动到记录集中的最后一条记录。
不能对只能向前滚动的记录集使用
该函数(或MoveFirst()函数),否则将
得到一个CDBException类型的异常 |
|
MovePrev() |
移动到记录集中当前记录前面的
那条记录。如果当前记录前面没有记
录,则移动到超过第一条记录的位置。
此后,记录集字段无效,IsBOF()函数返回true |
|
Move() |
该函数用来移过记录集中的一条或多
条记录。第一个long类型的实参指定
要移过的行数。第二个WORD类型的
实参确定移动操作的性质。供第二个实
参使用的4个值使该函数等价于已经见
过的其他移动函数。在Visual C++(www.cppentry.com)文档
中,可以找到关于该函数的更多细节 |
当while循环结束时,将得到存储在newOrderID中的最大订单ID,因此在返回该变量之前只需令其加1即可。
最后一步是把新订单的ID传输给控件,使其出现在IDD_CUSTOMER_FORM对话框中。为此,需要以FALSE作为实参,调用记录集视图对象的UpdateData()函数。记录视图类中的这个函数是从CWnd类继承的。FALSE实参使数据从视图类的数据成员传输到对话框的控件上。TRUE实参使数据从控件上检索出来,并存储在数据成员中。在这两种情况中,数据交换都是通过使框架调用视图类的DoDataExchange()成员实现的。
3. 启动ID创建过程
当初次显示时,客户视图需要可用的新订单ID。给CCustomerView类添加一个public成员函数SetNewOrderID(),并以下面的代码将其实现:
- void CCustomerView::SetNewOrderID(void)
- {
- // Get a new order ID from the COrderSet object in the document
- m_NewOrderID = static_cast<CDBSimpleUpdateDoc*>
- (GetDocument())->m_OrderSet.CreateNewOrderID();
- UpdateData(FALSE); // Transfer data to controls
- }
继承的GetDocument()函数返回的指针属于CDocument类型。需要使用该指针来访问派生类的m_OrderSet成员,因此必须将其强制转换为CDBSimpleUpdateDoc*类型。然后,为该文档类的m_OrderSet成员调用返回新订单ID的成员函数,并将结果存入CCustomerView类的m_NewOrderID成员。调用视图类中继承的UpdateData()成员将把数据从视图的数据成员传输到控件上。现在,必须给客户视图类的源文件添加嵌入DBSimpleUpdateDoc.h头文件的#include指令,因为要引用类名CDBSimpleUpdateDoc。
因为只创建了一个CCustomerView对象,并打算在需要时重用该对象,所以在每次切换到该视图时都需要有可用的新ID。CMainFrame对象的SelectView()成员处理对话框之间的切换,也是初次创建CCustomerView对象的地方。该函数是启动新订单ID创建过程的好地方。需要做的全部就是在视图对应于CCustomerView的情况下,添加一些调用SetNewOrderID()成员的代码。
- 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
- if(viewID==NEW_ORDER)
- static_cast<CCustomerView*>(pNewActiveView)->SetNewOrderID();
-
- 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();
- }
我们做的全部工作只是检查viewID的值。如果是NEW_ORDER,就调用新视图对象的SetNewOrderID()成员。因为pNewActiveView属于CView类型,所以必须将其强制转换为实际的视图类型才能调用SetNewOrderID()成员函数。