Converting Existing VC Project to VC.NET


Converting Existing VC++ Project to VC++.NET

VC++.NET supports interoperability with the existing C++ code. Your existing C++ code will run in VC++.NET, but it will not be able to use the .NET runtime features available to managed applications. To exploit these features such as type safety, security, and automatic garbage collection, you need to use managed C++ extensions to code your applications. Managed C++ extensions do not directly support a few features of C++, such as default arguments, unions, and function pointers.

Creating the AddressBook Application in VC++

The AddressBook application allows the school authorities to maintain student records, each of which includes the student name, student ID, address, date of birth, and phone number. The school authorities can view a list of all the records currently present in the address book and sorted by the names or IDs of the students. The application also allows them to add, update, delete, and search student records.

The AddressBook application consists of two projects:

  • StudentData: Provides the COM component that handles all operations to the database, such as adding a record, deleting or updating an existing record, and searching for a particular record.

  • AddressBook: Provides the user interface for the AddressBook application and handles the events that occur when the school authorities interact with the application. This project interacts with the StudentData component to add, retrieve, remove, or modify student information in the database.

Creating the Database Schema

The AddressBook application uses the Student database to store information about students. Listing 6-12 shows the SQL script to generate the database on the SQL Server:

Listing 6-12: The Student Database Schema

start example
 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[student]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[student] GO CREATE TABLE [dbo].[student]  (    [StudentId] [numeric](18, 0) NOT NULL ,    [studentName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,    [studentAddress] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,    [dob] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,    [phone] [numeric](18, 0) NULL,  ) ON [PRIMARY] GO 
end example

The above listing shows how to create the Student database for the AddressBook application. The listing creates the student table in the Student database. This table stores the information about students, such as name, StudentID, address, date of birth, and phone number.

Creating the StudentData Project

The StudentData project creates a reusable COM component that operates on the database storing student information. The component provides features such as addition, deletion, updation, searching, and sorting of student records.

To create the StudentData project:

  1. Select the ATL COM AppWizard in Visual C++ 6.0 to create a new project named StudentData. Select the Server Type as DLL and check the Support MFC check box. The wizard-generated application template window opens.

  2. Select Insert->New ATL Object. The ATL Object wizard opens.

  3. Select Objects from the Category list and Simple Object from the Objects list. Click Next.

  4. Enter DataAccess in the Short Name text box. The remaining fields fill up automatically. Click OK. The DataAccess ATL object is added to the project.

  5. Select the FileView tab in the workspace window. A list of all the files in the project, classified under different heads, appears.

  6. Double-click the StdAfx.h file in the Header Files folder. The contents of the file open in the Edit window of the IDE.

  7. Append the following line of code to the file contents to include a reference to the ActiveX Data Object (ADO) COM component:

     # import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") 

  8. Select the ClassView tab in the workspace window. A list of all classes in the project, along with their member variables and methods, appears.

  9. Right-click the IDataAccess interface and select the Add Method option. The Add Method to Interface window opens.

  10. Type the name of the method in the Method Name text box and the parameters in the Parameters text box. For example, to add the AddRecord() method, type the name as AddRecord and the parameters as shown below:

     [in]long StudentId,[in]BSTR name,[in] BSTR address,[in]BSTR dob, [in] long phone. 

    Note

    Every function added to the component using the Add Method tool returns the HRESULT type. You can use the [in] keyword to indicate the parameters passed from the client application to the server application and the [out] keyword for parameters passed vice versa.

  11. Add the remaining methods to the IDataAccess interface in the same way as in step 10. Table 6-2 lists the names and parameters of all the methods of IDataAccess:

    Table 6-2: Methods of the IDataAccess Interface

    Name of the Method

    Parameters

    AddRecord

    [in]long StudentId,[in]BSTR name,[in] BSTR address,[in]BSTR dob, [in] long phone

    DeleteRecord

    [in]long StudentId

    UpdateRecord

    [in]long StudentId, [in] BSTR name,[in] BSTR address, [in] BSTR dob, [in] long phone

    Sort

    [in]long no, [out,retval] IDispatch **p

    SearchByStudentId

    [in]long StudentId,[out,retval] IDispatch **p

    SearchByName

    [in]BSTR name,[out,retval] IDispatch **p

  12. In the ClassView tabpane of the workspace window, expand the CDataAccess node and then the IDataAccess node.

  13. Double-click the name of each method, to define its implementation, by writing the code in the edit window of the IDE.

The wizard automatically creates several files in the project. You need to define implementation of methods in the DataAccess.cpp file and the DataAccess.h file only.

Defining the DataAccess.h File

The DataAccess.h file is a header file in which you need to declare a reference to the built-in Windows class, ConnectionPointer and define the FinalConstruct() and FinalRelease() methods. The FinalConstruct() method performs final initialization of the CDataAccess class object and the FinalRelease() method finally destroys the object.

Note

Wizard generates the CdataAccess class automatically.

Listing 6-13 shows the additional code that you need to add to the public scope of the CDataAccess class in the DataAccess.h file:

Listing 6-13: The DataAccess.h File

start example
 //Declare a reference to the ConnectionPointer class _ConnectionPtr m_pconnection; /*This method invokes automatically during the final stages of object construction after the constructor finishes execution and performs any final initialization*/ HRESULT FinalConstruct() {    HRESULT hr ;     //Initialize the current COM library    hr=CoInitialize(NULL) ;    if(!SUCCEEDED(hr))    return hr;    /*Create an instance of the ConnectionPointer class*/    hr = m_pconnection.CreateInstance(__uuidof(Connection));    if(!SUCCEEDED(hr))    return hr;    //Open connection to the database    hr = m_pconnection->Open(_T("DSN=Student"),"","",adOpenUnspecified);    return hr ; } /*This method invokes after all applications that access this component close and releases the connection to the database*/ HRESULT FinalRelease() {    //Uninitializes the COM library    CoUninitialize( ) ;    HRESULT hr = m_pconnection->Close() ;    return hr ; } 
end example

The above listing declares a reference to the ConnectionPointer class that connects to the Student database. In addition, the listing defines two methods:

  • FinalConstruct(): Initializes the COM library and establishes connection to the database. This method executes after the constructor completes execution.

  • FinalRelease(): Uninitializes the COM library and releases connection to the database. This method executes after all applications that access this component complete execution.

Defining the DataAccess.cpp File

The DataAccess.cpp file contains methods that handle database operations, such as adding a student record, deleting or updating an existing record, and searching for a particular record. The wizard automatically generates this file along with a skeleton of the methods in it. You need to define your own implementation of the methods.

Listing 6-14 shows the DataAccess.cpp file:

Listing 6-14: The DataAccess.cpp File

start example
 /*This method adds a new record to the database*/ STDMETHODIMP CDataAccess::AddRecord(long StudentId, BSTR name, BSTR address, BSTR dob, long phone) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset;    HRESULT hr;    CString query;    /*Format and store a series of characters and values in the query string*/    query.Format("INSERT INTO STUDENT VALUES(%ld,'%ls','%ls','%ls',%ld)", StudentId, name, address, dob,    phone);    /*Declare a CComVariant type, which does not need initialization*/    CComVariant vNull;    vNull.vt=VT_ERROR;    //scode field for parameter not found error     vNull.scode=DISP_E_PARAMNOTFOUND;    //Create an instance of the recordset    hr=rset.CreateInstance(__uuidof(Recordset));    if(SUCCEEDED(hr))    {       /*Set the reference of the active database connection to the recordset*/       rset->PutRefActiveConnection(m_pconnection);       /*Execute the query, using the Open() method of the recordset object*/       hr=rset->Open(query.operator LPCTSTR(), vNull, adOpenForwardOnly, adLockOptimistic,       adCmdText);       if(!SUCCEEDED(hr))       {          return false;       }    }    return S_OK; } /*This method deletes a record from the database. The StudentID field of the student record to be deleted is passed to this method*/ STDMETHODIMP CDataAccess::DeleteRecord(long StudentId) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset;    HRESULT hr;    CString query;    query.Format("DELETE FROM student WHERE StudentId = %d",StudentId);    CComVariant vNull;    vNull.vt = VT_ERROR;    vNull.scode = DISP_E_PARAMNOTFOUND;    hr = rset.CreateInstance(_uuidof(Recordset));    if (SUCCEEDED(hr))    {       rset->PutRefActiveConnection(m_pconnection);       hr = rset -> Open ( query.operator LPCTSTR(), vNull, adOpenForwardOnly, adLockOptimistic,       adCmdText);    }    return S_OK; } /*This method updates an existing record in the database. The fields in the student record to be updated are passed to this method*/ STDMETHODIMP CDataAccess::UpdateRecord(long StudentId, BSTR name, BSTR address, BSTR dob, long phone) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset ;    HRESULT hr ;    CString query ;    query.Format("UPDATE student SET studentName = '%ls', studentAddress='%ls', dob='%ls', phone=%ld    where StudentId=%ld", name, address, dob, phone, StudentId);    CComVariant vNull ;    vNull.vt = VT_ERROR ;    vNull.scode = DISP_E_PARAMNOTFOUND ;    hr = rset.CreateInstance ( __uuidof(Recordset) ) ;    if ( SUCCEEDED ( hr ) )    {       rset -> PutRefActiveConnection ( m_pconnection ) ;       hr = rset -> Open ( query.operator LPCTSTR(), vNull, adOpenForwardOnly, adLockOptimistic,       adCmdText );       if(!SUCCEEDED(hr))       return false;    }    return S_OK; } /*This method returns a recordset that contains the student record searched based on StudentID*/ STDMETHODIMP CDataAccess::SearchByStudentId(long StudentId, IDispatch **p) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset ;    CComVariant v ( 0L ) ;    CString query ;    query.Format("SELECT * FROM student where StudentId= %d",StudentId);    /*Execute the query using the Execute() method of the Connection object that returns a recordset*/    rset = m_pconnection -> Execute ( query.operator LPCTSTR( ), &v, adOptionUnspecified );    /*Pass a reference of the resultant recordset to Idispatch*/    *p = (IDispatch* ) rset ;     /*Increment the counter variable inside the COM object*/    rset->AddRef() ;    return S_OK; } /*This method returns a recordset that contains student records sorted by studentName or StudentID*/ STDMETHODIMP CDataAccess::Sort(long no, IDispatch **p) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset ;    CString query ;    CComVariant v ( 0L ) ;    /*If Value of no is 0, sort by StudentID. Otherwise sort by name.*/    if ( no == 0 )     query.Format("SELECT * FROM student order by StudentId");    else    query.Format("SELECT * FROM student order by name");    rset = m_pconnection -> Execute ( (_bstr_t)query, NULL, adOptionUnspecified );    *p = (IDispatch* ) rset ;     rset->AddRef() ;    return S_OK; } /*This method returns a recordset that contains the student record searched based on student name*/ STDMETHODIMP CDataAccess::SearchByName(BSTR name, IDispatch **p) {    AFX_MANAGE_STATE(AfxGetStaticModuleState())    // TODO: Add your implementation code here    _RecordsetPtr rset ;    CComVariant v ( 0L ) ;    CString query ;    query.Format("SELECT * FROM student where name= \" "+(_bstr_t)name+"\"");    rset = m_pconnection -> Execute ( query.operator LPCTSTR( ), &v, adOptionUnspecified );    *p = (IDispatch* ) rset ;     rset->AddRef() ;    return S_OK; } 
end example

The above listing defines the following methods:

  • AddRecord(): Adds a student record to the student table in the database.

  • DeleteRecord(): Deletes an existing record from the student table in the database.

  • UpdateRecord(): Updates student records in the student table in the database.

  • SearchByStudentId(): Searches for the student record based on the student ID and returns a recordset that contains the searched student record.

  • SearchByName():Searches for the student record based on the name and returns a recordset that contains the searched student record.

  • Sort(): Retrieves the student records from the student table in the database ordered by name or student ID based on the flag passed to this method and returns the result in a recordset.

Creating the AddressBook Project

This project creates the user interface for the application using which the school authorities can use and manipulate student information. The project handles the various events that are generated because of the interaction with the controls on the interface.

To create the AddressBook project:

  1. Select the MFC AppWizard(exe) in Visual C++ 6.0 to create a new project named AddressBook with the Dialog-based option selected. The wizard generated application template window opens.

  2. Select Project->Add To Project->Components and Controls. The Components and Controls Gallery window opens.

  3. Double-click the Registered ActiveX Controls folder. A list of all the ActiveX controls in the folder appears. Select the Microsoft Date and Time Picker Control, version 6.0 control and click Insert. The Microsoft Visual C++ alert box opens that asks you whether or not to insert the component.

  4. Click OK. The Confirm Classes window opens. Click OK to accept the default class names.

  5. Close the Components and Controls Gallery window. The Microsoft Date and Time Picker Control, version 6.0 control adds to the toolbox.

  6. Create the user interface for the application by dragging controls from the toolbox, at the desired places on the user interface window. Figure 6-1 shows the user interface of the AddressBook application in its design view:

    click to expand: this figure shows the user interface of the addressbook application that allows the school authorities to view, add, update, delete, and search student records.
    Figure 6-1: User Interface of the Application

  7. Right-click on each control added to the user interface and select Properties. The Text Properties window opens.

  8. Select the General tab and type the ID of the control in the ID textbox. Close the window.

  9. Right-click each control added to the user interface and select ClassWizard. The MFC ClassWizard window opens.

  10. In the MemberVariables tab of the window, select each control and click Add Variable to associate variables with the control. The Add Member Variable window opens.

  11. Type the name of the member variable in the Member variable name text box. Select the category and the variable type from the drop-down lists and click OK. Table 6-3 shows the control ID, variable types, and the member variable names for each control in the user interface:

    Table 6-3: Information about the Controls

    Control

    Control ID

    Type

    Member Variable Name

    Address textbox

    IDC_ADDRESS

    CString

    m_address

    Address textbox

    IDC_ADDRESS

    CEdit

    m_addressCtrl

    Name textbox

    IDC_NAME

    CString

    m_name

    Name textbox

    IDC_NAME

    CEdit

    m_nameCtrl

    Phone Number textbox

    IDC_PHONE

    Long

    m_phone

    Phone Number textbox

    IDC_PHONE

    CEdit

    m_phoneCtrl

    Student ID textbox

    IDC_STUDENTID

    Long

     m_StudentId 

    Student ID textbox

    IDC_STUDENTID

    CEdit

    m_StudentIdCtrl

    New button

    IDC_NEW

    -

    -

    Delete button

    IDC_DELETE

    -

    -

    Update button

    IDC_UPDATE

    -

    -

    Search button

    IDC_SEARCH

    -

    -

    Commit button

    IDC_COMMIT

    CButton

    m_commit

    Hide List button

    IDC_HIDE

    CButton

    m_hlist

    Show List button

    IDC_SHOWLIST

    CButton

    m_show

    Exit button

    IDC_EXIT

    -

    -

    Date of Birth ActiveX control

    IDC_DATEPICKER1

    CDTPicker

    m_dob

    Search button (next to the Student

    ID textbox)

    IDC_FINALSEARCH

    CButton

    m_finalsearch

    List

    IDC_LIST1

    CListCtrl

    m_list

    Search by or Sort by Group Box

    IDC_SORTSTATIC

    CButton

    m_static

    Name radio button

    IDC_NAMERADIO

    CButton

    m_nameradioCtrl

    StudentID radio button

    IDC_STUDENTIDRADIO

    Int

    m_StudentIdradio

    Student ID radio button

    IDC_STUDENTIDRADIO

    CButton

    m_StudentIdradioCtrl

  12. Double-click each control with which you want to associate a method. The Add Member Function window opens in which you type the name of the associated method in the Member function name textbox. The method is added to the dialog window class.

  13. Add reference to ADO and the StudentData COM libraries. Listing 6-15 shows how to add these references:

    Listing 6-15: Adding Reference to ADO and StudentData Library

    start example
     //Include a reference to the ADO library # import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") /*Add a reference of the StudentData type library to the current application*/ # import "..\StudentData\StudentData.tlb" using namespace STUDENTDATALib ; 
    end example

    The above listing shows how to add reference to ADO and StudentData library. Adding reference to ADO library allows you to use ADO objects and adding reference to StudentData library allows you to use the methods that the StudentData component provides to access and manipulate student information.

  14. Add a new generic class, CStudent to the project.

The wizard automatically creates several files in the project. You need to define implementation of methods in the AddressBookDlg.cpp file and the Student.cpp file. In addition, you need to declare member variables in the AddressBookDlg.h file and the Student.h file.

Defining the AddressBookDlg.h File

In the AddressBookDlg.h header file, you need to declare the global variables that the CAddressBookDlg class uses. These include flags and a pointer to the CStudent class. Listing 6-16 shows the additional variables that you need to add to the private scope of the CAddressBookDlg class in the AddressBookdlg.h file:

Listing 6-16: The AddressBookDlg.h File

start example
 /*Flag to store whether the operation performed is search or sort*/ int SearchorSort; /*Variable to store the value of the Student ID selected in the list*/ long selected; /*Flag to store whether to search by Student ID or by name*/ int searchby; //Flag to store the current operation int m_oper; CStudent *student; 
end example

The above listing shows the private variables you need to add to the definition of the CAddressBookDlg class in the AddressBookdlg.h file.

Defining the Student.h File

In the Student.h header file, you need to include a reference to the IDataAccess interface that the StudentData component provides so that the CStudent class can access the database access methods of the StudentData component. To add a reference, you need to add the following code to the public scope of the CStudent class in the Student.h file:

 //Add a reference to the IDataAccess interface IDataAccess * stud; 

Defining the AddressBookDlg.cpp File

The AddressBookDlg.cpp file contains methods that handle the events generated when the end users interact with the controls on the user interface. The wizard automatically generates this file along with a skeleton code for the methods. You need to define your own implementation of the methods.

Listing 6-17 shows the AddressBookDlg.cpp file:

Listing 6-17: The AddressBookDlg.cpp File

start example
 /*This method performs initialization operations when the main window opens*/ BOOL CAddressBookDlg::OnInitDialog() {    //Windows-generated code    //TODO: Add extra initialization here    // Initialize COM library    CoInitialize ( NULL ) ;    /*Declare a variable to store the class ID of the DLL*/    CLSID clsid ;    HRESULT hr ;    /*Retrieves the corresponding class ID of a ProgID from the registry*/    hr = CLSIDFromProgID( OLESTR ("StudentData.DataAccess" ), &clsid) ;     if ( SUCCEEDED ( hr ) ) {       /* Creates uninitialized instance of specified CLSID, using the CoCreateInstance() method with       the arguments (class id, default null, context in which newly created object will run, reference       to interface, address of ptr that receives the interface ptr).*/       hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL,  __uuidof (IDataAccess), (void **) &stud)       ;       if( !SUCCEEDED ( hr ) )       {          CoUninitialize();          MessageBox("Connection could not be initialized.");          exit(0);       }    }    else    {       CoUninitialize();       MessageBox("Connection could not be initialized.");       exit(0);    }    /*Adds columns to the list using the InsertClumn method with the arguments column number, name,    alignment, width*/    m_list.InsertColumn(0,"Student ID",LVCFMT_LEFT,90) ;    m_list.InsertColumn(1,"Name",LVCFMT_LEFT,96) ;    m_list.InsertColumn(2,"Address",LVCFMT_LEFT,100) ;    m_list.InsertColumn(3,"Date of Birth", LVCFMT_LEFT, 90) ;    m_list.InsertColumn(4,"Phone No.", LVCFMT_LEFT, 90) ;    searchby=0;    SearchorSort=0;    SetWindowPos(&wndTop,100,50,500,310,SWP_SHOWWINDOW) ;    m_StudentIdradioCtrl.SetCheck(true);    /* Pass the reference of the COM connection to the constructor of the CStudent class*/    student=new CStudent(stud);    return TRUE;   } /*This method closes the main application window when the end user clicks the Exit button*/ void CAddressBookDlg::OnExit()  {    /* TODO: Add your control notification handler code here*/    DestroyWindow();    exit(0); } /*This method enables the disabled text boxes to allow the end user to enter the values of the new record*/ void CAddressBookDlg::OnNew()  {    /* TODO: Add your control notification handler code here*/    m_StudentId=0;    m_name="";    m_address="";    m_phone=0;    UpdateData(false);    m_StudentIdCtrl.EnableWindow ( TRUE ) ;    m_nameCtrl.EnableWindow ( TRUE ) ;    m_addressCtrl.EnableWindow ( TRUE ) ;    m_phoneCtrl.EnableWindow ( TRUE ) ;    m_dob.EnableWindow( TRUE ) ;    m_finalsearch.ShowWindow(SW_HIDE);    m_static.SetWindowText("Sort By");    m_commit.EnableWindow ( TRUE ) ;    m_StudentIdCtrl.SetFocus();    /*Set the operation to 1 to indicate AddNew Record operation*/    m_oper = 1 ;    SearchorSort=0; } /*This method calls the Delete() method of the CStudent class, when the end user clicks the Delete button */ void CAddressBookDlg::OnDelete()  {    /* TODO: Add your control notification handler code here*/    /*Pass the data from the controls into the variables*/    UpdateData(true);    student->DeleteRecord( m_StudentId ) ;    m_StudentId=0;    m_name="";    m_address="";    m_phone=0;    UpdateData(false);    OnShowlist();    SearchorSort=0; } /*This method enables the disabled text boxes to allow the user to enter the updated values of the record*/ void CAddressBookDlg::OnUpdate()  {    /* TODO: Add your control notification handler code here*/    UpdateData(true);    if(m_StudentId==0)    {       OnShowlist();       return;    }    m_commit . EnableWindow ( TRUE ) ;    m_nameCtrl.EnableWindow ( TRUE ) ;    m_addressCtrl.EnableWindow ( TRUE ) ;    m_phoneCtrl.EnableWindow ( TRUE ) ;    m_dob.EnableWindow( TRUE ) ;    /*Set the operation to 2 to indicate Update Record operation*/ m_oper = 2 ; SearchorSort=0; } /*This method enables and disables controls when the end user clicks the Search button*/ void CAddressBookDlg::OnSearch()  {    m_StudentId=0;    m_address="";    m_phone=0;    m_name="";    UpdateData(false);    m_StudentIdradioCtrl.SetCheck(true);    m_nameradioCtrl.SetCheck(false);    m_StudentIdCtrl.EnableWindow(true);    m_nameCtrl.EnableWindow(false);    m_finalsearch.EnableWindow(true);    m_finalsearch.ShowWindow(SW_SHOW);    m_addressCtrl.EnableWindow(false);    m_phoneCtrl.EnableWindow(false);    m_dob.EnableWindow(false);    m_static.SetWindowText("Search By");    m_commit.EnableWindow(false);    /*Set the search operation to search by Student ID*/    searchby=0;    SearchorSort=1; } /*This method shows the list sorted by Student ID or by name*/ void CAddressBookDlg::OnShowlist()  {    /* TODO: Add your control notification handler code here*/    /*Sets the size and position of the application window*/    SetWindowPos ( &wndTop, 100, 50, 500, 497, SWP_SHOWWINDOW ) ;    m_hlist.EnableWindow(true);    m_list.DeleteAllItems( ) ;    UpdateData ( TRUE ) ;    /*Declare variables to store student information*/    CComVariant studentStudentId ;    CComVariant studentname ;    CComVariant studentaddress ;    CComVariant studentphoneno ;    CComVariant studentdob ;    CString name,ID,address, dob, phone;    long i = 0 ;    _RecordsetPtr rset ;    int no=m_StudentIdradio;    /*Call the Sort method of the CStudent class to retrieve a recordse that contains sorted student    information*/    rset = (_RecordsetPtr) student->Sort(no);    /*Iterating through the recordset object to retrieve student information*/    while ( !rset -> adoEOF ) {       studentStudentId = rset -> GetCollect ( L"StudentId" ) ;       ID.Format ( "%d", studentStudentId.lVal ) ;       m_list.InsertItem ( i, ID , i ) ;       studentname = rset -> GetCollect ( L"name" ) ;       name = studentname.bstrVal ;       m_list.SetItemText ( i, 1, name ) ;       studentaddress = rset -> GetCollect ( L"add" ) ;       address=studentaddress.bstrVal;       m_list.SetItemText ( i, 2, address ) ;       studentdob= rset -> GetCollect ( L"dob" ) ;       dob=studentdob.bstrVal;       m_list.SetItemText ( i, 3, dob ) ;       studentphoneno = rset -> GetCollect ( L"phone" ) ;       phone.Format ( "%ld", studentphoneno.lVal) ;       m_list.SetItemText ( i, 4, phone ) ;       rset -> MoveNext( ) ;       i++ ; } rset->Close( ) ; } /*This method hides the list and adjusts the size of the window, when the end user clicks the Hide List button*/ void CAddressBookDlg::OnHide()  {    /* TODO: Add your control notification handler code here*/    SetWindowPos ( &wndTop, 100, 50, 500, 310, SWP_SHOWWINDOW ) ;    m_hlist.EnableWindow(false); } /*This method calls the search method of the CStudent class to search the record based on a particular Student ID or name*/ void CAddressBookDlg::OnFinalsearch()  {    /* TODO: Add your control notification handler code here*/    SetWindowPos ( &wndTop, 100, 50, 500, 497, SWP_SHOWWINDOW ) ;    m_hlist.EnableWindow(true);    m_static.SetWindowText("Sort By");    UpdateData(true);    m_list.DeleteAllItems( ) ;    UpdateData ( TRUE ) ;    /*Declare variables to store the values of a student record*/    CComVariant studentStudentId ;    CComVariant studentname ;    CComVariant studentaddress ;    CComVariant studentphoneno ;    CComVariant studentdob ;    CString namestr,ID,address, dob, phone;    long i = 0 ;    _RecordsetPtr rset ;    long no=m_StudentId;    _bstr_t name1=(_bstr_t)m_name;    if(searchby==0)    /*Call the SearchByStudentId method of CStudent class to retrieve the student information based on    Student ID*/    rset = (_RecordsetPtr) student->SearchByStudentId(m_StudentId) ;    else    /*Call the SearchByName method of CStudent class to retrieve the student information based on Name*/    rset = (_RecordsetPtr) student->SearchByName(m_name) ;    /*Iterating through the recordset object to retrieve student information*/    while ( !rset -> adoEOF ) {       studentStudentId = rset -> GetCollect ( L"StudentId" ) ;       ID.Format ( "%ld", studentStudentId.lVal ) ;       m_list.InsertItem ( i, ID , i ) ;       m_StudentId=studentStudentId.lVal ;       studentname = rset -> GetCollect ( L"name" ) ;       namestr = studentname.bstrVal ;       m_list.SetItemText ( i, 1, namestr ) ;       m_name=namestr;       studentaddress = rset -> GetCollect ( L"add" ) ;       address=studentaddress.bstrVal;       m_list.SetItemText ( i, 2, address ) ;       m_address=address;       studentdob= rset -> GetCollect ( L"dob" ) ;       dob=studentdob.bstrVal;       m_list.SetItemText ( i, 3, dob ) ;       m_dob.SetValue(studentdob);       studentphoneno = rset -> GetCollect ( L"phone" ) ;       phone.Format ( "%ld", studentphoneno.lVal) ;       m_list.SetItemText ( i, 4, phone ) ;       m_phone=studentphoneno.lVal;       rset -> MoveNext( ) ;       i++ ; }    rset->Close( ) ;    if(i==0)    MessageBox("No Record Found","Message");    m_finalsearch.EnableWindow(false);    m_finalsearch.ShowWindow(SW_HIDE);    m_StudentIdCtrl.EnableWindow(false);    m_nameCtrl.EnableWindow(false);    m_commit.EnableWindow(false);    SearchorSort=0;    searchby=0;    UpdateData(false); } /*This method calls the OnShowlist() method to show the list sorted by Student ID, if the sort flag is on. If the search flag is on, it will enable and disable appropriate controls for search purpose*/ void CAddressBookDlg::OnStudentIdradio()  {    /* TODO: Add your control notification handler code here */    /* 0 means sort by i.e. search option is off.*/    if(SearchorSort==0) OnShowlist();    else    {       m_StudentIdCtrl.EnableWindow(true);       m_nameCtrl.EnableWindow(false);       searchby=0;    } } /*This method calls the OnShowlist() method to show the list sorted by name, if the sort flag is on. If the search flag is on, it will enable and disable appropriate controls for search purpose*/ void CAddressBookDlg::OnNameradio()  {    if(SearchorSort==0)    OnShowlist();    else    {       m_StudentIdCtrl.EnableWindow(false);       m_nameCtrl.EnableWindow(true);       searchby=1;    } } /*This method displays the student record selected from the list in the text boxes*/ void CAddressBookDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)  {    /* Get the index of the row containing the selected item*/    long count=m_list.GetSelectionMark();    if(count>=0)    {       /*Retrieve the text value of the entry as specified by the row number and column number*/       CString s=m_list.GetItemText(count,0);       selected=atoi(s);       CComVariant studentStudentId;       CComVariant studentname ;       CComVariant studentaddress ;       CComVariant studentphone ;       CComVariant studentdob;       _RecordsetPtr rset ;       rset = ( _RecordsetPtr ) student ->SearchByStudentId(selected) ;       if ( ! rset -> adoEOF )       {          /*Extract the Student ID from the recordset */          studentStudentId = rset -> GetCollect ( L"StudentId" ) ;          /*Set the value of the Student ID variable to the retrieved value*/          m_StudentId = studentStudentId.lVal ;          /*Extract the name from the recordset */          studentname = rset -> GetCollect ( L"name" ) ;          /*Set the value of the name variable to the retrieved value*/          m_name = studentname.bstrVal ;          /*Extract the address from the recordset */          studentaddress = rset -> GetCollect ( L"add" ) ;          /*Set the value of the address variable to the retrieved value*/          m_address = studentaddress.bstrVal ;          /*Extract the phone number from the recordset */          studentphone = rset -> GetCollect ( L"phone" ) ;          /*Set the value of the phone number variable to the retrieved value*/          m_phone = studentphone.lVal ;          /*Extract the date of birth from the recordset */          studentdob = rset -> GetCollect ( L"dob" ) ;          /*Set the value of the date of birth variable to the retrieved value*/          m_dob.SetValue(studentdob);          rset -> Close( ) ;          /*Pass values from the variables to the text box controls*/          UpdateData ( FALSE ) ;          m_StudentIdCtrl.EnableWindow(FALSE);          m_nameCtrl.EnableWindow ( FALSE ) ;          m_phoneCtrl.EnableWindow ( FALSE ) ;          m_dob.EnableWindow( FALSE );          m_addressCtrl.EnableWindow ( FALSE ) ;          m_commit.EnableWindow ( FALSE ) ; }       else       MessageBox ("Record not found") ; }    *pResult = 0; } /* This method commits the changes to be made to the database when either a new record is added or an existing record is updated*/ void CAddressBookDlg::OnCommit()  {    /* TODO: Add your control notification handler code here*/    if(!UpdateData ( TRUE ) )    return;    CString datestr="";    _variant_t day,month,year;    if(m_StudentId==0)    {       MessageBox("StudentId cannot be 0");       return; }    /*Extract the values of the day, month and year using methods exposed by the Microsoft Date and Time    Picker ActiveX control*/    day=m_dob.GetDay();    month=m_dob.GetMonth();    year=m_dob.GetYear();    /*Format the date string in the mm/dd/yyyy form*/    datestr.Format("%d/%d/%d",month.intVal,day.intVal,year.intVal);    CComVariant studentStudentId ;    _RecordsetPtr rset ;    switch ( m_oper )    {       //AddNew Record operation       case 1:       if(!student->IsStudentIdExists(m_StudentId))       student->AddRecord(m_StudentId, m_name, m_address, datestr, m_phone) ;       else       {          MessageBox("Student ID already exists.","Message");          return;       }       OnShowlist();       break ;       //Update Record operation       case 2:       student ->UpdateRecord(m_StudentId, m_name, m_address, datestr, m_phone) ;       OnShowlist();       break ; }    m_StudentId = 0 ;    m_name = "" ;    m_address = "" ;    m_phone=0;    m_StudentIdCtrl.EnableWindow ( FALSE ) ;    m_nameCtrl.EnableWindow ( FALSE ) ;    m_addressCtrl.EnableWindow ( FALSE ) ;    m_phoneCtrl.EnableWindow(FALSE);    m_dob.EnableWindow( FALSE ) ;    m_commit.EnableWindow ( FALSE ) ;    UpdateData ( FALSE ) ;    m_static.SetWindowText("Sort By"); } 
end example

The above listing defines the following methods:

  • OnInitDialog(): Performs initialization operations when the main application window opens. These operations include initializing the COM library, establishing connection with the COM component, setting the size of the window, and enabling and disabling controls.

  • OnExit(): Destroys the application window when the end user quits the application.

  • OnNew(): Enables the disabled textbox controls to allow the school authorities to enter the information for the new student record to be added. This method invokes when an end user clicks the New button.

  • OnDelete(): Calls the DeleteRecord() method of the CStudent class when an end user clicks the Delete button.

  • OnUpdate(): Enables the disabled textbox controls to allow the school authorities to enter the updated values of the selected student record. This method invokes when an end user clicks the Update button.

  • OnSearch(): Enables and disables appropriate controls when an end user clicks the Search button.

  • OnShowList(): Shows the student information sorted by student ID or by name, after retrieving the information from the database.

  • OnHide(): Hides the list and adjusts the size of the window when an end user clicks the Hide List button.

  • OnFinalSearch(): Calls the SearchByName() method or the SearchByStudentId() method of the CStudent class to search the record based on a particular student ID or name. In addition, the method displays the retrieved information in the text box controls. This method invokes when an end user clicks the Search button.

  • OnStudentIdradio(): Calls the OnShowList() method to show the student information sorted by student ID, if the sort flag is on. If the search flag is on, this method enables and disables appropriate controls for search purpose. This method invokes when an end user selects the Student ID radio option in the Sort group box.

  • OnNameradio(): Calls the OnShowList() method to show the student information sorted by name, if the sort flag is on. If the search flag is on this method enables and disables appropriate controls for search purpose. This method invokes when the end user selects the Name radio option in the Sort group box.

  • OnClickList1(): Fills the text box controls with the student information selected from the student list. This method invokes when an end user clicks a student record in the student list.

  • OnCommit(): Commits changes to be made to the database when the school authorities specify the student information to be added or updated. This method invokes when an end user clicks the Commit button.

Defining the Student.cpp File

The Student.cpp file contains the CStudent class that represents a student and contains methods that calls the methods of the StudentData component to perform operations, such as adding, retrieving, updating, deleting, and searching student information in the database.

Listing 6-18 shows the code of the Student.cpp file

Listing 6-18: The Student.cpp File:

start example
 //Constructor for the CStudent class CStudent::CStudent(IDataAccess * studptr) {    /*Store the connection pointer that stores connection to the StudentData component*/    stud=studptr; } /*This method calls the DeleteRecord() method of the StudentData component and passes the Student ID value of the record to be deleted*/ void CStudent::DeleteRecord(long StudentId) {    stud ->DeleteRecord( StudentId ) ; } /*This method calls the Sort() method of the StudentData component that sorts the list by name or Student ID, as specified to it*/ _RecordsetPtr CStudent::Sort(BOOL NameOrStudentID) {    return (_RecordsetPtr) stud -> Sort(NameOrStudentID) ; } /*This method calls SearchByName() method of the StudentData component that searches a particular record based on the name passed to it.*/ _RecordsetPtr CStudent::SearchByName(CString name) {    return (_RecordsetPtr) stud ->SearchByName((_bstr_t)name) ; } /*This method calls the SearchByStudentId() method of the StudentData component that searches a particular record based on the Student ID passed to it.*/ _RecordsetPtr CStudent::SearchByStudentId(long StudentId) {    return (_RecordsetPtr) stud ->SearchByStudentId(StudentId) ; } /*This method checks if the StudentID value passed to it already exists in the database or not*/ BOOL CStudent::IsStudentIdExists(long StudentId) {    _RecordsetPtr rset = (_RecordsetPtr) stud ->Sort(0) ;    long StudentIDtemp;    int i;    while ( !rset -> adoEOF )    {       StudentIDtemp=(rset -> GetCollect ( L"StudentId" )).intVal ;       if(StudentIDtemp==StudentId)       {          return true; } rset -> MoveNext( ) ; i++ ;    }    rset->Close( ) ;    return false; } /*This method calls the AddRecord method of the StudentData component and passes the value of the fields of the record to be inserted*/ void CStudent::AddRecord(long StudentId, CString name, CString address, CString dob, long phone) {    stud ->AddRecord(StudentId, (_bstr_t)name, (_bstr_t)address, (_bstr_t)dob, phone) ; } /*This method calls the UpdateRecord method of the StudentData component and passes all the fields of the record to be updated*/ void CStudent::UpdateRecord(long StudentId, CString name, CString address, CString dob, long phone) {    stud ->UpdateRecord(StudentId, (_bstr_t)name, (_bstr_t)address, (_bstr_t)dob, phone) ; } 
end example

The above listing defines the following methods:

  • CStudent(): Stores the connection pointer to the StudentData component.

  • AddRecord(): Calls the AddRecord() method of the StudentData component, passing the values of the various fields for the new record as arguments.

  • DeleteRecord(): Calls the DeleteRecord() method of the StudentData component, passing the student ID field of the student record to be deleted as an argument.

  • UpdateRecord(): Calls the UpdateRecord() method of the StudentData component, passing the values of various fields for the student record to be updated as arguments.

  • SearchByStudentId(): Calls the SearchByStudentId() method of the StudentData component, passing the value of the student ID field of the student record to be searched.

  • SearchByName():Calls the SearchByName() method of the StudentData component, passing the value of the name field of the student record to be searched.

  • Sort(): Calls the Sort() method of the StudentData component, passing the flag that decides whether to sort by name or student ID as an argument.

  • IsStudentIdExists(): Checks whether or not the student ID value passed to the method already exists in the database.

Creating the AddressBook Application Using Managed C++ Extensions

Creating the AddressBook application using managed extensions for VC++ allows you to use the features of the .NET Framework, such as compilation to Intermediate Language (IL), automatic garbage collection, access to Base Class Libraries, and interoperability with unmanaged code.

  • In VC++.NET, the AddressBook application is a Windows Forms application that uses managed extensions for C++. This application consists of one project, AddressBook, which defines the AddressBook window and calls to the methods provided by the StudentData COM component, created earlier using VC++. The VC++.NET AddressBook project provides the same functionality as the VC++ AddressBook project provides but it uses the managed extension for C++ to provide the functionality.

Creating the AddressBook Project

The AddressBook project consists of the following files:

  • Form1.h: Contains the implementation of the form class and InitializeComponent() function. This file defines the AddressBook window.

  • Form1.cpp: Contains code to display the form. This is the main application source file.

When you create a Windows Forms application using managed extensions for C++, several files such as StdAfx.h are added automatically to the solution. You need to write code in Form1.h and Form1.cpp files.

Important

To interact with the StudentData COM component, you need to add a reference to the StudentData Library from the available COM component list. When you add a reference to the StudentData Library, the .NET Framework creates a Runtime Callable Wrapper (RCW) around the COM component provided by the StudentData Library to enable interoperability.

Creating the AddressBook Window

The Student class defines the AddressBook window that allows the end users to work with student information. Student class is a managed class as the definition of the Student class is prefixed by the __gc keyword. Declaring the Student class as managed allows the CLR to perform garbage collection on the objects of the Student class. Listing 6-19 shows the Form1.h file that provides the Student class:

Listing 6-19: The Form1.h File

start example
 #pragma once #using <mscorlib.dll>  namespace AddressBook    {       using namespace System;       using namespace System::Runtime::InteropServices;        using namespace System::ComponentModel;       using namespace System::Collections;       using namespace System::Windows::Forms;       using namespace System::Data;       using namespace System::Drawing;       using namespace System::Data::OleDb;       //To use MessageBox API       [DllImport("user32")]       extern "C" int MessageBox(void *,        [MarshalAs (UnmanagedType::LPStr)] String *,        [MarshalAs (UnmanagedType::LPStr)] String *, int uType);        public __gc class Student : public System::Windows::Forms::Form       {          public:          Student(void)          {             InitializeComponent();          }          /* This method shows the student records in the listViewStudent ListView control*/          void showList()          {        try             {                listViewStudent->Items->Clear();                /* Calling the Sort() method of StudentData component*/                ADODB::Recordset *r=(ADODB::Recordset *)DataAccess->Sort(sortBy);                /* Creating the DataAdapter */                OleDbDataAdapter *x=new OleDbDataAdapter();                /* Pointer to DataSet class*/                DataSet *ds;                /* Pointer to DataTable class */                DataTable *dt;                /*Creating a DataSet object*/                ds=new DataSet();                /*Creating a DataTable object*/                dt=new DataTable();                /* Filling the Dataset with the contents of recorset retrieved from the Sort() method*/                x->Fill(ds,r,S"student");                /* Retrieving the table from the dataset. This table is the student table.*/                dt=ds->Tables->get_Item(0);                int i;                /*Adding student information is listViewStudent ListView control*/                for(i=0;i<dt->Rows->Count ;i++)                {                   DataRow *dr;                   dr=dt->Rows->get_Item(i);                   ListViewItem *tempListViewItem;                  tempListViewItem=listViewStudent->Items->Add                  (dr->get_Item(0)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(1)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(2)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(3)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(4)->ToString());                }               }             catch(System::Exception *e)             {                MessageBox(0, e->Message->ToString(),"Error", 0);              }          }          private:           Interop::STUDENTDATALib::DataAccessClass * DataAccess;          int m_oper;          /*A variable to store the flag whether the search option is on or not.*/          int SearchorSort;          /*A variable to store the flag whether the search is to be performed by name or by Student          ID*/          int searchby;          /*A variable to store the flag whether the sort is to be performed by name or by Student ID*/          int sortBy;          System::ComponentModel::Container * components;          System::Void cmdExit_Click(System::Object *  sender, System::EventArgs *  e)          {             exit(0);          }          /* This method invokes when StudentId radio option is clicked.*/          System::Void radioStudentId_CheckedChanged(System::Object *  sender, System::EventArgs *  e)          {             /* 0 means sort by option is on and search option is off.*/             if(SearchorSort==0)             {                sortBy=0;                showList();             }             else             {                txtStudentId->set_Enabled(true);                txtName->set_Enabled(false);                searchby=0;             }            }          System::Void Student_Load(System::Object *  sender, System::EventArgs *  e)          {             try             {                /* Pointer to  COM component is created. STUDENTDATALib is RCW created while adding a                reference to the                StudentData component*/                DataAccess=new  Interop::STUDENTDATALib::DataAccessClass;             }             catch(Exception *e)             {                MessageBox(0, e->Message->ToString(),"Error", 0);                 return;             }             txtStudentId->Clear() ;             txtName->Clear();             txtAddress->Clear();             txtPhone->Clear();             txtStudentId->set_Enabled(false);             txtName->set_Enabled(false);             txtAddress->set_Enabled(false);             txtPhone->set_Enabled(false);             dateTimeDOB->set_Enabled(false);             cmdCommit->set_Enabled(false);             cmdGo->set_Visible(false);             groupBoxSort->set_Text("Sort By");             sortBy=0;             showList();          }          /* This method invokes when the New button is clicked.*/          System::Void cmdNew_Click(System::Object *  sender, System::EventArgs *  e)          {             txtStudentId->Clear();             txtName->Clear();             txtAddress->Clear();             txtPhone->Clear();             txtStudentId->set_Enabled(true);             txtName->set_Enabled(true);             txtAddress->set_Enabled(true);             txtPhone->set_Enabled(true);             dateTimeDOB->set_Enabled(true);             cmdGo->set_Visible(false);             cmdCommit->set_Enabled(true);             groupBoxSort->set_Text("Sort By");             txtStudentId->Focus();             m_oper = 1 ;             SearchorSort=0;     }          /* This method invokes when the Delete button is clicked.*/          System::Void cmdDelete_Click(System::Object *  sender, System::EventArgs *  e)          {             /* Check if StudentId is entered or not.*/             if(!txtStudentId->get_Text()->Length)             return;             try             {                /*convert the StudentId from string to integer of 32 bit i.e. long*/                long StudentId=System::Int32::Parse(txtStudentId->get_Text()->Trim());                /* call the DeleteRecord of StudentData component*/                DataAccess->DeleteRecord(StudentId);             }             catch(Exception *e)             {             MessageBox(0, e->Message->ToString(),"Error", 0);              return;          }          txtStudentId->Clear();          txtName->Clear();          txtAddress->Clear();          txtPhone->Clear();          showList();          SearchorSort=0;       }       /* This method invokes when the Update button is clicked.*/       System::Void cmdUpdate_Click(System::Object *  sender, System::EventArgs *  e)       {          /* Check is the StudentId is selected from list.*/          if(!txtStudentId->get_Text()->get_Length())          {             showList();             return;          }          cmdGo->set_Visible(false);          cmdCommit->set_Enabled(true);          txtStudentId->set_Enabled(false);          txtName->set_Enabled(true) ;          txtAddress->set_Enabled(true);          txtPhone->set_Enabled(true);          dateTimeDOB->set_Enabled(true);          txtName->Focus();          /*Set the operation to 2 to indicate Update Record operation.*/          m_oper = 2 ;          SearchorSort=0;       }       /* This method invokes when the Search button is clicked.*/       System::Void cmdSearch_Click(System::Object *  sender, System::EventArgs *  e)       {          showList();          txtStudentId->Clear();          txtAddress->Clear();          txtPhone->Clear();          txtName->Clear();          radioStudentId->set_Checked(true);          radioName->set_Checked(false);          txtStudentId->set_Enabled(true);          txtName->set_Enabled(false);          cmdGo->set_Enabled(true);          cmdGo->set_Visible(true);          txtAddress->set_Enabled(false);          txtPhone->set_Enabled(false);          dateTimeDOB->set_Enabled(false);          groupBoxSort->set_Text("Search By");          cmdCommit->set_Enabled(false);          /*Set the search operation to search by Student ID*/          searchby=0;          SearchorSort=1; }       /* This method invokes when the Commit button is clicked.*/       System::Void cmdCommit_Click(System::Object *  sender, System::EventArgs *  e)       {          //check for the Student ID          if(!txtStudentId->get_Text()->Trim()->get_Length())          {             MessageBox(0, S"You must enter the StudentId.", S"StudentId. Entry Error", 0);              return;          }          String *datestr=S"";          int day,month,year;          /* get the date, month and year from date time control*/          day=dateTimeDOB->get_Value().get_Day();          month=dateTimeDOB->get_Value().get_Month();          year=dateTimeDOB->get_Value().get_Year();          String *slash=S"/";          /* concatenate the string to create a format of mm/dd/yyyy and store in datestr variable*/          datestr=datestr->Concat(month.ToString(),slash,day.ToString(),slash,year.ToString());          ADODB::Recordset *r;          int rows, phoneNo=0;          try          {             /* Convert the StudentId from string to int of 32 bit*/             System::Int32::Parse(txtStudentId->get_Text()->Trim());             if(txtPhone->get_Text()->Trim()->Length)             phoneNo=System::Int32::Parse(txtPhone->get_Text()->Trim());          }          catch(System::Exception *)          {             MessageBox(0,S"Please enter the StudentId and Phone no. in numeric form.",S"Message",0);             return;          }          try             {                /*Calling the SearchByStudentId function of StudentData component*/                r=(ADODB::Recordset *)DataAccess->SearchByStudentId(System::Int32::Parse                (txtStudentId->get_Text()->Trim()));                OleDbDataAdapter *x=new OleDbDataAdapter();                DataSet *ds;                DataTable *dt;                ds=new DataSet();                dt=new DataTable();                x->Fill(ds,r,S"student");                dt=ds->Tables->get_Item(0);                rows=dt->Rows->Count;      }             catch(System::Exception *e)             {                MessageBox(0, e->Message->ToString(),"Error", 0);                return;              }             /*Checking which operation is performed by the end user*/             switch ( m_oper )             {                //AddNew Record operation                case 1: if(!rows)                {                   /* if row with same StudentId does not exist*/                    DataAccess->AddRecord(System::Int32::Parse                    (txtStudentId->get_Text()->Trim()), txtName->get_Text()->Trim(),                    txtAddress->get_Text()->Trim(), datestr, phoneNo);           }                else                {                   MessageBox(0, "Student ID already exists.","Message", 0);                    return;                }                showList();                break ;                //Update Record operation                case 2:                DataAccess->UpdateRecord(System::Int32::Parse(txtStudentId->                get_Text()->Trim()),                txtName->get_Text()->Trim(), txtAddress->get_Text()->Trim(), datestr,                System::Int32::Parse(txtPhone->get_Text()->Trim())) ;                showList();                break ;             }             txtStudentId->Clear() ;             txtName->Clear();             txtAddress->Clear();             txtPhone->Clear();             txtStudentId->set_Enabled(false);             txtName->set_Enabled(false);             txtAddress->set_Enabled(false);             txtPhone->set_Enabled(false);             dateTimeDOB->set_Enabled(false);             cmdCommit->set_Enabled(false);             groupBoxSort->set_Text("Sort By");          }          /* This method invokes when the end user selects a student record in the listViewStudent          control.*/          System::Void listViewStudent_SelectedIndexChanged(System::Object *  sender, System::EventArgs          *  e)          {             ADODB::Recordset *r;             long rows,StudentId;             txtStudentId->set_Enabled(false);             txtName->set_Enabled(false);             txtAddress->set_Enabled(false);             dateTimeDOB->set_Enabled(false);             txtPhone->set_Enabled(false);             try             {                try                {                   /* get the selected StudentId in long form in the StudentId variable. */                   StudentId=System::Int32::Parse(listViewStudent->get_SelectedItems()->                   get_Item(0)->get_Text()->Trim());                }                catch(System::Exception *){}                r=(ADODB::Recordset *)DataAccess->SearchByStudentId(StudentId);                OleDbDataAdapter *x=new OleDbDataAdapter();                DataSet *ds;                DataTable *dt;                ds=new DataSet();                dt=new DataTable();                x->Fill(ds,r,S"student");                dt=ds->Tables->get_Item(0);                int i;                rows=dt->Rows->Count;                /*Retrieving the selected information in the text boxes*/                for(i=0;i<dt->Rows->Count ;i++)                {                   DataRow *dr;                   dr=dt->Rows->get_Item(i);                   txtStudentId->set_Text(dr->get_Item(0)->ToString());                   txtName->set_Text(dr->get_Item(1)->ToString());                   txtAddress->set_Text(dr->get_Item(2)->ToString());                   dateTimeDOB->set_Text(dr->get_Item(3)->ToString());                   txtPhone->set_Text(dr->get_Item(4)->ToString());                }             }             catch(System::Exception *e)             {                MessageBox(0, e->Message->ToString(),"Error", 0);                 return;              }             // selected item list is cleared.             listViewStudent->get_SelectedItems()->Clear();          }          /* This method invokes when the end user clicks the Go button to perform search */          System::Void cmdGo_Click(System::Object *  sender, System::EventArgs *  e)          {             groupBoxSort->set_Text("Sort By");          listViewStudent->Items->Clear();          ADODB::Recordset *r;          int rows;          try          {             if(searchby==0)             /*Performing the search based on Student ID*/             r=(ADODB::Recordset             *)DataAccess->SearchByStudentId(System::Int32::Parse(txtStudentId->             get_Text()->Trim()));             else             /*Performing the search based on name*/             r=(ADODB::Recordset *)DataAccess->SearchByName(txtName->get_Text()->Trim());             OleDbDataAdapter *x=new OleDbDataAdapter();             DataSet *ds;             DataTable *dt;             ds=new DataSet();             dt=new DataTable();             x->Fill(ds,r,S"student");             dt=ds->Tables->get_Item(0);             int i;             rows=dt->Rows->Count;             /*Displaying the searched records in the listViewStudent ListView control*/             for(i=0;i<dt->Rows->Count ;i++)             {                DataRow *dr;                dr=dt->Rows->get_Item(i);                txtStudentId->set_Text(dr->get_Item(0)->ToString());                ListViewItem *tempListViewItem;                tempListViewItem=listViewStudent->Items->Add(dr->get_Item(0)->ToString());                txtName->set_Text(dr->get_Item(1)->ToString());                tempListViewItem->SubItems->Add(dr->get_Item(1)->ToString());                txtAddress->set_Text(dr->get_Item(2)->ToString());                tempListViewItem->SubItems->Add(dr->get_Item(2)->ToString());                dateTimeDOB->set_Text(dr->get_Item(3)->ToString());                tempListViewItem->SubItems->Add(dr->get_Item(3)->ToString());                txtPhone->set_Text(dr->get_Item(4)->ToString());                tempListViewItem->SubItems->Add(dr->get_Item(4)->ToString());             }          }          catch(System::Exception *e)          {             MessageBox(0, e->Message->ToString(),"Error", 0);              return;          }          if(rows==0)          MessageBox(0, "No Record found.","Message", 0);           cmdGo->set_Visible(false);          txtStudentId->set_Enabled(false);          txtName->set_Enabled(false);          cmdCommit->set_Enabled(false);          SearchorSort=0;          searchby=0;       }       /* This method invokes when the Name radio option is selected */       System::Void radioName_CheckedChanged(System::Object *  sender, System::EventArgs *  e)       {          /* 0 means sort by option is on and search option is off. */          if(SearchorSort==0)          {             showList();             listViewStudent->Items->Clear();             try             {                ADODB::Recordset *r=(ADODB::Recordset *)DataAccess->Sort(1);                OleDbDataAdapter *x=new OleDbDataAdapter();                DataSet *ds;                DataTable *dt;                ds=new DataSet();                dt=new DataTable();                x->Fill(ds,r,S"student");                dt=ds->Tables->get_Item(0);                int i;                for(i=0;i<dt->Rows->Count ;i++)                {                   DataRow *dr;                   dr=dt->Rows->get_Item(i);                   ListViewItem *tempListViewItem;                   tempListViewItem=listViewStudent->Items->Add(dr->                   get_Item(0)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(1)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(2)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(3)->ToString());                   tempListViewItem->SubItems->Add(dr->get_Item(4)->ToString());                }             }             catch(System::Exception *e)             {                MessageBox(0, e->Message->ToString(),"Error", 0);                return;             }          }          // if search option is selected.          else          {             txtStudentId->set_Enabled(false);             txtName->set_Enabled(true);             searchby=1;          }       }       System::Void onEnter(System::Object *  sender, System::Windows::Forms::KeyEventArgs *  e)       {          if(e->KeyCode==13)          cmdGo_Click(sender,e);       }    }; } 
end example

The above listing defines the following methods:

  • showList(): Calls the Sort() method of the StudentData component to retrieve the available student information from the student table. This method retrieves the student information in a DataSet object and displays the retrieved information in the listViewStudent ListView control.

  • cmdExit_Click(): Executes when an end user clicks the Exit button. This method terminates the thread in which the application is running.

  • radioStudentId_CheckedChanged(): Executes when the school authorities click the Student ID radio option to search or sort on the basis of a student ID. This method enables the txtStudentID text box to allow the school authorities to specify the student ID.

  • Student_Load(): Executes when an end user invokes the AddressBook window to work with student information. This method creates a pointer to the StudentData component to access the methods that this component provides. This method then calls the showList() method to display the student information.

  • cmdNew_Click(): Executes when an end user clicks the New button to add a student record. This method clears the content in the text boxes and sets the value of the m_oper variable to 1, which signifies that the current operation is adding a new student record to the database. The m_oper variable is a flag that stores the value of the type of operation the school authorities wants to perform.

  • cmdDelete_Click(): Executes when an end user clicks the Delete button to delete an existing student record. This method calls the DeleteRecord() method of the StudentData component.

  • cmdUpdate_Click(): Executes when an end user clicks the Update button to update an existing student record. This method sets the value of the m_oper variable to 2, which signifies that the current operation is updating a student record.

  • cmdSearch_Click(): Executes when an end user clicks the Search button to perform a search for student information. This method sets the search operation to search by student ID by setting the value of searchby variable to 0. This method also sets the value of SearchorSort variable to 1, which means the current operation is searching.

  • cmdCommit_Click(): Executes when an end user clicks the Commit button to add new student information or update existing student information depending on the value of the m_oper variable. If the value of the m_oper variable is 1, this method calls the AddRecord() method of the StudentData component. Otherwise, it calls the UpdateRecord() method of the component.

  • listViewStudent_SelectedIndexChanged(): Executes when an end user selects a record from the Student list. This method fills the text boxes according to the record selected from the list.

  • cmdGo_Click(): Executes when the end user clicks the Go button. This method performs search depending on the value of the searchby variable. If the value of the searchby variable is 0, this method calls the SearchByStudentId() method of the StudentData component. Otherwise, it calls the SearchByName() method of the component. This method then displays the records in the listViewStudent ListView control.

Figure 6-2 shows the output of Listing 6-19.

click to expand: this figure shows the addressbook window that the managed student class defines. this window allows the school authorities to access and manipulate student information.
Figure 6-2: The AddressBook Window

Creating the Form1.cpp File

The Form1.cpp file creates a new Single Thread Apartment (STA) thread to execute the application. Listing 6-20 shows the Form1.cpp file

Listing 6-20: The Form1.cpp File

start example
 #include "stdafx.h" #include "Form1.h" #include <windows.h> using namespace AddressBook; int APIENTRY_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {    System::Threading::Thread::CurrentThread->ApartmentState =    System::Threading::ApartmentState::STA;    Application::Run(new Student());    return 0; } 
end example

The above listing provides the APIENTRY_tWinMain() method that provides the starting point of the AddressBook application. This method creates a thread for executing the application and passes an instance of the managed Student class to the Run() method.




Migrating Unmanaged Applications to. NET
Migrating Unmanaged Applications to. NET
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 31

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net