Oracle
AppWizard for Microsoft Visual C++
Release 8.1.5 for Windows NT A67160-01 |
|
This chapter walks you through the creation and customization of an application generated by Oracle AppWizard for Microsoft Visual C++. All of the customization lessons presented in this tutorial are based on information described in Chapter 3, "Understanding Your Application's Code." The tutorial introduces each lesson with an explanation of what you will have learned after you complete it.
By working through all the lessons of this tutorial, you will have mastered how to create and customize an Oracle AppWizard starter application. This chapter is organized as follows:
A store owner must keep accurate records of all customers and their purchases. And a database application is perfect for this job.
In this tutorial, you will develop a custom purchase order application for Nicole's Sporting Goods called "Order." This business must track information about sales orders, the items sold, and to which of the store's customers. You will create and examine the structure of the database tables, then create and customize the application to manage that information. The application you develop will allow Nicole and her employees to create, update, and view purchase orders for her sporting goods store.
Each main section of the tutorial corresponds to a version number for Order, with each successive lesson building on what was learned in the last one. When you finish working through the final lesson, you will have programmed a completely customized purchase order system for Nichole's Sporting Goods.
You may access the files for the tutorial in the following location:
These files show you what you should have built by the end of each lesson. The Order1 file corresponds to Lesson 1, Order2 corresponds to Lesson 2, and so on. Therefore, to see the set of completed files for Lesson 1, access:
ORACLE_HOME\APPWIZARD\VC++\TUTORIAL\ORDER1
To create this purchase order system, you must set up the following database tables to interact with each other:
The following illustrates the data models for the tables you will construct.
Sales_Order table:Name Null? Type ------------------------------- -------- ---- ORDER_ID NOT NULL NUMBER(4) ORDER_DATE DATE CUSTOMER_ID NUMBER(6) SHIP_DATE DATE TOTAL NUMBER(8,2)Name Null? Type ------------------------------- -------- ---- ORDER_ID NOT NULL NUMBER(4) ITEM_ID NOT NULL NUMBER(4) PRODUCT_ID NUMBER(6) ACTUAL_PRICE NUMBER(8,2) QUANTITY NUMBER(8) TOTAL NUMBER(8,2)Customer table:Name Null? Type ------------------------------- -------- ---- CUSTOMER_ID NOT NULL NUMBER(6) NAME VARCHAR2(45) ADDRESS VARCHAR2(40) CITY VARCHAR2(30) STATE VARCHAR2(2) ZIP_CODE VARCHAR2(9) AREA_CODE NUMBER(3) PHONE_NUMBER NUMBER(7) SALESPERSON_ID NUMBER(4) CREDIT_LIMIT NUMBER(9,2) COMMENTS LONGProduct table:Name Null? Type ------------------------------- -------- ---- PRODUCT_ID NOT NULL NUMBER(6) DESCRIPTION VARCHAR2(30)
In Lesson 1, you form the basis of the purchase order application for Nicole's Sporting Goods. In this lesson, you learn how to quickly complete a starter application as explained in Chapter 2, "Creating a Starter Application." The application you create using Oracle AppWizard for Microsoft Visual C++ is then ready for customization.
When you are finished with this section of the tutorial, you will understand how to use Oracle AppWizard for Microsoft Visual C++ to create a starter application.
Lesson 1 consists of the following parts:
The Welcome window welcomes you to the Oracle AppWizard.
Click Next to continue.
From ORACLE DB/Users/DEMO:
From ORACLE DB/Users/DEMO:
The next window displays the columns from the master and the detail tables you have selected and the default join clause that Oracle AppWizard has created. Oracle AppWizard creates the default join it bases on the primary and foreign keys of the master and detail tables.
In our example, Oracle AppWizard has created a default join, based on the primary and foreign keys:
Sales.Order.Order_ID joined with Item.Order_ID
In the next window:
Oracle AppWizard for Microsoft Visual C++ creates the source, header, and resource files for your Order application and takes you automatically to the Microsoft Developer Studio with Workspace "Order" open.
Now that you have created the Order application using Oracle AppWizard for Microsoft Visual C++, you can customize it to better suit your needs. In order to be able to customize this application, you need know about the classes and files it has created for this purpose, illustrated in Table 4-1, "Files and classes created for the "Order" application by Oracle AppWizard".
Oracle AppWizard creates a ReadMe.txt file for the generated Order project. This ReadMe.txt file describes the source, header, and resource files that Oracle AppWizard has created.
To view the contents of the ReadMe.txt file:
The following illustration shows what the ReadMe.txt file
for Order should look like.
In this section you use Microsoft Developer Studio to build and run the executable files Oracle AppWizard for Microsoft Visual C++ has created.
To build the application:
To run the application:
Notice and try using the following features:
In this first customization task, you learn how to add specific detailed information about customers which should appear on any purchase order for the Order application. To accomplish this task, complete the following parts of this lesson:
To see the set of completed files for Lesson 2, access:
ORACLE_HOME\APPWIZARD\VC++\TUTORIAL\ORDER2
Note: Some parts of this lesson require you to add or modify code in the application. The code that must be added or modified is in bold print. |
To display customer information on your purchase order form for an active order, you must first create an ODynaset class to represent the CUSTOMER table. To do this, create a new generic class called COrderCustomerDynaset, which is derived from the ODynaset class.
The ODynaset class is a class in Oracle Objects for OLE C++ class library. It creates, manages, and accesses records of data from the database.
To create a dynaset for the CUSTOMER table:
Oracle AppWizard generates both an OrderDynasetCustomer.cpp and an OrderDynasetCustomer.h file for the COrderDynasetCustomer class with the following contents:ORACLE_HOME\0040\cpp\includea ORACLE_HOME\0040\cpp\include
//OrderDynasetCustomer.h: interface for the COrderDynasetCustomer Class// ////////////////////////////////////////////////////////// class COrderDynasetCustomer : public ODynaset { public: COrderDynasetCustomer(); };
//OrderDynasetCustomer.cpp: implmentation of the COrderDynasetCustomer class. // ////////////////////////////////////////////////////////// #include "stdafcx.h" #include "Order.h" #include "OrderDynasetCustomer.h" COrderDynasetCustomer:COrderDynasetCustomer() { } COrderDynasetCustomer:~COrderDynasetCustomer() { }
COrderDynasetCustomer class is derived from the ODynaset class. This class will contain member variables that store information about a SQL statement to query the database. This class will also store information to represent columns in the USER.DEMO.CUSTOMER table. These are shown in Table 4-2, " COrderDynasetCustomer Data Members".
Table 4-2 COrderDynasetCustomer Data Members
To add member variables for the COrderDynasetCustomer class, enter the following code in the COrderDynasetCustomer.h file:
class COrderDynasetCustomer : public ODynaset
{
...
public:
COrderDynasetCustomer();
virtual ~COrderDynasetCustomer();
public:
// strings needed for creating the queries
CString m_strSQLQuery; // the query to be sent to the database
CString m_strSQLSelect; // the select portion
CString m_strSQLFilter; // the where portion
CString m_strSQLSort; // the order by portion
OField m_CUSTOMER_ID;
OField m_NAME;
OField m_ADDRESS;
OField m_CITY;
OField m_STATE;
OField m_ZIP_CODE;
OField m_AREA_CODE;
OField m_PHONE_NUMBER;
OField m_SALESPERSON_ID;
OField m_CREDIT_LIMIT;
OField m_COMMENTS;
Adding the member functions shown in Table 4-3, "COrderDynaset Customer Member Functions" to the COrderDynaset customer class will allow you to create a query statement, have the database process it, then retrieve and store information.
To declare member functions for the COrderDynasetCustomer class, add the following code to the OrderDynasetCustomer.h file:
class COrderDynasetCustomer : public ODynaset{ ... public: COrderDynasetCustomer(); virtual ~COrderDynasetCustomer(); // Operations public: void OpenQuery(ODatabase theDB); void CreateSQLSelect(); void AddFilter(CString strFilter); void ResetToDefaultFilter(); void RefreshQuery(); ... };
To initialize the value in the member variables, add the following code to the constructor method of COrderDynasetCustomer Class in the OrderDynasetCustomer.cpp file:
// Creates the default selectvoid COrderDynasetCustomer::CreateSQLSelect() { m_strSQLSelect = "select CUSTOMER_ID, NAME, ADDRESS, CITY, STATE, \ ZIP_CODE, AREA_CODE, PHONE_NUMBER, \ SALESPERSON_ID, CREDIT_LIMIT, COMMENTS \ from DEMO.CUSTOMER"; }
To create a query statement, to process the query, and to retrieve information from the database, enter the following code to the COrderDynasetCustomer class::OpenQuery() method in the OrderCustomer.cpp file:
// opens the query void COrderDynasetCustomer::OpenQuery(ODatabase theDB) { oresult dbresult; // create a query statement m_strSQLQuery = m_strSQLSelect; if (m_strSQLFilter) m_strSQLQuery += m_strSQLFilter; if (m_strSQLSort) m_strSQLQuery += m_strSQLSort; // query the database dbresult = Open(theDB, m_strSQLQuery); // retreive/store information from the database m_CUSTOMER_ID = GetField("CUSTOMER_ID"); m_NAME = GetField("NAME"); m_ADDRESS = GetField("ADDRESS"); m_CITY = GetField("CITY"); m_STATE = GetField("STATE"); m_ZIP_CODE = GetField("ZIP_CODE"); m_AREA_CODE = GetField("AREA_CODE"); m_PHONE_NUMBER = GetField("PHONE_NUMBER"); m_SALESPERSON_ID = GetField("SALESPERSON_ID"); m_CREDIT_LIMIT = GetField("CREDIT_LIMIT"); m_COMMENTS = GetField("COMMENTS"); // display the first record from the Customer table dbresult = MoveFirst(); }
To add a conditional clause for the query, enter the following code to the COrderDynasetCustomer class::AddFilter() method in the OrderCustomer.cpp file:
// adds a condition to the where clause void COrderDynasetCustomer::AddFilter(CString strFilter) { m_strSQLFilter += m_strSQLFilter.IsEmpty() ? " WHERE " : " AND "; m_strSQLFilter += strFilter; }
To reset the conditional clause for the query, enter the following code to the COrderDynasetCustomer class::ResetToDefaultFilter() method in the OrderCustomer.cpp file:
To refresh the query to be executed, add the following code to COrderDynasetCustomer class::RefreshQuery() method in the OrderCustomer.cpp file:// resets the filter to the default value void COrderDynasetCustomer::ResetToDefaultFilter() { m_strSQLFilter.Empty(); }
void COrderDynasetCustomer::RefreshQuery() { oresult dbresult; // create a query statement m_strSQLQuery = m_strSQLSelect; if (m_strSQLFilter) m_strSQLQuery += m_strSQLFilter; if (m_strSQLSort) m_strSQLQuery += m_strSQLSort; // set the query statement to be used dbresult = SetSQL(m_strSQLQuery); dbresult = Refresh(); }
Add a member variable called m_pDynasetCustomer in COrderView class. This member variable is a pointer to the type COrderCustomerDynaset class.
class COrderView : public CFormView { ... COrderDynasetMaster *m_pDynasetMaster; COrderDynasetDetail *m_pDynasetDetail; COrderDynasetCustomer *m_pDynasetCustomer; ... }
COrderView::COrderView() : CFormView(COrderView::IDD) { ... m_pDynasetMaster = NULL; m_pDynasetDetail = NULL; m_pDynasetCustomer = NULL; ... }
Add a member variable called m_OrderDynasetCustomer in the COrderDoc class. This is an object of COrderCustomerDynaset class.
class COrderDoc : public CDocument {... COrderDynasetMaster m_OrderDynasetMaster; COrderDynasetDetail m_OrderDynasetDetail; COrderDynasetCustomer m_OrderDynasetCustomer; ... }
This section demonstrates how to display customer information for each purchase order.
Add 10 edit controls to display customer information in the IDD_ORDER_FORM dialog box with the Control IDs shown in Table 4-4, "Mapping edit control IDs to OField member variables in the COrderDynasetCustomer class".
After you add these edit controls, the IDD_ORDER_FORM dialog
box will appear similar to this one shown below. This illustration serves
only as a sample. Yours may look slightly different.
To bind these edit controls with the OField members in the COrderDynasetCustomer class, call the DDX_FieldText() method for each customer edit control in the COrderView class::DoDataExchange() method. The OField members represent the columns in the Customer table. Bind this with an OField member variable of the COrderDynasetCustomer class, as shown in Table 4-4, "Mapping edit control IDs to OField member variables in the COrderDynasetCustomer class".
For example, when you use DDX_FieldText() to bind
the edit control
IDC_CUST_NAME with the m_NAME member variable of COrderDynasetCustomer
class, it appears as follows:
DDX_FieldText(pDX, IDC_CUST_NAME, m_pDynasetCustomer->m_Name, m_pDynasetCustomer); where m_pDynasetCustomer is a member variable in COrderView class
void COrderView::DoDataExchange(CDataExchange* pDX) { ... CFormView::DoDataExchange(pDX); ... // for customer dynaset DDX_FieldText(pDX, IDC_CUST_NAME, m_pDynasetCustomer->m_NAME, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_ADDRESS, m_pDynasetCustomer->m_ADDRESS, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_CITY, m_pDynasetCustomer->m_CITY, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_STATE, m_pDynasetCustomer->m_STATE, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_ZIP_CODE, m_pDynasetCustomer->m_ZIP_CODE, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_AREA_CODE, m_pDynasetCustomer->m_AREA_CODE, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_PHONE_NUMBER, m_pDynasetCustomer->m_PHONE_NUMBER, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_CREDIT_LIMIT, m_pDynasetCustomer->m_CREDIT_LIMIT, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_SALESPERSON_ID, m_pDynasetCustomer->m_SALESPERSON_ID, m_pDynasetCustomer); DDX_FieldText(pDX, IDC_CUST_COMMENTS, m_pDynasetCustomer->m_COMMENTS, m_pDynasetCustomer); ... }
void COrderView::OnInitialUpdate() { CString strJoin; ... m_pDynasetMaster = &GetDocument()->m_OrderDynasetMaster; m_pDynasetDetail = &GetDocument()->m_OrderDynasetDetail; m_pDynasetCustomer = &GetDocument()->m_OrderDynasetCustomer; m_pDynasetMaster->OpenQuery(GetDocument()->m_database); }
// create a join based on CUSTOMER_ID // between the Customer table and // the Sales.Order table. m_pDynasetCustomer->ResetToDefaultFilter(); strJoin = "CUSTOMER_ID = " + (CString)m_pDynasetMaster->m_Column1; m_pDynasetCustomer->AddFilter(strJoin); // create, process the query m_pDynasetCustomer->OpenQuery(GetDocument()->m_database); ... CFormView::OnInitialUpdate(); m_dataControl.SetRecordset((LPDISPATCH)(m_pDynasetDetail->Internal())); ... }
void COrderView::PerformMove(int nCommand) { ... // Update Customer information m_pDynasetCustomer->ResetToDefaultFilter(); strJoin = "CUSTOMER_ID = " + (CString)m_pDynasetMaster->m_Column1; m_pDynasetCustomer->AddFilter(strJoin); m_pDynasetCustomer->RefreshQuery(); UpdateData(FALSE); }
Nicole's employees need to be able to add products to a purchase order. Therefore, Lesson 3 demonstrates how to customize your application to do the following:
Lesson 3 contains the following parts:
- Display available products from the PRODUCT table
- Add product items to a purchase order
- Update the changes in the ITEM table and in the detail table control when product items have been added to a purchase order
- Update the changes in the SALES_ORDER table and in the master table controls when product items have been added to a purchase order.
To see the set of completed files for Lesson 3, access:
ORACLE_HOME\APPWIZARD\VC++\TUTORIAL\ORDER3
Note: Some parts of this lesson require you to add or modify code in the application. The code that must be added or modified is in bold print.: |
Nicole's Sporting Goods carries a wide variety of products. Many of them, however, have similar names and descriptions. To insure data integrity, it's best to display a list of the product items in the purchase order application window. This will allow Nicole's employees to select the items that customers have purchased from the list.
In this part, you will add a list box that displays the available products in the IDD_ORDER_FORM dialog box.
void COrderView::OnInitialUpdate() { ... CFormView::OnInitialUpdate() ... // Put list of sales items into the listbox ODynaset oProdList; oProdList.Open(GetDocument()->m_database, "SELECT PRODUCT_ID, FROM DEMO.PRODUCT ORDER BY PRODUCT_ID"); int index = 0; while (!oProdList.IsEOF()) { m_prodList.InsertString(index, (CString)oProdList.GetField(0) + " - " + oProdList.GetField(1)); m_prodList.SetItemData(index, (long)oProdList.GetField(0)); oProdList.MoveNext(); index++; } }
To have the TOTAL column in the SALES_ORDER table updated when a purchased item is added to a purchase order, the SALES_ORDER table should be updated. To allow the updating of the SALES_ORDER table, remove the third parameter, ODYNASET_READONLY, from the Open() function call in the COrderDynasetMaster::OpenQuery() method.
In the IDD_ORDER_FORM dialog, create a button that handles the event of adding a purchase item. The button should have the following properties:Change:dbresult = Open(theDB, m_strSQLQuery, ODYNASET_READONLY);To:dbresult = Open(theDB, m_strSQLQuery);
Button Control ID | Button Caption | Event | Event Handler Function |
---|---|---|---|
IDC_ADDITEMS |
Add to Order |
BN_Clicked |
OnAdditems |
To process the updates in the SALES _ORDER table, the ITEM table, the master table controls, and the detail table control when purchase items are added to a purchase order, enter the following code to COrderView::OnAddItems() method in the OrderView.cpp file:
The function TotalOrder() is being called in COrderView::OnAdditems() method. It is a member function for COrderView class. It re-calculates the total amount for a purchase order and updates the TOTAL column in the SALES_ORDER table.void COrderView::OnAdditems() { int *pAddIndices; int nSelCount; oresult r; nSelCount = m_prodList.GetSelCount(); pAddIndices = new int[nSelCount]; m_prodList.GetSelItems(nSelCount, pAddIndices); for (int i = 0; i < nSelCount; i++) { char szProdID[8]; char szItemID[8]; itoa(m_prodList.GetItemData(pAddIndices[i]), szProdID, 10); itoa(m_pDynasetDetail->GetRecordCount() + 1, szItemID, 10); CString strInsert = "INSERT INTO DEMO.ITEM (ORDER_ID, PRODUCT_ID, ITEM_ID, QUANTITY, ACTUAL_PRICE, TOTAL) SELECT " + CString)m_pDynasetMaster->m_Column3 + ", " + szProdID +", " + szItemID + ", 1, LIST_PRICE, LIST_PRICE FROM DEMO.PRICE WHERE PRODUCT_ID = " + szProdID + " AND ((SYSDATE BETWEEN START_DATE AND END_DATE) OR " + "(SYSDATE > START_DATE AND END_DATE IS NULL))"; r = GetDocument()->m_database.ExecuteSQL(strInsert); if (r == OFAILURE) ProcessOO4OError(&GetDocument()->m_database); m_pDynasetDetail->Refresh(); } TotalOrder(); m_prodList.SelItemRange(FALSE, 0, m_prodList.GetCount()); delete pAddIndices; }
To declare TotalOrder() in COrderView class, enter the following code in COrderView class in the OrderView.h file:
Add the following code to COrderView::TotalOrder() method in the OrderView.cpp file:public: void TotalOrder();
Build and run the application. The application will look similar to the one below.void COrderView::TotalOrder() { ODynaset oTotal; OTotal.Open(GetDocument()->m_database, "SELECT SUM(TOTAL) FROM DEMO.ITEM WHERE ORDER_ID = " + (CString)m_pDynasetMaster->m_Column3); m_pDynasetMaster->StartEdit(); m_pDynasetMaster-> m_Column5.SetValue((double)oTotal.GetField(0)); m_pDynasetMaster->Update(); UpdateData(FALSE);}
This section allows you to make changes in the detail table control for the Order application. When the value in the QUANTITY column or the ACTUAL_PRICE column in the detail table changes, the application should update the appropriate changes to the ITEM table, the SALES_ORDER table, the content in the master detail controls and the detail table control accordingly.
This section consists of the following parts:
To see the set of completed files for Lesson 4, access:
ORACLE_HOME\APPWIZARD\VC++\TUTORIAL\ORDER4
Note: Some parts of this lesson require you to add or modify code in the application. The code that must be added or modified is in bold print. |
Table 4-6 Mapping event type to event handler function for the detail table control
Event Type | Event Handler |
---|---|
AfterColUpdate |
OnAfterColUpdateDatagrid |
AfterUpdate |
OnAfterUpdateDatagrid |
AfterDelete |
OnAfterDeleteDatagrid |
Create a member variable,
m_datagrid, for the detail table control in COrderView class. The variable,
m_datagrid, is a control handler of type CMsDgridCtrl. It represents the
detail table and allows for update or retrieve data.
To update the TOTAL column for the detail table control when the ACTUAL_PRICE column or the QUANTITY column in the detail table control changes, add the following code to COrderView::OnAfterColUpdateDatagrid() method in the OrderView.cpp file:
// recalcuates the TOTAL column in the detail table when the value // in the ACTUAL_PRICE or QUANTITY column changes void COrderView::OnAfterColUpdateDatagrid(short ColIndex) { if (ColIndex == 4 || ColIndex == 0) { CString strText = m_datagrid.GetText(); CString strTotal; char *stopString; char szTotal[15]; long quantity; double price; // QUANTITY column is updated if (ColIndex == 4) { quantity = strtol(strText, &stopString, 10); m_datagrid.SetCol(0); strText = m_datagrid.GetText(); price = strtod(strText, &stopString); m_datagrid.SetCol(4); } else // PRICE column is updated { price = strtod(strText, &stopString); m_datagrid.SetCol(4); strText = m_datagrid.GetText(); quantity = strtol(strText, &stopString, 10); m_datagrid.SetCol(0); } sprintf(szTotal, "%f", quantity * price); strTotal = szTotal; m_datagrid.SetCol(5); m_datagrid.SetText((LPCTSTR)strTotal); } }
To update the TOTAL column for the master table controls when the ACTUAL_PRICE column or the QUANTITY column in the detail table change , add the following codes to the COrderView::OnAfterUpdateDatagrid() method in the OrderView.cpp file:
void COrderView::OnAfterUpdateDatagrid() { // Calculates the total amount for a purchase order TotalOrder(); }
To update the TOTAL column for the master table controls when the a record has been deleted from the detail table control, add the following codes to the COrderView::OnAfterDeleteDatagrid() method OrderView.cpp file:
void COrderView::OnAfterDeleteDatagrid(){ // Calculates the total amount for a purchase order TotalOrder(); }
This section consists of the following parts:
- Part 1: Creating a Customer List Dialog Box
- Part 2: Creating a New Class to Handle Events for the Customer Dialog Box
- Part 3: Creating "New Order", Commit Order", and "Cancel Order" Buttons
- Part 4: Enabling Users to Add a New Purchase Order
- Part 5: Enabling Users to Commit a New Purchase Order
- Part 6: Enabling Users to Cancel a New Purchase Order
To see the set of completed files for Lesson 5, access:
ORACLE_HOME\APPWIZARD\VC++\TUTORIAL\ORDER5
Note: Some parts of this lesson require you to add or modify code in the application. The code that must be added or modified is in bold print. |
Create a dialog box with
control ID = IDD_SELCUSTOMER. Customize the dialog box so that it contains
a OK Button, Cancel Button and a List Box with control ID = IDC_CUSTLIST.
The customer list dialog box should look similar
to the one shown below. The list box will display a list of customers from
the CUSTOMER table.
Create a new MFC class, CSelectCustomer, that is derived from CDialog. This class handles events occurring in the customer dialog box.
Allow the CSelectCustomer class to handle the events shown in Table 4-7, " CSelectCustomer Class Events".
Table 4-7 CSelectCustomer Class Events
Object ID | Event | Event Handler Function |
---|---|---|
CSelectCustomer |
WM_INITDIALOG |
OnInitDialog |
IDOK |
BN_CLICKED |
OnOK |
Create a member variable, m_CustomerList, for the customer list box in CSelectCustomer class. The variable, m_CustomerList, is a control handler of type CListBox. It enables users to select a customer from the customer list box for a purchase order.
To implement the events for
the Customer dialog box, add the following member declarations to CSelectCustomer
class in SelectCustomer.h file:
public: long GetSelection(); // obtain the selected customer from the // customer list box. int DoModal(ODatabase *db); // involve the customer dialog box long m_nSelection; // nth location of the selected customers // in the customer list. ODatabase * m_Database; // the database
Include the header file ORACL.H
in the SelectCustomer.h file.
To display a list of customer in the customer list box, add the following code to CSelectCustomer::OnInitDialog() method in the CSelectCustomer.cpp file:
BOOL CSelectCustomer::OnInitDialog() { ... CDialog::OnInitDialog(); ODynaset oCustList; int index = 0; oCustList.Open(*m_pDatabase, "SELECT CUSTOMER_ID, NAME FROM DEMO.CUSTOMER"); while (!oCustList.IsEOF()) { m_CustomerList.InsertString(index, (CString)oCustList.GetField(0) + " - " + oCustList.GetField(1)); m_CustomerList.SetItemData(index, (long)oCustList.GetField(0)); oCustList.MoveNext(); index++; } ... }
int CSelectCustomer::DoModal(ODatabase *db) { m_pDatabase = db; return CDialog::DoModal(); }
long CSelectCustomer::GetSelection() { return(m_nSelection); }
void CSelectCustomer::OnOK() { // TODO: Add extra validation here int nItem = -1; nItem = m_CustomerList.GetCurSel(); if (nItem >=0) { // location of selected customer in the customer list box m_nSelection = m_CustomerList.GetItemData(nItem); CDialog::OnOK(); } else AfxMessageBox(_T("Please select a customer.\n"), MB_OK, 0); }
These event handler functions will be added to the COrderView
class when the buttons specify the event handle.
To add a new purchase order to the purchase order system, add the following code to COrderView::OnNeworder() method in OrderView.cpp file:
#include <SelectCustomer.h> // define CSelectCustomer class // to get customer information for // a new purchase // order void COrderView::OnNeworder() { CWnd *tempWindow; char szCUSTOMER_ID[8]; OField oORDER_ID; CSelectCustomer selectCustomer; result dbresult; if (selectCustomer.DoModal(&GetDocument()->m_database) == IDCANCEL) return; if (GetDocument()->m_database.GetSession(). BeginTransaction() == OSUCCESS && m_pDynasetMaster->AddNewRecord() == OSUCCESS) { UpdateData(FALSE); tempWindow = GetDlgItem(IDC_Column1); itoa(selectCustomer.GetSelection(), szCUSTOMER_ID, 10); tempWindow->SetWindowText(szCUSTOMER_ID); if (m_pDynasetMaster->GetEditMode() == ODYNASET_EDIT_NEWRECORD) { ODynaset oSequenceDynaset; dbresult = oSequenceDynaset.Open( GetDocument()->m_database, "SELECT MAX(ORDER_ID) + 1 FROM DEMO.SALES_ORDER"); oORDER_ID = oSequenceDynaset.GetField(0); dbresult = oSequenceDynaset.Close(); tempWindow = GetDlgItem(IDC_Column3); tempWindow->SetWindowText ((CString)oORDER_ID); } dbresult = UpdateData(); if (m_pDynasetMaster->Update() == OFAILURE) { ProcessOO4OError(m_pDynasetMaster); return; } m_pDynasetMaster->ResetToDefaultFilter(); m_pDynasetMaster->AddFilter("ORDER_ID = " + (CString)oORDER_ID); m_pDynasetMaster->RefreshQuery(); m_pDynasetCustomer->ResetToDefaultFilter(); m_pDynasetCustomer->AddFilter("CUSTOMER_ID = " + (CString)m_pDynasetMaster->m_Column1); m_pDynasetCustomer->RefreshQuery(); m_pDynasetDetail->ResetToDefaultFilter(); m_pDynasetDetail->AddFilter("ORDER_ID = " + (CString)m_pDynasetMaster->m_Column3); m_pDynasetDetail->RefreshQuery(); UpdateData(FALSE); } CButton *tempButton = (CButton *)GetDlgItem(IDC_NEWORDER); tempButton->EnableWindow(FALSE); tempButton = (CButton *)GetDlgItem(IDC_COMMITORDER); tempButton->EnableWindow(TRUE); tempButton = (CButton *)GetDlgItem(IDC_CANCELORDER); tempButton->EnableWindow(TRUE); }
To commit a new purchase order, add the following code to COrderView::OnCommitorder() method in OrderView.cpp file:
void COrderView::OnCommitorder() { // TODO: Add your control notification handler code here CString strORDER_DATE; CString strSHIP_DATE; CWnd *tempWindow; m_pDynasetMaster->StartEdit(); tempWindow = GetDlgItem(IDC_Column2); tempWindow->GetWindowText(strORDER_DATE); tempWindow = GetDlgItem(IDC_Column4); tempWindow->GetWindowText(strSHIP_DATE); m_pDynasetMaster->m_Column2.SetValue(LPCTSTR(strORDER_DATE)); m_pDynasetMaster->m_Column4.SetValue(LPCTSTR(strSHIP_DATE)); m_pDynasetMaster->Update(); OSession oSess = GetDocument()->m_database.GetSession(); if (oSess.Commit() == OFAILURE) rocessOO4OError(&oSess); m_pDynasetMaster->ResetToDefaultFilter(); m_pDynasetMaster->RefreshQuery(); UpdateData(FALSE); OnMoveFirst(); CButton *tempButton = (CButton *)GetDlgItem(IDC_NEWORDER); tempButton->EnableWindow(TRUE); tempButton = (CButton *)GetDlgItem(IDC_COMMITORDER); tempButton->EnableWindow(FALSE); tempButton = (CButton *)GetDlgItem(IDC_CANCELORDER); tempButton->EnableWindow(FALSE); }
To enable cancelling a new purchase order, add the following code to COrderView::OnCancelorder() method in OrderView.cpp file:
Build and run the application. It should look similar to the screen shown below.void COrderView::OnCancelorder() { // TODO: Add your control notification handler code here GetDocument()->m_database.GetSession().Rollback(); m_pDynasetMaster->ResetToDefaultFilter(); m_pDynasetMaster->RefreshQuery(); UpdateData(FALSE); OnMoveFirst(); CButton *tempButton = (CButton *)GetDlgItem(IDC_NEWORDER); tempButton->EnableWindow(TRUE); tempButton = (CButton *)GetDlgItem(IDC_COMMITORDER); tempButton->EnableWindow(FALSE); tempButton = (CButton *)GetDlgItem(IDC_CANCELORDER); tempButton->EnableWindow(FALSE); }
Your application is now complete.
|
![]() Copyright © 1999 Oracle Corporation. All Rights Reserved. |
|