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

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

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

260 Project 1 DATABASE PROGRAMMING USING VC++.NET

m_pGet->MoveFirst();

}

}

else if(ptr_Tran->m_Transaction_Mode.CompareNoCase(“TRF”) == 0)

//Case of money transfer from one account to another

{

//Transfer to an internal account

 

 

 

 

Y

if (ptr_Tran->m_Transaction Type.CompareNoCase(“ITF”) == 0)

{

 

 

L

 

 

 

F

 

long lAccNumFrom = ptr Tran->m_Account_Number;

 

while (!m_pGet->IsEO ())

 

{

 

M

 

 

 

 

 

 

 

if (m pGet->m Account_Number == ptr_Tran-

 

 

>m ccount Number)

E

 

 

 

{

 

 

T

m pGet->Edit();

 

 

Am pGet->m_Balance=m_pGet->m_Balance - ptr_Tran-

>m_Transaction_Amount; m_pGet->Update(); m_pGet->Requery();

if (bFirstTransactionOver)

{

ptr_Tran->Edit(); ptr_Tran->m_Transaction_Status = “C”; ptr_Tran->Update(); ptr_Tran->Requery();

break;

}

bFirstTransactionOver = TRUE;

}

if (m_pGet->m_Account_Number == ptr_Tran->m_To_Account)

{

m_pGet->Edit(); m_pGet->m_Balance=m_pGet->m_Balance + ptr_Tran->m_Transaction_Amount;

m_pGet->Update(); m_pGet->Requery();

if (bFirstTransactionOver)

{

Team-Fly®

IMPLEMENTING DATA ACCESS TECHNOLOGIES

Chapter 8

261

 

 

 

ptr_Tran->Edit(); ptr_Tran->m_Transaction_Status = “C”; ptr_Tran->Update(); ptr_Tran->Requery();

break;

}

bFirstTransactionOver = TRUE;

}

m_pGet->MoveNext();

}

m_pGet->MoveFirst();

}

else if (ptr_Tran->m_Transaction_Type.CompareNoCase(“ETF”) == 0)

{

//Transfer to an External account

long lAccNumFrom = ptr_Tran->m_Account_Number; while (!m_pGet->IsEOF())

{

if (m_pGet->m_Account_Number == ptr_Tran->m_Account_Number)

{

m_pGet->Edit(); m_pGet->m_Balance=m_pGet->m_Balance - ptr_Tran-

>m_Transaction_Amount; m_pGet->Update();

m_pGet->Requery(); ptr_Tran->Edit();

ptr_Tran->m_Transaction_Status = “C”; ptr_Tran->Update(); ptr_Tran->Requery();

break;

}

m_pGet->MoveNext();

}

m_pGet->MoveFirst();

}

}

bFirstTransactionOver = FALSE;

262 Project 1 DATABASE PROGRAMMING USING VC++.NET

}

ptr_Tran->MoveNext();

}

if (ptr_Tran) //Contains Transaction Details delete ptr_Tran;

if (m_pGet) //Contains Transaction Details delete m_pGet;

//Refresh the records m_bFromCommit = TRUE; OnInitialUpdate();

MessageBox(“All pending transactions have been commited”);

}

You have learned to implement the various functionalities of the banking application using MFC ODBC classes.

Summary

In Chapter 7, you learned about the basics of database connectivity concepts. In this chapter, you learned to implement the same concepts. You learned to create an MFC-based application with database connectivity. The database connectivity was done through ODBC classes. In the next chapter, you will learn the basics of debugging.

Chapter 9

Debugging and

Exception

Handling in

VC++.NET

One of the critical phases of project development is the testing phase. Why so? Any thoughts? Well, creating a project is a challenge, but a bigger challenge is creating a bug-free and robust application. Recall those days when you had just

started to create small projects. Weren’t those days terrible? If you took, say, five days to create a project, you took at least two days to debug it and make it work the way you wanted it to. For those who don’t agree with me with the above-stated fact, and who are already gurus in handling bugs and creating first-rate applications, this chapter might not be for you. For the rest of you, don’t fret! What fun is programming without debugging? The more you debug an application, the stronger your understanding of the language becomes. So, go ahead and get the best out of this chapter!

The chapter begins with an introduction to exceptions, proceeds to explain how to handle exceptions in an MFC application, and then deals with basics of debugging and demonstrates the use of different debugging windows.

Exception Handling in MFC Applications

Although debugging remains the same across managed and unmanaged applications, the process of exception handling differs in both. However, there are some basic concepts related to exceptions that are common across managed and unmanaged applications. To begin with, you will learn those basic concepts, and then proceed to learn how an exception is handled in an MFC application. In Chapter 10, you will learn how exceptions are handled in a managed application.

Exception Basics

Think for a while and recall how often some of your best-laid plans have not worked out because of unexpected problems. This is true not only in our real lives, but also in the work that we do. It should not surprise you if any part of your application, which you developed after a detailed analysis and design, ends up with some unexpected problems when you finally execute it. Such unexpected bugs that cause abnormal behavior of your application are referred to as exceptions.

DEBUGGING AND EXCEPTION HANDLING IN VC++.NET

Chapter 9

 

265

 

 

 

 

 

You likely have come across such situations a number of times. One simple example that you can easily relate to is entering text values for a numeric variable. If your application is not prepared to handle such exceptions, then it can terminate abnormally any time.

Before getting deep into exception handling, you need to spend some time understanding how to determine the need for exception handling. When do you need to handle exceptions? Well, this is based on what the outcome of a specific function is in a program. Broadly, the result of a function call can be classified into any of three categories:

Normal execution. Normal execution occurs when a called function executes successfully and returns control back to the caller function. The called function may return some values indicating the result of the execution to the caller. The return value is predefined in the function and can represent a successful execution or a failure. One traditional approach is to return a 0 in case of success and –1 in case of failure.

Erroneous execution. While calling a function, there are chances for passing wrong values to the parameters of the called function. To handle such errors, you need to use assertion while developing the program.

Abnormal execution. Despite all preventive measures, inevitably, you do fall sick! Similarly, despite you trapping all possible errors, sometimes your application terminates due to reasons that are out of your application’s scope, such as memory problems. The best way (probably the only way) to handle such situations is to use exception handling.

From the preceding list, you can easily conclude that exception handling is used to handle situations that are not within your application’s reach. It is extremely important to handle such situations so that you can avoid abnormal termination of your application.

In MFC, you can handle exceptions using either the C++ exceptions or the MFC exceptions macros. The subsequent sections detail each of these methods.

C++ Exceptions

Exception handling is not an alien concept for programmers. The traditional programs used the omnipresent if-then-else construct for handling exceptions. The introduction of try, catch, and throw statements in C++ brought a sigh of relief from programmers. Exception handling suddenly became easier and more flexible

266 Project 1 DATABASE PROGRAMMING USING VC++.NET

than it was earlier. The biggest factor contributing to the flexibility of exception handling in C++ is its ability to handle exceptions of varied types. Following is a description of how the try, catch, and throw statements help in exception handling:

The try statement is used to chunk the statements that are expected to result in an exception. The try statement followed by the code together is referred to as the try block.

The throw statement is used to raise an exception from within the try block when any code segment generates an unexpected result.

The catch statement is used to assign an exception handler for each type of exception that can occur in the application.

Here’s how the control flows in an application that implements exception handling using the try, catch, and throw statements:

The control flows sequentially and reaches the try block. The code within the try block is executed as specified.

If the trapped error does not occur, then no exception is thrown; hence, the catch statement is not executed. The control from the try block is then transferred to the statement after the last catch clause following this try block.

If the trapped error is encountered and the throw statement throws an exception, then the control is transferred to the corresponding catch block. One try block can have multiple catch handlers; hence, the appropriate handler is searched for and the control is passed on.

MFC Exceptions

The same concept of try, catch, and throw is implemented in MFC. To accomplish this, MFC provides a number of predefined exception classes. The base class for all of these exception classes is the CException class. Table 9-1 lists some of the exception handling classes.

DEBUGGING AND EXCEPTION HANDLING IN VC++.NET

Chapter 9

 

267

 

 

 

 

 

Table 9-1 MFC Exception Handling Classes

Exception Class

Used to

CMemoryException

Handle memory-related exceptions

CFileException

Handle file-related exceptions

CArchiveException

Handle archiveand serialization-specific exceptions

CDBException

Handle database-related exceptions specific to ODBC classes

CDaoException

Handle database-related exceptions involving DAO classes

 

 

You will next learn to use one of the classes listed in Table 9-1, CDBException. To do so, you can use the banking application that you created in Chapter 8 or create a fresh application with ODBC support. Edit the OnGetRecordSet method of the RecordView class and add the following code snippet:

CRecordSet* CMyRecordView::OnGetRecordset()

{

if (m_pSet !=NULL) return m_pSet;

m_pSet=new CMyRecordSet (NULL); try

{

m_pSet->Open();

// The Open member function throws a CDBException

}

catch(CDBException* e)

{

AfxMessageBox(e->m_strError); //m_strError stores the error description

delete m_pSet; m_pSet=NULL.

}

}

Try executing this application and see the result.

Apart from the exception classes, MFC also provides two macros that can be used in exception handling:

268Project 1 DATABASE PROGRAMMING USING VC++.NET

The ASSERT macro. This macro enables you to identify errors while you develop an application. The macro accepts an argument, which typically is an expression. If the expression evaluates to false (0), then an Assertion box is displayed by the macro. The Assertion box displays an alert message to the user and then halts the program. On the other hand, if the expression evaluates to true (1), then no alerts are displayed. The Assertion Failure box is similar to the ones that you saw when you worked with the breakpoints. If you click Abort, program execution is terminated; if you click Ignore, program execution continues after ignoring the cause of the error; and if you choose Retry, the application enters break mode. The following is a sample code snippet illustrating how to use the ASSERT macro:

int x = Calculate();

ASSERT(x==0);

CAUTION

The ASSERT macro works only in the Debug version of a project and not in the

Release version.

The TRACE macro. This macro enables you to display messages in the debug window, which is the Output window, while your program is in break mode.

You are now aware of handling exceptions in an MFC application. You, as a programmer, would definitely agree with the fact that not all bugs can be caught as exceptions. What is the way out, then? The only possible solution is to debug your application. In the following sections, you will get to know the what and why of debugging and also learn to work with Visual Studio .NET’s debugger windows.

Debugging VC++.NET Applications

What is debugging? To answer this question, you must first know what are bugs. Bugs are errors in programs that result in erroneous or unexpected output. The process of tracing and removing bugs is termed debugging. Before delving directly into the intricacies of debugging, it’s important to get a hang of the basic concepts

DEBUGGING AND EXCEPTION HANDLING IN VC++.NET

Chapter 9

 

269

 

 

 

 

 

of debugging. These basic concepts are the same irrespective of whether you are working with MFC applications, which use unmanaged code, or working with pure VC++.NET applications, which use managed code.

Basics of Debugging

Errors or bugs can be broadly categorized into three categories:

Syntax errors. All programming languages have a predefined set of rules that define the syntax of the language. The errors that result due to violation of syntax are called syntax errors. Consider the following code snippet in Visual C++:

CRecordSet *m_pSet;

m_pSet.Open();

In the preceding code snippet, m_pSet is declared as a CRecordSet pointer variable. In the second line, m_pSet is used to invoke the Open member function of the CRecordSet class. When you compile this code in Visual Studio .NET , the compiler displays the following error in the Output window:

d:\Temp\Debug1\Debug1View.cpp(44): error C2228: left of

‘.Open’ must have class/struct/union type

The error message specifies the location of the error and the error description. In the preceding code, d:\Temp\Debug1\Debug1View.cpp (44) is the location of the error, which indicates that the error is in line number 44 of the Debug1View.cpp file; and error C2228: left of

‘.Open’ must have class/struct/union type is the error description,

which implies that you need to use a class-, structure-, or union-type variable to invoke the Open function, because you have used the “.” operator. However, because m_pSet is a pointer variable, as per the syntax, you need to use the “->” operator to access any of the methods or properties of a class. This is a clear violation of the syntax; hence, the compiler reports a syntax error. Concisely, any violation of syntax of a language will result in syntax errors, and are pointed out by the compiler or the interpreter of that language.

Semantic errors. With experience, you do grasp the syntax of the language. However, despite following the syntax, sometimes certain code causes the program to crash or misbehave. Such errors are classified as