需要注意的是#import的no_namespace屬性,它告訴編譯器該類在不在一個單獨的名字空間中。使用no_namespace意味着不需要在初始化變量時引用名字空間。當然如果在應用中需要導入多個類型庫時,最好不要使用no_namespace,以免引起名字衝突
下面是一個簡單的採用了#import方法的基於ADO應用的示例代碼: |
#import <msado15.dll> rename(“EOF”, “adoEOF”) |
//因爲沒有在#import中指定no_namespace,所以必須採用ADODB::這樣的形式來定義變量類型 |
ADODB::_RecordsetPtr Rs1 = NULL; |
_bstr_t Connect( “DSN=AdoDemo;UID=sa;PWD=;” ); |
_bstr_t Source ( “SELECT * FROM Authors” ); |
hr = Rs1.CreateInstance( __uuidof( ADODB::Recordset ) ); |
ADODB::adOpenForwardOnly, |
::MessageBox( NULL,“Success!”,“”,MB_OK ); |
MFC OLE同樣能夠封裝(wrapper)一個類型庫,但是與#import不同,它不能從類型庫中產生枚舉類型。MFC類CString和COleVariant隱藏了BSTRS和Variants的細節。由MFC OLE產生的類都繼承了類ColeDispatchDriver,由ADO產生的失敗的HRESULTS被封裝在類ColeDispatchException中。 |
用MFC OLE ClassWizard創建ADO應用的步驟如下: |
●從Tools菜單中,選擇Options選項中的Directories tab條目,在Show Directories中的Library Files中增加路徑C:/program files/common files/system/ado,設置包含ADO類型庫的路徑。 |
●從View菜單中,激活ClassWizard,點擊Add Class按鈕並選擇“From A Type Library...”選項,然後在Type Library dialog box對話框中,從C:/program files/common files/system/ado中選擇文件msado15.dll,在Confirm Classes對話框中,選擇所有列出的類並按OK按鈕退出ClassWizard。這樣,ClassWizard便生成了兩個文件msado15.h和msado15.cpp。 |
COleVariant Connect( “DSN=AdoDemo;UID=sa;PWD=;” ); |
COleVariant Source ( “SELECT * FROM Authors” ); |
Rs1.CreateDispatch(“ADODB.Recordset.2.0”,&e ); |
Rs1.Open( (VARIANT) Source, |
AfxMessageBox(“Success!”); |
#import和MFC OLE都圍繞着一個給定的自動化對象產生了一個封裝類,它們分別繼承自_com_ptr_t和ColeDispatchDriver。其實也可以通過使用Windows API函數直接初始化ADO對象。爲了直接使用ADO和COM對象,需要添加兩個頭文件adoid.h和adoint.h,這兩個頭文件定義了CLSIDs、接口定義和操作ADO類型庫所需要的枚舉類型。此外,還需要增加頭文件INITGUID.H。 |
爲了能夠編譯用COM API創建的ADO工程文件,還需要在機器中安裝OLE DB SDK或者是MSDASDK工具。下面是利用API創建ADO的簡單的示例代碼: |
#include “adoid.h” // ADO的GUID's |
#include “adoint.h” // ADO的類、枚舉等等 |
// ADORecordset 是在adoint.h中定義的 |
ADORecordset* Rs1 = NULL; |
Source.bstrVal = ::SysAllocString( L“SELECT * FROM Authors”); |
Connect.bstrVal = ::SysAllocString( L“DSN=AdoDemo;UID=sa;PWD=;” ); |
hr = CoCreateInstance( CLSID_CADORecordset, |
if( SUCCEEDED( hr ) ) hr = Rs1->Open |
if( SUCCEEDED( hr ) ) hr = Rs1->Close(); |
if( SUCCEEDED( hr ) ) { Rs1->Release(); Rs1 = NULL; } |
if( SUCCEEDED( hr ) ) ::MessageBox( NULL, “Success!”, “”, MB_OK ); |
如果用C++進行ADO應用程序開發,應該使用ADO C++ Extensions。我們知道,用VB或者VBScript來操作ADO是非常方便的,但是如果使用C++或者是Java,就必須要處理類似Variants這樣的數據結構以實現和C++數據結構的轉換,而這種處理無疑是所有C++開發人員都很頭疼的事情。但如果使用C++ Extensions的話,ADO就不需要從數據提供者處得到列信息,而是在設計時刻使用開發人員提供的列信息。以下是一個簡單的示例: |
class CAuthor : public CADORecordBinding |
BEGIN_ADO_BINDING(CCustomRs1) |
ADO_VARIABLE_LENGTH_ENTRY4(1, |
adVarChar, m_szau_id, sizeof(m_szau_id), FALSE) |
ADO_VARIABLE_LENGTH_ENTRY4(2, |
adVarChar,m_szau_fname,sizeof(m_szau_fname), FALSE) |
ADO_VARIABLE_LENGTH_ENTRY4(3, |
adVarChar,m_szau_lname,sizeof(m_szau_lname), FALSE) |
IADORecordBinding *piAdoRecordBinding; |
pRs.CreateInstance(__uuidof(Recordset)); |
pRs->Open(“select au_id,au_fname,au_lname from Employees”,“Provider=SQLOLEDB;Data Source=sureshk1;Database=pubs;User Id=sa;Password=;”, |
pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&piAdoRecordBinding); |
piAdoRecordBinding->BindToRecordset(&author); |
while (VARIANT_FALSE == pRs->EOF) { |
printf(“%s %s %s”, author.m_szau_id, |
author.m_szau_fname, author.m_szau_lname); |
piAdoRecordBinding->Release(); |
|