FILE: Adovc.exe Demonstrates How to Use ADO with Visual C++
ID: q174565
|
The information in this article applies to:
-
ActiveX Data Objects (ADO), version 1.0, included with:
-
Microsoft Visual C++, 32-bit Editions, version 5.0
SUMMARY
Adovc.exe is a sample that demonstrates using ActiveX Data Objects (ADO)
within Visual C++ 5.0.
MORE INFORMATION
The following file is available for download from the Microsoft Software
Library.
Note: After you click on the following link, please choose "Save this
program to disk" from the File Download dialog box. Then, click Run on the
Start menu and run the .exe file with the -d attribute, as in the following
example:
C:\...\Adovc.exe -d
Adovc.exe
For more information about downloading files from the Microsoft Software
Library, please see the following article in the Microsoft Knowledge Base:
Q119591
How to Obtain Microsoft Support Files from Online Services
What ADOVC Demonstrates
ADOVC is a sample that demonstrates using ActiveX Data Objects (ADO) within
Visual C++ 5.0. Demonstration code for each of ADO's six classes is
presented, with some additional code for handling more common issues such
as output/return parameters and error/exception handling.
This sample actually has three separate projects, one for each of the three
techniques that can be used with ADO inside Visual C++:
- Via #import with Visual C++ 5.0
- Via MFC OLE based classes for Visual C++ 5.0/4.2.
- Via OLE SDK for Visual C++ 5.0/4.2
Three separate but nearly identical projects demonstrate each of these
techniques. The projects were written so that WinDiff could be used on each
directory. This helps identify the files that are different for each
implementation, and then makes easy comparison to see what differences in
the code each implementation imposes.
Three files in each sample contain all ADO specific code:
Adoutils.h - Contains the declaration of error/exception functions,
helper functions, and is where ADO declarations are
included in the project.
Adoutils.cpp - Implementation of error/exception and helper functions.
Adocore.cpp - Actual ADO sample code, where ADO is demonstrated.
Advantages of Using #import
- #import offers very Visual Basic-like syntax
for using ADO, easing much
of the sting of "raw" COM. This can't be stressed enough, as it greatly
simplifies referencing a specific item within a collection of a specific
object. Consider the code fragment shown below and compare it to similar
ADO coding techniques.
- _bstr_t and _variant_t both make handling BSTR and VARIANT types
relatively painless.
- Failed HRESULT results in an exception being raised. _com_error
automates the task of querying the IErrorInfo interface to acquire
details of the error.
- The gritty details of COM are hidden. That is with #import you should
never have to AddRef, QueryInterface or Release.
Disadvantages of Using #import
- Failed HRESULTS results in an exception being
raised. You can alter
this behavior as described in the following article in the Microsoft
Knowledge Base:
- Very few default arguments are provided. This
is a noticeable
difference between #import and Visual Basic (VB). With VB, optional
arguments can be left off; however, with #import and ADO, very few
defaults are actually picked up.
- #import's exception handling mechanism has a bug wherein it does not
correctly release the IErrorInfo interface when an error is raised
through or by ADO. A three line fix, implemented in the ImportErrorEx()
function is implemented, and the bug is described in detail in the
following Visual C++ Knowledge Base article:
Q173645
BUG: Access Violation in Msdaer.dll with _com_error
Exceptions
Advantages of Using MFC-OLE
An advantage of using MFC-OLE is that it hides BSTR and VARIANTS from
implementor, methods that return these types are modified so that the
actual wrapper class returns a CString.
Disadvantages of Using MFC-OLE
Here are some disadvantages of using MFC-OLE:
- HRESULTS are hidden and not returned by
wrappers around methods.
- Unlike #import and the headers provided for OLE-SDK, MFC-OLE does not
read the typelib to provide values for the enumerated types defined
there. This is best demonstrated in Adoutils.h, where three enums
used by the helper functions are manually defined.
- No ability to pass a license key [without overriding
CreateDispatch()]
for ADO 1.0 users. With ADO 1.5, MFC-OLE works just fine; however, with
ADO 1.0, you must override two of the CreateDispatch() methods of the
COleDispatchDriver class. This is demonstrated in the sample in the
_Connection class.
- Wrappers derived from COleDispatchDriver do not return HRESULTS. It is
possible to receive failed HRESULTS bundled inside a ColeDispatchDriver
exception, but there are scenarios where HRESULTS may not be received.
It is also important that the exception handling, if it uses the
Connection object's Errors collection, not process this collection
unless you have a valid connection object. Otherwise it may be possible
to generate exceptions within your exception handler.
Advantages of Using OLE-SDK
- The bulk of the ADO samples that come with
the OLE-DB SDK are written
using raw OLE-SDK. The Adoid.h and Adoint.h files provide much of
the kind of information #import generates off the typelib, only without
the helpful wrapper classes or advanced bstr/variant handling, as well
as automatically processing information from IErrorInfo.
Disadvantages of Using OLE-SDK
Here are some disadvantages of using OLE-SDK:
- Requires more coding, especially managing
BSTR and VARIANT types.
- The actual sample code uses MFC classes, COleVarient and CString, to
facilitate coding. A pure OLE-SDK application would not take advantage
of the CString::AllocSysString() method. (However, if you don't want to
use CString, this method's source is an excellent place to get a handy
helper function to convert between char* and BSTR).
#import and the Advantage of "VB-Like Syntax"
Consider the following three code fragments to get the ActualSize property
of a Field object, starting from the Recordset object:
// #import
CString strTmp;
strTmp.Format( "\t\t...Actual Size = %ld",
Rs1->Fields->Item[_variant_t((long)0)]->ActualSize );
One line of code to go from Recordset to the ActualSize property. Now
consider MFC-OLE:
// MFC-OLE
CString strTmp;
Fields Flds1
Field Fld1;
Flds1 = Rs1.GetFields();
Fld1 = Flds1.GetItem( COleVariant( (long) 0 ) );
strTmp.Format( "\t\t...Actual Size = %ld", Fld1.GetActualSize );
Finally, consider the OLE-SDK equivalent code, which is nearly the same
size as MFC-OLE, but gives more immediate error handling results than MFC-
OLE is capable of.
// OLE-SDK with ADOID.H and ADOINT.H
CString strTmp;
ADOFields* Flds1 = NULL;
ADOField* Fld1 = NULL;
long nTmp;
if( SUCCEEDED ( hr ) ) hr = Rs1->get_Fields( & Flds1 );
if( SUCCEEDED ( hr ) ) hr = Flds1->get_Item( COleVariant((long) 0 ),
&Fld1 );
if( SUCCEEDED ( hr ) ) hr = Fld1->get_ActualSize( &nTmp );
if( SUCCEEDED ( hr ) ) strTmp.Format( "\t\t...Actual Size = %ld",
nTmp );
#import vs. COleDispatchDriver vs. OLE SDK
Based on the three projects in this sample, the recommended preference for
using ADO in Visual C++ follows:
- #import because it dramatically simplifies
using COM
- OLE SDK because you get back HRESULTS that are otherwise buried in
MFC-
OLE (when OLE SDK breaks, you know it)
- MFC-OLE, despite being an intermediate step towards #import, hides
too
much when it doesn't give you back a failed HRESULT
Other Tips for Using VC and ADO
- When in doubt, use adCmdUnknown for options,
especially for either
Execute or Open methods. ADO will determine the correct option,
whereas using adCmdText to open a stored procedure may cause problems
(especially if trying to auto-fill the Parameters Collection).
- Use vtEmpty and bstrEmpty for arguments that would otherwise be
optional in Visual Basic.
- Catch exceptions. In this case, modified versions of the helper
routines provided from the ExceptEx sample were used to trap and
log any exceptions raised by ADO or by the mechanisms used to
manipulate ADO.
For additional information, please see the following article in the
Microsoft Knowledge Base:
Q167802
SAMPLE: EXCEPTEX Traps MFC and Win32 Structured
Exceptions
- In this case, to manage a list box with a horizontal scroll bar, the
CHorzListBox class was utilized as described in the following article
in the Microsoft Knowledge Base:
Q146437
SAMPLE: Horizontal Scrolling List Box in an MFC Class
- Cracking Variants into something reasonable can be time-consuming.
Embedded in multiple locations within MFC, and even various samples,
is code to decipher a variant into a conventional type, such as CString.
The definitive helper, though, ships with the DAOVIEW sample in
Visual C++ 4.X/5.0 and its method: CCrack::strvariant. This method
has been extracted from DAOVIEW and included with all three versions
of the ADOVC projects as the function CrackStrVariant().
About the ADO* Series of Samples
This is one of several identical samples implemented using ADO within
various products, as listed below. The advantage is that these articles
have an identical interface/functionality, demonstrating both the
similarities differences in using ADO with different languages and with
different mechanisms within that language (where applicable).
QNumber Title Q172403 FILE: Adovb.exe Demonstrates How to Use ADO with Visual Basic
Q174565 FILE: Adovc.exe Demonstrates How to Use ADO with Visual C++
Q182782 FILE: Adovj.exe Demonstrates How to Use ADO with Visual J++
Q185033 FILE: Adoacc.exe Demonstrates Using ADO with Access 97
Other Knowledge Base Articles of Note
These articles provide detailed information not covered in this text about
using ADO with various Visual C++ implementation mechanisms.
QNumber Title Q169496 INFO: Using ActiveX
Data Objects (ADO) via #import in VC++
Q175993 INFO: Using ActiveX
Data Objects (ADO) via MFC OLE in VC++
Q176342 INFO: Using ActiveX
Data Objects (ADO) via OLE SDK in VC++
ADO Version 1.5
At the time of the writing of this sample, ADO 1.5 was not yet released,
but was available publicly in beta. This sample has been written to work
with either version, but there are some differences:
- Most notably that version 1.5 requires an
extra argument which must be -
1 for Open and Execute methods.
- Code specific to 1.0 or 1.5 has a single line comment preceding it,
as shown below:
// ADO 1.0 Version
Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty );
// ADO 1.5 Version
// Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty, -1 );
- The MFCOLE sample requires you to remove Msado10.h and Msado15.cpp
from the project, and add the already created Msado15.h and Msado15.cpp
files.
- The OLE-SDK sample will require you to have the OLE-DB 1.5 SDK, and
more importantly the Adoid.h and Adoint.h files that will be included
with that SDK. As of beta1 for that SDK, these files were not
available, but they will be included with Beta2 as well as the final
release of the OLE-DB SDK.
Additional query words:
Keywords : kbsample kbADO kbVC
Version : WINDOWS:1.0
Platform : WINDOWS
Issue type :
|