📄 s15_03.cpp
字号:
// S15_03.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "HandleResult.h"
BOOL g_bPrompt; // 是否提示用户选择数据源
#define MAX_NAME_LEN 255 // 表名字符串的最大长度
#define MAX_COL_SIZE 5000 // 列的最大字节数
#define MAX_ROWS 1 // 每次取的最大行数
#define MAX_DISPLAY_SIZE 20 //
#define MIN_DISPLAY_SIZE 3 //
// OLE DB ODBC提供程序的CLSID
extern const MSDASQLDECLSPEC GUID CLSID_MSDASQL = {0xC8B522CBL,0x5CF3,0x11CE,{0xAD,0xE5,0x00,0xAA,0x00,0x44,0x77,0x3D}};
// 创建数据源对象.
HRESULT CreateDataSource(IUnknown **ppUnkDataSource);
// 初始化数据源对象.
HRESULT DoInitialization(IUnknown *pIUnknown);
// 初始化单个属性结构DBPROP.
void AddProperty(DBPROP *pProp, DBPROPID dwPropertyID, VARIANT vValue,
DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED,
DBID colid = DB_NULLID);
void AddProperty(DBPROP* pProp, DBPROPID dwPropertyID, VARTYPE vtType = VT_BOOL,
LONG lValue = VARIANT_TRUE, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_OPTIONAL);
// 获取指定属性的BOOL值.
HRESULT GetProperty(IUnknown *pIUnknown, REFIID riid, DBPROPID dwPropertyID,
REFGUID guidPropertySet, BOOL *pbValue );
// 提示用户输入字符串.
BOOL GetInputFromUser(LPWSTR pwszInput, LPCWSTR pwszFmt, ... );
// 创建一个OLE DB会话对象(从指定的数据源对象).
HRESULT CreateSession( IUnknown *pUnkDataSource, IUnknown **ppUnkSession);
// 由会话对象创建一个行集对象.
HRESULT CreateRowset(IUnknown *pUnkSession, IUnknown **ppUnkRowset);
// 设置行集属性.
void AddRowsetProperties(DBPROPSET *pPropSet, ULONG cProperties, DBPROP *rgProperties);
// 创建架构行集对象.
HRESULT CreateSchemaRowset(GUID guidSchema, IUnknown *pUnkSession,
ULONG cchBuffer, LPWSTR pwszBuffer);
// 显示行集数据.
HRESULT DisplayRowset(IUnknown* pUnkRowset, LPCWSTR pwszColToReturn,
ULONG cchBuffer, LPWSTR pwszBuffer);
// 显示表的列名.
HRESULT DisplayColumnNames(IUnknown* pUnkRowset, ULONG* rgDispSize);
HRESULT FindColumn(IUnknown * pUnkRowset, LPCWSTR pwszName, LONG* plIndex);
// 显示行集行数据.
HRESULT DisplayRow(ULONG iRow, ULONG cBindings, DBBINDING* rgBindings,
void* pData, ULONG * rgDispSize);
// 更新显示尺寸.
HRESULT UpdateDisplaySize(ULONG cBindings, DBBINDING* rgBindings,
void* pData, ULONG* rgDispSize);
// 设置绑定数据结构.
HRESULT SetupBindings(IUnknown *pUnkRowset, ULONG *pcBindings,
DBBINDING **prgBindings, ULONG *pcbRowSize );
// 释放绑定数据结构.
void FreeBindings(ULONG cBindings, DBBINDING* rgBindings);
// 试图从会话对象创建一个命令对话.
HRESULT CreateCommand(IUnknown *pUnkSession, IUnknown **ppUnkCommand);
// 执行命令, 并创建相应的行集对象.
HRESULT ExecuteCommand(IUnknown* pUnkCommand, WCHAR* pwszCommandText,
ULONG cPropSets, DBPROPSET* rgPropSets, IUnknown** ppUnkRowset);
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = NULL;
IUnknown* pUnkDataSource = NULL;
IUnknown* pUnkSession = NULL;
IUnknown* pUnkRowset = NULL;
//初始化COM库.
CoInitialize(NULL);
g_bPrompt = FALSE;
// 创建并初始化数据源对象.
XCHECK_HR(hr = CreateDataSource(&pUnkDataSource));
// 创建会话对象.
XCHECK_HR(hr = CreateSession(pUnkDataSource, &pUnkSession));
// 创建行集对象.
XCHECK_HR(hr = CreateRowset(pUnkSession, &pUnkRowset));
// 显示行集对象数据.
CHECK_HR(hr = DisplayRowset(pUnkRowset, NULL, 0, NULL));
CLEANUP:
if( pUnkDataSource ) pUnkDataSource->Release();
if( pUnkSession ) pUnkSession->Release();
if( pUnkRowset ) pUnkRowset->Release();
//清除COM库.
CoUninitialize();
return 0;
}
HRESULT CreateDataSource(IUnknown ** ppUnkDataSource)
{
HRESULT hr;
IDataInitialize * pIDataInitialize = NULL;
IDBPromptInitialize * pIDBPromptInitialize = NULL;
IDBInitialize * pIDBInitialize = NULL;
CLSID clsid = CLSID_MSDASQL;
//使用数据连接(Data Links)用户界面, 提示用户选择一个连接的提供程序.
if( g_bPrompt )
{
//创建数据连接组件对象, 并获取它的IDBPromptInitialize接口.
XCHECK_HR(hr = CoCreateInstance(
CLSID_DataLinks, // clsid--Data Links UI
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER, // dwClsContext
IID_IDBPromptInitialize, // riid
(void**)&pIDBPromptInitialize)); // ppvObj
//提示用户选择一个要创建的数据提供程序.
XCHECK_HR(hr = pIDBPromptInitialize->PromptDataSource(
NULL, // pUnkOuter
GetDesktopWindow(), // hWndParent
DBPROMPTOPTIONS_PROPERTYSHEET, // dwPromptOptions
0, // cSourceTypeFilter
NULL, // rgSourceTypeFilter
NULL, // pwszszzProviderFilter
IID_IDBInitialize, // riid
(IUnknown**)&pIDBInitialize)); // ppDataSource
// 已经从数据连接对象获取了数据提供程序数据源对象.
// 这个对象已经包含有初始化属性集, 于是我们可以直接对其初始化.
XCHECK_HR(hr = pIDBInitialize->Initialize());
}
//不使用数据连接组件, 而直接创建OLE DB ODBC提供程序数据源对象.
else
{
// 创建OLE DB ODBC提供程序数据源对象.
XCHECK_HR(hr = CoCreateInstance(
CLSID_MSDASQL, // clsid--provider
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER, // dwClsContext
IID_IDBInitialize, // riid
(LPVOID*)&pIDBInitialize)); // ppDataSource
// 初始化数据源对象.
CHECK_HR(hr = DoInitialization(pIDBInitialize));
}
CLEANUP:
*ppUnkDataSource = pIDBInitialize;
if( pIDataInitialize )
pIDataInitialize->Release();
if( pIDBPromptInitialize )
pIDBPromptInitialize->Release();
return hr;
}
HRESULT DoInitialization(IUnknown* pIUnknown)
{
HRESULT hr;
IDBInitialize * pIDBInitialize = NULL;
IDBProperties * pIDBProperties = NULL;
HWND hWnd = GetDesktopWindow();
//const ULONG cProperties = 2;
const ULONG cProperties = 4;
DBPROP rgProperties[cProperties];
DBPROPSET rgPropSets[1];
VARIANT vValue;
// 设置初始化属性.
// 提示用户提供所需的初始化属性.
//vValue.vt = VT_I2; vValue.lVal = DBPROMPT_COMPLETE;
//AddProperty(&rgProperties[0], DBPROP_INIT_PROMPT, vValue );
//vValue.vt = VT_I4; vValue.lVal = (LONG)hWnd;
//AddProperty(&rgProperties[1], DBPROP_INIT_HWND, vValue);
// 直接指定初始化属性, 而不提示用户.
// 指定不提示用户选择初始化属性.
vValue.vt = VT_I2; vValue.lVal = DBPROMPT_NOPROMPT;
AddProperty(&rgProperties[0], DBPROP_INIT_PROMPT, vValue);
// 提定用户名.
vValue.vt = VT_BSTR; vValue.bstrVal=SysAllocString((LPOLESTR)L"");
AddProperty(&rgProperties[1], DBPROP_AUTH_USERID, vValue);
// 指定用户口令.
vValue.vt = VT_BSTR; vValue.bstrVal=SysAllocString((LPOLESTR)L"");
AddProperty(&rgProperties[2], DBPROP_AUTH_PASSWORD, vValue);
// 指定数据源名称.
vValue.vt = VT_BSTR; vValue.bstrVal=SysAllocString((LPOLESTR)L"ENorthwind");
AddProperty(&rgProperties[3], DBPROP_INIT_DATASOURCE, vValue);
rgPropSets[0].rgProperties = rgProperties;
rgPropSets[0].cProperties = cProperties;
rgPropSets[0].guidPropertySet = DBPROPSET_DBINIT;
// 获取设置属性的接口: IDBProperties.
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBProperties,
(void**)&pIDBProperties));
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBInitialize,
(void**)&pIDBInitialize));
// 设置初始化属性.
XCHECK_HR(hr = pIDBProperties->SetProperties(1, rgPropSets));
// 初始化数据源对象..
XCHECK_HR(hr = pIDBInitialize->Initialize());
CLEANUP:
if( pIDBProperties )
pIDBProperties->Release();
if( pIDBInitialize )
pIDBInitialize->Release();
return hr;
}
/////////////////////////////////////////////////////////////////
// 函数: AddProperty
//
// 这个函数初始化属性结构(DBPROP)pProp.
//
////////////////////////////////////////////////////////////////
void AddProperty(DBPROP * pProp,
DBPROPID dwPropertyID,
VARIANT vValue,
DBPROPOPTIONS dwOptions,
DBID colid)
{
pProp->dwPropertyID = dwPropertyID;
pProp->dwOptions = dwOptions;
pProp->dwStatus = DBPROPSTATUS_OK;
pProp->colid = DB_NULLID;
pProp->vValue = vValue;
}
void AddProperty(DBPROP * pProp,
DBPROPID dwPropertyID,
VARTYPE vtType,
LONG lValue,
DBPROPOPTIONS dwOptions )
{
// Set up the property structure.
pProp->dwPropertyID = dwPropertyID;
pProp->dwOptions = dwOptions;
pProp->dwStatus = DBPROPSTATUS_OK;
pProp->colid = DB_NULLID;
V_VT(&pProp->vValue) = vtType;
// Since VARIANT data is a union, we can place the value in any
// member (except for VT_DECIMAL, which is a union with the whole
// VARIANT structure -- but we know we're not passing VT_DECIMAL).
V_I4(&pProp->vValue) = lValue;
}
/////////////////////////////////////////////////////////////////
// 函数: GetProperty
//
// 这个函数获取指定属性的BOOL值, 并将结果放在*pbValue中.
//
/////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown * pIUnknown,
REFIID riid,
DBPROPID dwPropertyID,
REFGUID guidPropertySet,
BOOL * pbValue )
{
HRESULT hr;
DBPROPID rgPropertyIDs[1];
DBPROPIDSET rgPropertyIDSets[1];
ULONG cPropSets = 0;
DBPROPSET * rgPropSets = NULL;
IDBProperties * pIDBProperties = NULL;
ISessionProperties * pISesProps = NULL;
ICommandProperties * pICmdProps = NULL;
IRowsetInfo * pIRowsetInfo = NULL;
// 初始化输出值.
*pbValue = FALSE;
// 设置属性ID数组.
rgPropertyIDs[0] = dwPropertyID;
// 设置属性ID集.
rgPropertyIDSets[0].rgPropertyIDs = rgPropertyIDs;
rgPropertyIDSets[0].cPropertyIDs = 1;
rgPropertyIDSets[0].guidPropertySet = guidPropertySet;
// 从提供程序获取指定属性的属性值.
if( riid == IID_IDBProperties )
{
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBProperties,
(void**)&pIDBProperties));
CHECK_HR(hr = pIDBProperties->GetProperties(
1, // cPropertyIDSets
rgPropertyIDSets, // rgPropertyIDSets
&cPropSets, // pcPropSets
&rgPropSets // prgPropSets
));
}
else if( riid == IID_ISessionProperties )
{
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ISessionProperties,
(void**)&pISesProps));
CHECK_HR(hr = pISesProps->GetProperties(
1, // cPropertyIDSets
rgPropertyIDSets, // rgPropertyIDSets
&cPropSets, // pcPropSets
&rgPropSets // prgPropSets
));
}
else if( riid == IID_ICommandProperties )
{
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ICommandProperties,
(void**)&pICmdProps));
CHECK_HR(hr = pICmdProps->GetProperties(
1, // cPropertyIDSets
rgPropertyIDSets, // rgPropertyIDSets
&cPropSets, // pcPropSets
&rgPropSets // prgPropSets
));
}
else
{
XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IRowsetInfo,
(void**)&pIRowsetInfo));
CHECK_HR(hr = pIRowsetInfo->GetProperties(
1, // cPropertyIDSets
rgPropertyIDSets, // rgPropertyIDSets
&cPropSets, // pcPropSets
&rgPropSets // prgPropSets
));
}
// 将属性值返回给调用者(如果是一个VT_BOOL类型值).
if( V_VT(&rgPropSets[0].rgProperties[0].vValue) == VT_BOOL )
*pbValue = V_BOOL(&rgPropSets[0].rgProperties[0].vValue);
CLEANUP:
if( rgPropSets )
{
CoTaskMemFree(rgPropSets[0].rgProperties);
CoTaskMemFree(rgPropSets);
}
if( pIDBProperties )
pIDBProperties->Release();
if( pISesProps )
pISesProps->Release();
if( pICmdProps )
pICmdProps->Release();
if( pIRowsetInfo )
pIRowsetInfo->Release();
return hr;
}
/////////////////////////////////////////////////////////////////
// 函数: CreateSession
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -