Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Microsoft Visual C++ .NET Professional Projects - Premier Press

.pdf
Скачиваний:
168
Добавлен:
24.05.2014
Размер:
25.78 Mб
Скачать

210 Project 1 DATABASE PROGRAMMING USING VC++.NET

in a back-end table, you need to have a CRecordSet-based class that will create a recordset of the records in the BankLogin table. To do so, perform the following steps:

1.Choose Project, Add Class to open the Add Class dialog box. From the Templates list, select MFC ODBC Consumer. The MFC ODBC Consumer Wizard appears.

2.Click on the Data Source button toYopen the Select Data Source dialog box. Specify the data source as BankLand click on OK. If a SQL Server Login dialog box appears, log in using the appropriate username and password. F

3.In the Select Database ObjectMdialog box that appears, expand Tables, dbo. A

4.Select the BankLogin table and click on OK. This will add a CRecordSet-basedEclass to your project. You can then use this class to interact withTthe BankLogin table.

5.Click on the OK button. CBankLogin appears in the Class name box and, correspondingly, .h and .cpp files also appear in the respective boxes. Edit the class name to read CBankLoginSet. Figure 8-32 depicts the specified values.

FIGURE 8-32 The MFC ODBC Consumer Wizard

Team-Fly®

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

211

 

 

 

Two files, CBankLogin.h and CBankLogin.cpp, are added to the project. Now you have the CRecordSet-based class that can act as the interface between the Login form and the database. In this scenario, the Login form is acting as the view class.

The next task is to perform the required validation when the user clicks on the Submit button. So, you need to trap the OnBnClicked event of this button and add the required code. Perform the following steps to accomplish this:

1.Open the LoginDlg.cpp file.

2.Include the specified file:

#include “BankLoginSet.h” // For the CLoginDlg class to identify the

recordset class that is required to do the

required validation.

3.Edit the OnBnClickedOK function to add the following code. In this function, you are trapping the value entered by the user and comparing it with the values in the recordset corresponding to the BankLogin table. If the values match, then the bLoginCorrect variable is set to True. Otherwise, it is set to False.

void CLoginDlg::OnBnClickedOk()

{

// TODO: Add your control notification handler code here

CString strLoginID, strPassword; CWnd* pWnd = GetDlgItem(IDC_LOGIN); pWnd->GetWindowText(strLoginID);

GetDlgItem(IDC_PASSWORD)->GetWindowText(strPassword);

CBankLoginSet *m_pGet=new CBankLoginSet; if(!m_pGet->IsOpen ())

m_pGet->Open();

if(!m_pGet->IsBOF() && m_pGet->IsEOF()) m_pGet->MoveFirst();

CString strTemp1, strTemp2; strTemp1 = m_pGet->m_UserNm; strTemp2 = m_pGet->m_Pwd;

212 Project 1 DATABASE PROGRAMMING USING VC++.NET

while(!m_pGet->IsEOF())

{

if ( (strLoginID.CompareNoCase(strTemp1) == 0) && (strPassword.Compare(strTemp2) == 0) )

{

((CBankOperationApp*)AfxGetApp())->bLoginCorrect =

TRUE;

}

else

{

((CBankOperationApp*)AfxGetApp())->bLoginCorrect =

FALSE;

}

m_pGet->MoveNext();

}

CDialog::OnOK();

}

The explanation of the preceding code snippet follows:

Initially, two string variables are declared, strLoginID and strPassword, to store the caption of the Login ID and Password Edit Controls of the dialog box.

The GetDlgItem function is used to retrieve a pointer to the Login ID Edit control that you created in the dialog box. You need this pointer to refer to the control and retrieve the value stored in it.

The GetWindowText function is used to retrieve the caption of the control pointed to by the pWnd pointer and store it in the CString variable, strLoginID, passed as its parameter.

The next line of code combines the previous two steps. The GetDlgItem

method retrieves the pointer to the Password control, and the GetWindowText method retrieves the caption of the control and stores it in the

CString variable strPassword.

After retrieving the captions of the controls, you next need to declare a pointer to the CRecordSet-derived class, CBankLoginSet. This class stores the records of the BankLogin table and acts as an interface between

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

213

 

 

 

the database and the front-end dialog box. The m_pGet pointer is required to access the records in the recordset.

After declaring the pointer, you need to check whether the recordset is opened. You do this by using the IsOpen() method of the CRecordSet class.

If the recordset is not open, then open it by using the Open() method of

the CRecordSet class.

Once the recordset is open, you need to check whether the recordset pointer is at the beginning or the end of the file. You do this by using the IsBOF() and IsEOF() methods, respectively.

If the pointer is neither at the beginning nor at the end, then position it to point to the first record by using the MoveFirst() method of the

CRecordSet class.

You now have the recordset ready to be accessed. The next step is to retrieve the values from the Login ID and Password controls. To store these values, you need to declare two CString variables, strTemp1 and

strTemp2.

Once the values are retrieved, you need to run a loop to scan through the recordset for the existence of the values entered by the user. This loop should execute until the recordset pointer reaches the end of the file.

Within the loop, to compare the values, you need to use the CompareNo-

Case and Compare methods of the CString class. The CompareNoCase

method does a non-case-sensitive comparison, while the Compare method does a case-sensitive comparison.

If both the functions return a 0, it indicates the presence of the values entered by the user in the recordset.

If either of the functions returns a value other than 0, it indicates a failure — implying that the entered values are not found. In that case, you need to move to the next record to proceed with the search. You do this by using the MoveNext method of the CRecordSet class.

You have coded to provide the login functionality of the application. Next, you will code to provide the functionality to handle the Account_Detail form.

214 Project 1 DATABASE PROGRAMMING USING VC++.NET

Coding the Account_Detail Form

The Account_Detail form is designed as the main form because the entire banking operation revolves around customers’ accounts. Before coding the same, let me spend some time explaining the logic to be applied.

The logic behind:

When the user successfully passes through the login screen, he or she enters the Account_Detail form. This, being the main form, provides links to all operations that are typically handled in a bank.

The form provides options for navigating through the records, adding, editing, deactivating, and reactivating accounts, and for making deposits, withdrawals, and transfers.

I will discuss the logic and the code required to provide each of these functionalities and in the same sequence as they occur in the preceding list.

Navigation

The most frequently performed operation in a day would be browsing through the records of the customers’ accounts. To facilitate this, you need to provide the options to navigate to the first, next, previous, and last records. Now, I will discuss the code to provide this functionality.

1. Switch to the Resource view and open the dialog box corresponding to

IDD_BANKOPERATION_FORM.

2.Right-click the button with the caption <<. First, you will code to navigate to the first record in the recordset.

3.Choose Add Event Handler to invoke the Event Handler Wizard.

4.From the Message type list, select BN_CLICKED.

5.From the Class list, select CBankOperationView.

6.Edit the event handler’s name to OnBnClickedFirst.

7.Click on Add and Edit to add the following code:

//Code to move to the first record

void CBankOperationView::OnBnClickedFirst()

{

//Invoke the function that will fetch and display the first record in the record-

set.

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

215

 

 

 

OnRecordFirst();

//Invoke the function that will appropriately enable and disable the navigation //buttons

EnableDisableNavigationKeys(1);

}

Recall that the menu that you designed also had options to navigate from one record to another. You added these buttons to make the interface user-friendly. Clicking on a button is easier than choosing a menu option to do the same thing. However, what if the user prefers to go through the menu? To handle that situation, you use a common method that will contain the code for navigating. One such function is OnRecordFirst. To add this function, open the menu IDR_MAINFRAME. Right-click Record, First Record and choose Add Event Handler. Add the function to the view class.

TIP

Use the second list box in the code window that displays the members corresponding to the class selected in the first list.

Before adding the code for OnRecordFist() method to the CPP file, add the following declarations to the header file of the view class:

//BankOperationView.h

int m_nCurrentRecord;

The code snippet for the OnRecordFirst() method follows:

//BankOperationView.cpp

void CBankOperationView::OnRecordFirst()

{

//Moving the recordset pointer to the first record and refreshing the view m_nCurrentRecord = 1;

m_pSet->MoveFirst(); UpdateData(false);

//Disabling or Enabling of Command Buttons

CButton *bAdd,*bMod,*bDel,*bUpd;

216 Project 1 DATABASE PROGRAMMING USING VC++.NET

if(m_pSet->m_Valid_Acc==”CA”)

{

SetDlgItemText(IDC_VALID,”UnOperational Account”);

bAdd=(CButton*)GetDlgItem(IDC_ADD); bAdd->EnableWindow(false);

bUpd=(CButton*)GetDlgItem(IDC_UPD); bUpd->EnableWindow(false);

bMod=(CButton*)GetDlgItem(IDC_MOD); bMod->EnableWindow(false);

bDel=(CButton*)GetDlgItem(IDC_DELETE); bDel->EnableWindow(false);

//Disabling the check box control

CButton *chk1; chk1=(CButton*)GetDlgItem(IDC_CHECK1); chk1->SetCheck(false);

}

else

{

SetDlgItemText(IDC_VALID,”Operational Account”);

//Disabling or Enabling of Command Buttons bAdd=(CButton*)GetDlgItem(IDC_ADD); bAdd->EnableWindow(true);

bUpd=(CButton*)GetDlgItem(IDC_UPD); bUpd->EnableWindow(false);

bMod=(CButton*)GetDlgItem(IDC_MOD); bMod->EnableWindow(true);

bDel=(CButton*)GetDlgItem(IDC_DELETE); bDel->EnableWindow(true);

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

217

 

 

 

//Disabling the check box control

CButton *chk1; chk1=(CButton*)GetDlgItem(IDC_CHECK1); chk1->SetCheck(false);

}

//Setting the values of the radio buttons

CButton *pSaving,*pCurrent,*pChecking; pSaving=(CButton*)GetDlgItem(IDC_RADIO1); pCurrent=(CButton*)GetDlgItem(IDC_RADIO2); pChecking=(CButton*)GetDlgItem(IDC_RADIO3);

//Based on the type of account, enable the corresponding check box and disable //the other two.

if(m_pSet->m_Type_account==”S”)

{

pSaving->SetCheck(true); pCurrent->SetCheck(false); pChecking->SetCheck(false);

}

else if(m_pSet->m_Type_account==”C”)

{

pSaving->SetCheck(false); pCurrent->SetCheck(true); pChecking->SetCheck(false);

}

else if(m_pSet->m_Type_account==”K”)

{

pSaving->SetCheck(false); pCurrent->SetCheck(false); pChecking->SetCheck(true);

}

}

When the user navigates, you need to take care that all controls display the appropriate values. In addition, you need to ensure that the other buttons are appropriately enabled or disabled. Let me now explain what the preceding code does:

m_nCurrentRecord = 1;

218 Project 1 DATABASE PROGRAMMING USING VC++.NET

m_pSet->MoveFirst();

UpdateData(false);

The m_nCurrentRecord variable is used to track the current record. In this function, the user has chosen to move to the first record. As a result, m_nCurrentRecord is set to 1. The MoveFirst method moves the recordset pointer to the first record. The UpdateData(false) method is used to invoke the RFX mechanism that retrieves values from the recordset and displays them in the corresponding view.

CButton *bAdd,*bMod,*bDel,*bUpd;

As stated earlier, you need to disable and enable the buttons as required. To accomplish that, you need a variable to store the pointer to the corresponding controls. Here, you have declared four CButton pointer variables that will store the handlers to the Add, Modify, Deactivate, and Update buttons.

if(m_pSet->m_Valid_Acc==”CA”)

{

SetDlgItemText(IDC_VALID,”UnOperational Account”);

bAdd=(CButton*)GetDlgItem(IDC_ADD); bAdd->EnableWindow(false);

//Code for the other button controls

………………………….

………………………….

………………………….

}

Recall that an account is either operational or unoperational but it is never deleted permanently. The field Valid_Acc of the Account_Detail table stores two values, CA and VA. Here, CA indicates that the account is unoperational and VA indicates that it is valid. While retrieving the records, you need to check the value in this field and display an appropriate message in the static control, IDC_VALID, which is just below the check box control. The first line, ‘if(m_pSet- >m_Valid_Acc==“CA”)…’ checks for the previously discussed value, and if it is CA, then it sets the value of the IDC_VALID control to UnOperational Account.

Following this, the code disables or enables the command buttons (based on which ones need to be available while browsing). First, the handle to the button control is retrieved, and then, using the function EnableWindow(false), the control is disabled.

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

219

 

 

 

NOTE

When you pass false as the parameter for the EnableWindow function, it disables the corresponding control.

else

{

SetDlgItemText(IDC_VALID,”Operational Account”); //Code for the other button controls

………………………….

………………………….

………………………….

}

If the value in the variable m_Valid_Acc is VA, then the value of the IDC_VALID control is set to Operational Account. Then, the buttons are again enabled or disabled based on the requirement.

Besides the command buttons, the code also disables the check box control. In addition, the radio buttons that represent the account types are also enabled and disabled based on the type of account of the current record.

Next, you need to add the functionality for the < button. This button is used to move to the previous record. Follow the same steps that you performed for adding the functionality to move to the first record. Specify the event handler’s name as OnBnClickedPrev. Click Add and Edit to add the following code:

void CBankOperationView::OnBnClickedPrev()

{

//Invoke the function that will fetch and display the record before the current //record in the recordset.

OnRecordPrev();

//Invoke the function that will appropriately enable and disable the navigation //buttons

EnableDisableNavigationKeys(3);

}