Oracle
AppWizard for Microsoft Visual C++
Release 8.1.5 for Windows NT A67160-01 |
|
This chapter describes the building blocks Oracle AppWizard
for Microsoft Visual C++ uses to create an application. Using this information,
you can easily customize your application.
Topics include the following:
Oracle AppWizard for Microsoft Visual C++ uses Microsoft
Foundation Classes (MFC) to provide the application framework. Oracle Objects
for OLE C++ Class Library is used to create a starter application. Oracle
AppWizard generates a complete set of source and resource files your Visual
C++ project that you can customize as required for your business needs.
The following illustration shows how the framework created
by Oracle AppWizard uses the Oracle Objects for OLE C++ to interact with
the Oracle database.
After you complete all the Oracle AppWizard for Microsoft Visual C++ steps and have chosen the options appropriate for the application you want to create, Oracle AppWizard generates a complete set files:
Oracle AppWizard creates the following source and header
files. Your files would have the actual name of your project, instead of
PRJNAME.
Derives from and implements the application class CPRJNAMEApp.
This class provides member functions for initializing and running the application.
Used by the ClassWizard to store information about the classes
in your project.
Derives from and implements the dialog class CConnDialog.
This class enables the application to request connection information from
the user.
Derives from and implements the document class CPRJNAMEDoc.
This class also contains the application data, variables, and objects associated
with the Oracle database. Data access occurs through Oracle Objects for
OLE.
PRJNAMEView.h, PRJNAMEView.cpp
Derives from and implements the View class CPRJNAMEView.
This class displays document data graphically to the user and accepts and
interprets user input as changes to the document.
PRJNAMEDynaset.h, PRJNAMEDynaset.cpp (for Single-Record
and Multiple-Records Display Form)
Derives from and implements the Dynaset class CPRJNAMEDynaset.
This class creates, manages, and accesses records in the database.
PRJNAMEDynasetMaster.h, PRJNAMEDynasetMaster.cpp
(for Master-Detail Display Form)
Derives from and implements the Dynaset class CPRJNAMEDynasetMaster.
This class creates, manages, and accesses records in the database.
PRJNAMEDynasetDetail.h, PRJNAMEDynasetDetail.cpp
(for Master-Detail Display Form)
Derives from and implements the Dynaset class CPRJNAMEDDynasetDetail.
This class creates, manages, and accesses records in the database.
ChildFrm.h, ChildFrm.cpp (for Multiple-Document interface
application)
Derives from and implements the Child Window class CChildFrame.
This class is used for MDI document frames.
oradc.h, oradc.cpp (for Multiple-Records and Master-Detail
Display form)
Derives from and implements the Window class CORADC. This
class is the wrapper class for Oracle Data Control, an ActiveX control
and is used to access data for an application using multiple-record display
mode or master-detail display mode.
PRJNAMEUtil.h, PRJNAMEUtil.cpp
Declare and implement stand-alone functions used by other
classes. ProcessOO4OError() and DDX_FieldText() functions are defined in
these files.
Derives from and implements the Frame class CMainFrame. This
class provides the functionality of an overlapped single-document interface
(SDI) or a pop-up window, along with members for managing the window.
Oracle AppWizard creates the following standard files.
These files are used to build a precompiled header file PRJNAME.PCH
and a precompiled types file StdAfx.OBJ.
Oracle AppWizard creates the following standard header file
and a main resource file.
These files contain the default menu definition, accelerator,
and string tables for the generated application.
This file is useful for including resources used by several
different projects. Instead of having to create the same resources several
times for different projects, you can put them in an RC2 file and include
the RC2 file into the main RC file.
This is the icon file for the application. This icon appears
when the application is minimized and is also used in the About box.
This is the icon file for the child window in the Multiple
Document Interface application.
This bitmap file is used to represent your program or control
in a toolbar or palette.
Oracle AppWizard also creates the following file.
This file contains information about the files that Oracle
AppWizard creates for your application.
This section is divided into the following subsections, which explain the function of the code generated by Oracle AppWizard for Microsoft Visual C++:
Note: The generated code described in all but the last list item above is based on an application using single-record display mode exclusively. |
Oracle AppWizard generates Oracle Object for OLE C++ code
to provide connectivity and data access to the Oracle database. The table
below illustrates the classes that Oracle AppWizard uses to communicate
with the Oracle database, using the Oracle Objects for OLE C++ Class Library.
The oracl.h header file in ORACLE_HOME\OO4O\CPP\INCLUDE contains
the declarations for Oracle Objects for OLE classes.
This subsection describes the methods that control the following activities either during or after start-up as you work through the sequence of windows designed to build the starter application.
When the application starts, OStartup() call in CPRJNAMEApp::InitInstance()
initializes the Oracle Object for OLE C++ Class Library as described below:
Note: Bolding represents Oracle code. |
BOOL CTestApp::InitInstance() {
... // initializing Oracle Object for OLE C++ Class Library OStartup(); ...}
The application framework creates a document object (CPRJNAMEDoc class) that stores the application data. During document initialization, it calls DbConnect() to initialize the database (m_database) associated with the document and connects to it, using the following declaration.
class CPRJNAMEDoc : public CDocument { ...
// Attributes public:
ODatabase m_database; CPRJNAMEDynaset m_PRJNAMEDynaset;
// Implementation public:
virtual ~CTestDoc(); bool DbConnect();...};
Constructor method of CPRJNAMEDoc class:
CPRJNAMEDoc:: CPRJNAMEDoc() {
while (!m_database.IsOpen())
{ if (DbConnect() == false)
return;
}
}
To initialize and connect to the database, the application:
The method CPRJNAMEDoc::DbConnect() implements the database connection as illustrated below.
bool CPRJNAMEDoc::DbConnect() {
CConnDialog connDlg; oresult dbresult; int dlgResult;// a dialog box to get connection information from users
dlgResult = connDlg.DoModal(); if (dlgResult == IDOK){ // Connect to the database
dbresult = m_database.Open(connDlg.GetDbAlias(),
connDlg.GetUsername(), connDlg.GetPassword());
if (dbresult == OFAILURE) {// processing error message
ProcessOO4OError(&m_database); } return(true);}else
return(false);}
If successfully connected, the framework creates a view (CPRJNAMEView class) for the application, using the following declaration.
class CPRJNAMEView : public CFormView {
... public:
CTestDynaset *m_pDynaset; bool m_bEditingRecord; //if the record must be edited
// Operations protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual void OnInitialUpdate(); // called first time after construct
...// Implementationpublic:
virtual ~CPRJNAMEView();protected:...void PerformMove(int nCommand);// Generated message map functionsprotected:
... afx_msg void OnMoveNext(); afx_msg void OnMovePrev(); afx_msg void OnMoveFirst(); afx_msg void OnMoveLast(); afx_msg void OnUpdateMoveNext(CCmdUI* pCmdUI); afx_msg void OnUpdateMovePrev(CCmdUI* pCmdUI); afx_msg void OnUpdateMoveFirst(CCmdUI* pCmdUI); afx_msg void OnUpdateMoveLast(CCmdUI* pCmdUI); afx_msg void OnAddNewRecord(); afx_msg void OnUpdateAddNewRecord(CCmdUI* pCmdUI); afx_msg void OnDeleteRecord(); afx_msg void OnUpdateDeleteRecord(CCmdUI* pCmdUI); afx_msg void OnUpdateRecord(); afx_msg void OnUpdateUpdateRecord(CCmdUI* pCmdUI); afx_msg void OnCancelRecord(); afx_msg void OnUpdateCancelRecord(CCmdUI* pCmdUI); afx_msg void OnChangeEdit(); ...}
The constructor method for the CPRJNAMEView class initializes its member variables, as illustrated below.
CPRJNAMEView::CPRJNAMEView()
: CFormView(CPRJNAMEView::IDD){
... m_pDynaset = NULL; m_bEditingRecord = false; ...}
Before the view appears, the application framework calls the CPRJNAMEView::OnInitialUpdate() method to perform initialization, requiring information the following document information:
This implements the CPRJNAMEView::OnInitialUpdate() method, illustrated below.
void CPRJNAMEView::OnInitialUpdate() {
... m_pDynaset = &GetDocument()->m_PRJNAMEDynaset; m_pDynaset->OpenQuery(GetDocument()->m_database); ...}
The CPRJNAMEDynaset class represents a set of records in a table. It creates, manages, and accesses records in the database, using the declaration shown below. In this declaration, data member variables have comments that indicate which real columns they represent.
class CTestDynaset : public ODynaset { ... 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 // Field/Param Data OField m_Column1; //for COL1 OField m_Column2; //for COL2...// Operationspublic:
void OpenQuery(ODatabase theDB);
void AddFilter(CString strFilter);
void RefreshQuery();
... }
To open a dynaset associated with the document the method CPRJNAMEDynaset::OpenQuery() is called in CPRJNAMEView::OnInitialUpdate(). The CPRJNAMEDynaset::OpenQuery() method takes the following actions:
CPRJNAMEDynaset::OpenQuery() method is implemented as illustrated below:
// opens the query void CPRJNAMEDynaset::OpenQuery(ODatabase theDB) {
oresult dbresult;// m_strSQLQuery, m_strSQLSelect, m_strSQLFilter are CString objects.// These are member variables in CPRJNAMEDynaset class// create a query statement to be executed by the Open() callm_strSQLQuery = m_strSQLSelect;if (m_strSQLFilter)
m_strSQLQuery += m_strSQLFilter;if (m_strSQLSort)
m_strSQLQuery += m_strSQLSort;// executing a SQL statementdbresult = Open(theDB, m_strSQLQuery);// binding edit controls with columns in the tablem_Column1 = GetField("COL1");m_Column2 = GetField("COL2");
...}
A view displays the stored data in the associated document. Data in both the document and the view must be consistent. Therefore, the OField member variables (the columns in a database table) of the CPRJNAMEDynaset class and the edit controls in the view must be validated and exchanged, using the CPRJNAMEView::DoDataExchange() method, which is implemented as shown below.
void CPRJNAMEView::DoDataExchange(CDataExchange* pDX) {
... // performing data exchange DDX_FieldText(pDX, IDC_COL1,
m_pDynaset->m_Column1, m_pDynaset);
DDX_FieldText(pDX, IDC_COL2,
m_pDynaset->m_Column2, m_pDynaset);...}
This section explains the code generated by Oracle AppWizard
for Microsoft Visual C++ to allow navigation through a dynaset record set.
The four controls, shown below, enable your application users
to navigate through records.
These navigational controls work as shown in the following
two tables. Event handlers handle the COMMAND message, and Message handlers
handle UPDATE_COMMAND_UI messages.
The navigational operations all use the CPRJNAMEView::PerformMove()
method to perform the requested navigation. To explain the generated code
for the navigational operations, we must explain the generated code for
the CPRJNAMEView::PerformMove() method.
All navigational operations use the CPRJNAMEView::PerformMove()
method.
After a request for record navigation by the user and before any navigation occurs, the application verifies whether or not the current record must be updated or inserted into the database by calling CPRJNAMEView::PerformMove(). The method performs the following operations:
CPRJNAMEView::PerformMove() method is implemented as shown below:
void CPRJNAMEView::PerformMove(int nCommand) {
// nCommand is the control ID of the navigational button and represents // the requested operation.oresult dbresult;
// Verify whether or not the record can be edited. if (m_pDynaset->GetEditMode() != ODYNASET_EDIT_NEWRECORD)
m_pDynaset->StartEdit();
// exchange data between the the view and the dynaset if (!UpdateData())
return;
// if the record changes, update the record in the dynaset if (m_pDynaset->get_CurrentRowModified()) { dbresult = m_pDynaset->Update(); if (dbresult == OFAILURE)
{
ProcessOO4OError(m_pDynaset); return;
}
} else
dbresult = m_pDynaset->CancelEdit();switch(nCommand) // perform action, depends on the requeset navigation{
case ID_RECORD_MOVENEXT:
m_pDynaset->MoveNext(); break;
case ID_RECORD_MOVEPREV:
m_pDynaset->MovePrev(); break;
case ID_RECORD_MOVEFIRST:
m_pDynaset->MoveFirst(); break;
case ID_RECORD_MOVELAST:
m_pDynaset->MoveLast(); break;}// exchange data between the view and the dynasetUpdateData(FALSE);m_bEditingRecord = false;}
When the current record is not the first record and the user
clicks the "First Record" button, corresponding to control ID = ID_RECORD_MOVEFIRST,
users navigate to the first record.
The CPRJNAMEView::OnUpdateMoveFirst() method enables/disables the "First Record" button and is implemented as shown below.
Void CTestView::OnUpdateMoveFirst(CCmdUI* pCmdUI) {
pCmdUI->Enable((m_pDynaset->IsOpen() == TRUE
&& m_pDynaset->IsFirst() == FALSE) ? true : false);}
When the button with control ID = ID_RECORD_MOVEFIRST is
clicked, CPRJNAMEView::OnMoveFirst() method is called to handle the "Move
to First Record" event.
CPRJNAMEView::OnMoveFirst() method is implemented as illustrated below.
// move to the first record void CPRJNAMEView::OnMoveFirst() {
PerformMove(ID_RECORD_MOVEFIRST);}
When the current record is not the last record and the user
clicks the "Last Record" button, corresponding to control ID = ID_RECORD_MOVELAST,
users navigate to the last record.
The CPRJNAMEView::OnUpdateMoveLast() method enables/disables the "Move to Last Record" button as illustrated below:
void CTestView::OnUpdateMoveLast(CCmdUI* pCmdUI) {
pCmdUI->Enable((m_pDynaset->IsOpen() == TRUE
&& m_pDynaset->IsLast() == FALSE) ? true : false);}
When the button with control ID = ID_RECORD_MOVELAST is clicked,
CPRJNAMEView::OnMoveLast() method is called to handle the "Move to Last
Record" event.
This is the implementation of CPRJNAMEView::OnMoveLast() method:
// move to the last record void CPRJNAMEView::OnMoveLast() {
PerformMove(ID_RECORD_MOVELAST);}
When the current record is not the first record and the user
clicks the "Previous Record" button, corresponding to control ID = ID_RECORD_MOVEPREV,
users navigate to the previous record.
The CPRJNAMEView::OnUpdateMovePrev() method enables/disables the "Previous Record" button as illustrated below
void CTestView::OnUpdateMovePrev(CCmdUI* pCmdUI)
{
CTestView::OnUpdateMoveFirst(pCmdUI);}
Clicking the "Previous Record" button, calls the CPRJNAMEView::OnMovePrev() method to handle the "Move to Previous Record" event. It is implemented as illustrated below.
// move to the previous record void CPRJNAMEView::OnMovePrev() {
PerformMove(ID_RECORD_MOVEPREV);}
When the current record is not the last record and the user
clicks the "Next Record" button, corresponding to control ID = ID_RECORD_MOVENEXT,
users navigate to the next record.
The CPRJNAMEView::OnUpdateMoveNext() method enables/disables the "Next Record" button as shown below.
void CTestView::OnUpdateMoveNext(CCmdUI* pCmdUI) {
CTestView::OnUpdateMoveLast(pCmdUI);}
Clicking the "Next Record" button, calls the CPRJNAMEView::OnMoveNext() method to handle the "Move to Next Record" event. It is implemented as illustrated below.
// move to the next record void CPRJNAMEView::OnMoveNext() {
PerformMove(ID_RECORD_MOVENEXT);}
This section explains the code that Oracle AppWizard for
Microsoft Visual C++ generates to manipulation data in a table.
The four controls below enable application users to add,
delete, and update records, or to cancel record updates before being sent
to the database.
The controls illustrated above correspond to the ODynaset
class methods shown in the table below. Event handlers handle the COMMAND
message, and Message handlers handle UPDATE_COMMAND_UI messages.
When the current record is not being updated and the user
clicks the "Add New Record" button, corresponding to control ID = ID_RECORD_ADDNEW,
users add a new record to the database.
The CPRJNAMEView::OnUpdateAddNewRecord() method enables/disables the "Add New Record" button as illustrated below.
void CTestView::OnUpdateAddNewRecord(CCmdUI* pCmdUI) {
CmdUI->Enable(m_pDynaset->IsOpen() == TRUE && !m_bEditingRecord);}
Clicking the "Add New Record" button, calls the CPRJNAMEView::OnAddNewRecord() method to handle the "Add Record" event. It is implemented as illustrated below.
// Allows the user to add a new record to the table void CPRJNAMEView::OnAddNewRecord() {
if (m_pDynaset->AddNewRecord() == OSUCCESS) {
UpdateData(FALSE); m_bEditingRecord = true;
} else {
ProcessOO4OError(m_pDynaset);
}}
When the current record is not being updated and the user
clicks the "Update Record" button, corresponding to control ID = ID_RECORD_UPDATE,
users update a record in the database.
The CPRJNAMEView::OnUpdateUpdateRecord() method enables/disables the "Update Record" button as illustrated below.
void CTestView::OnUpdateUpdateRecord(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_pDynaset->IsOpen() == TRUE && m_bEditingRecord);}
Clicking the "Update Record" button, calls the CPRJNAMEView::OnUpdateRecord() method to handle the "Update Record" event. It is implemented as illustrated below.
// Updates the changes the user has made to the current record of the table void CCPRJNAMEView::OnUpdateRecord() {
oresult dbresult; if (m_pDynaset->GetEditMode() != ODYNASET_EDIT_NEWRECORD)
m_pDynaset->StartEdit();
if (!UpdateData())
return;
if (m_pDynaset->get_CurrentRowModified()) { dbresult = m_pDynaset->Update(); if (dbresult == OFAILURE) {
ProcessOO4OError(m_pDynaset); return; }}
else dbresult = m_pDynaset->CancelEdit(); UpdateData(FALSE); m_bEditingRecord = false;}
When the current record is not being updated and the user
clicks the "Delete Record" button, corresponding to control ID = ID_RECORD_DELETE,
users delete a record in the database.
The CPRJNAMEView::OnUpdateDeleteRecord() method enables/disables the "Delete Record" button as illustrated below.
void CTestView::OnUpdateDeleteRecord(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_pDynaset->IsOpen() == TRUE && !m_bEditingRecord);}
Clicking the "Delete Record" button, calls the CPRJNAMEView::OnDeleteRecord() method to handle the "Delete Record" event. It is implemented as illustrated below.
// Deletes the current record from the table void CCPRJNAMEView::OnDeleteRecord() {
bool bWasLast = m_pDynaset->IsLast() == TRUE ? true : false; if (m_pDynaset->DeleteRecord() == OSUCCESS) {
if (!bWasLast)
m_pDynaset->MoveNext();
else
m_pDynaset->MovePrev();
UpdateData(FALSE); m_bEditingRecord = false;
} else {
ProcessOO4OError(m_pDynaset);
}}
When the current record is being updated and the user clicks
the "Cancel record changes" button, corresponding to control ID = ID_RECORD_CANCEL,
users cancel changes they have entered, but have not yet committed, to
a record in the database.
The CPRJNAMEView::OnUpdateCancelRecord() method enables/disables the "Cancel Changes" button as illustrated below.
void CTestView::OnUpdateCancelRecord(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_pDynaset->IsOpen() == TRUE && m_bEditingRecord);}
Clicking the "Cancel Changes" button, calls the CPRJNAMEView::OnCancelRecord() method to handle the "Cancel the change" event. It is implemented as illustrated below.
// Cancels the changes to the current record. void CCPRJNAMEView::OnCancelRecord() {
if (m_pDynaset->GetEditMode() != ODYNASET_EDIT_NOEDIT) if (m_pDynaset->CancelEdit() == OFAILURE)
ProcessOO4OError(m_pDynaset);
UpdateData(FALSE); m_bEditingRecord = false;}
This subsection explains the generated code for applications
using multiple-record display forms. The previous discussion in this section
dealt with generated code for single-record display forms.
Note: Bolding represents Oracle code. |
Oracle AppWizard for Microsoft Visual C++ uses Oracle Data Control class CORADC to display and access records in this mode. The CPRJNAMEView class is defined as follows:
class CPRJNAMEView : public CFormView {
... public:
CTestDynaset *m_pDynaset; CORADC m_dataControl // Used by Oracle control to display
and access data
...}
Data exchange takes place, using the Oracle Data Control Object (m_dataControl) in the CPRJNAMEView::DoDataExchange() as follows:
void CPRJNAMEView::DoDataExchange(CDataExchange* pDX) {
// performing data exchange // IDC_ORADC is the control ID for the Oracle Data Control grid DDX_Control(pDX, IDC_ORADC, m_dataControl);}
|
![]() Copyright © 1999 Oracle Corporation. All Rights Reserved. |
|