📄 ctable.cpp
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module CTABLE.CPP
//
//-----------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////
// Includes
//
//////////////////////////////////////////////////////////////////////////////
#include "Common.h"
#include "CTable.h"
#include "msdaguid.h" //CLSID_OLEDB_ROWPOSITIONLIBRARY
/////////////////////////////////////////////////////////////////
// CRowset::CRowset
//
/////////////////////////////////////////////////////////////////
CRowset::CRowset(CMDIChild* pCMDIChild, CDataSource* pCDataSource) : CBase(pCMDIChild)
{
//DataSource
ASSERT(pCDataSource);
m_pCDataSource = pCDataSource;
m_pCSession = new CSession(pCMDIChild, m_pCDataSource);
m_pCCommand = new CCommand(pCMDIChild, m_pCSession);
m_pCRowPos = new CRowPos(pCMDIChild);
m_pCMultipleResults = new CMultipleResults(pCMDIChild);
m_pCDataset = new CDataset(pCMDIChild);
//ColInfo
m_cColumns = 0;
m_rgColumnInfo = NULL;
m_pStringBuffer = NULL;
//Rowset
m_pIAccessor = NULL;//Rowset Interface
m_pIColumnsInfo = NULL;//Rowset Interface
m_pIConvertType = NULL;//Rowset Interface
m_pIRowset = NULL;//Rowset Interface
m_pIRowsetInfo = NULL;//Rowset Interface
m_pIColumnsRowset = NULL;//Rowset Interface
m_pIConnectionPointContainer = NULL;//Rowset Interface
m_pIDBAsynchStatus = NULL;//Rowset Interface
m_pIRowsetChange = NULL;//Rowset Interface
m_pIRowsetIdentity = NULL;//Rowset Interface
m_pIRowsetLocate = NULL;//Rowset Interface
m_pIRowsetFind = NULL;//Rowset Interface
m_pIRowsetView = NULL;//Rowset Interface
m_pIChapteredRowset = NULL;//Rowset Interface
m_pIRowsetResynch = NULL;//Rowset Interface
m_pIRowsetScroll = NULL;//Rowset Interface
m_pIRowsetUpdate = NULL;//Rowset Interface
m_pISupportErrorInfo = NULL;//Rowset Interface
//Extra Interfaces
m_pIConnectionPoint = NULL;//Connection Interface
//Accessor
m_cBindings = 0;
m_rgBindings = NULL;
m_hAccessor = NULL;
m_pData = NULL;
//Bookmark Accessor
m_cBmkBindings = 0;
m_rgBmkBindings = NULL;
m_hBmkAccessor = NULL;
m_fContainsBmk = FALSE;
//Listeners
m_pCRowsetNotify = new CRowsetNotify(m_pCMDIChild->m_pCListBox);
m_pCAsynchNotify = new CAsynchNotify(m_pCMDIChild->m_pCListBox);
//Data
m_ulEstimatedRows = 0;
}
/////////////////////////////////////////////////////////////////
// CRowset::~CRowset
//
/////////////////////////////////////////////////////////////////
CRowset::~CRowset()
{
ReleaseRowset();
SAFE_DELETE(m_pCDataset);
SAFE_DELETE(m_pCMultipleResults);
SAFE_DELETE(m_pCRowPos);
SAFE_DELETE(m_pCCommand);
SAFE_DELETE(m_pCSession);
SAFE_DELETE(m_pCDataSource);
//Verify Listeners have no extra references on them...
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
pCListBox->OutputRelease((IUnknown**)&m_pCRowsetNotify, "IRowsetNotify", 0);
pCListBox->OutputRelease((IUnknown**)&m_pCAsynchNotify, "IDBAsynchNotify", 0);
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::SetInterface
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::SetInterface(REFIID riid, IUnknown* pIUnknown)
{
HRESULT hr = S_OK;
//no-op
if(pIUnknown == NULL)
return E_INVALIDARG;
//If the requested interface is a Rowset interface, place it in the
//Appropiate member variable, otherwise we have to release it, since we
//have no place to store it...
if(riid == IID_IUnknown)
m_pIUnknown = (IUnknown*)pIUnknown;
else if(riid == IID_IAccessor)
m_pIAccessor = (IAccessor*)pIUnknown;
else if(riid == IID_IColumnsInfo)
m_pIColumnsInfo = (IColumnsInfo*)pIUnknown;
else if(riid == IID_IConvertType)
m_pIConvertType = (IConvertType*)pIUnknown;
else if(riid == IID_IRowset)
m_pIRowset = (IRowset*)pIUnknown;
else if(riid == IID_IRowsetInfo)
m_pIRowsetInfo = (IRowsetInfo*)pIUnknown;
else if(riid == IID_IColumnsRowset)
m_pIColumnsRowset = (IColumnsRowset*)pIUnknown;
else if(riid == IID_IConnectionPointContainer)
m_pIConnectionPointContainer = (IConnectionPointContainer*)pIUnknown;
else if(riid == IID_IDBAsynchStatus)
m_pIDBAsynchStatus = (IDBAsynchStatus*)pIUnknown;
else if(riid == IID_IRowsetChange)
m_pIRowsetChange = (IRowsetChange*)pIUnknown;
else if(riid == IID_IRowsetIdentity)
m_pIRowsetIdentity = (IRowsetIdentity*)pIUnknown;
else if(riid == IID_IRowsetLocate)
m_pIRowsetLocate = (IRowsetLocate*)pIUnknown;
else if(riid == IID_IRowsetFind)
m_pIRowsetFind = (IRowsetFind*)pIUnknown;
else if(riid == IID_IRowsetView)
m_pIRowsetView = (IRowsetView*)pIUnknown;
else if(riid == IID_IChapteredRowset)
m_pIChapteredRowset = (IChapteredRowset*)pIUnknown;
else if(riid == IID_IRowsetResynch)
m_pIRowsetResynch = (IRowsetResynch*)pIUnknown;
else if(riid == IID_IRowsetScroll)
m_pIRowsetScroll = (IRowsetScroll*)pIUnknown;
else if(riid == IID_IRowsetUpdate)
m_pIRowsetUpdate = (IRowsetUpdate*)pIUnknown;
else if(riid == IID_ISupportErrorInfo)
m_pISupportErrorInfo = (ISupportErrorInfo*)pIUnknown;
else
hr = E_NOINTERFACE;
return hr;
}
/////////////////////////////////////////////////////////////////
// CRowset::ReleaseRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::ReleaseRowset()
{
//ColInfo
SAFE_FREE(m_rgColumnInfo);
SAFE_FREE(m_pStringBuffer);
ReleaseAccessor(&m_hAccessor);
FreeBindings(&m_cBindings, &m_rgBindings);
SAFE_FREE(m_pData);
m_fContainsBmk = FALSE;
ReleaseAccessor(&m_hBmkAccessor);
FreeBindings(&m_cBmkBindings, &m_rgBmkBindings);
//Rowset
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
pCListBox->OutputRelease((IUnknown**)&m_pIAccessor, "IAccessor");
pCListBox->OutputRelease((IUnknown**)&m_pIColumnsInfo, "IColumnsInfo");
pCListBox->OutputRelease((IUnknown**)&m_pIConvertType, "IConvertType");
pCListBox->OutputRelease((IUnknown**)&m_pIRowset, "IRowset");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetInfo, "IRowsetInfo");
pCListBox->OutputRelease((IUnknown**)&m_pIColumnsRowset, "IColumnsRowset");
pCListBox->OutputRelease((IUnknown**)&m_pIConnectionPointContainer, "IConnectionPointContainer");
pCListBox->OutputRelease((IUnknown**)&m_pIDBAsynchStatus, "IDBAsynchStatus");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetChange, "IRowsetChange");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetIdentity, "IRowsetIdentity");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetLocate, "IRowsetLocate");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetFind, "IRowsetFind");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetView, "IRowsetView");
pCListBox->OutputRelease((IUnknown**)&m_pIChapteredRowset, "IChapteredRowset");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetResynch, "IRowsetResynch");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetScroll, "IRowsetScroll");
pCListBox->OutputRelease((IUnknown**)&m_pIRowsetUpdate, "IRowsetUpdate");
pCListBox->OutputRelease((IUnknown**)&m_pISupportErrorInfo, "IRowsetErrorInfo");
//Extra intefaces
pCListBox->OutputRelease((IUnknown**)&m_pIConnectionPoint, "IConnectionPoint");
//RowPosition
m_pCRowPos->ReleaseRowPos();
//Base
ReleaseBase("Rowset");
//Don't Unadvise the Lsiteners until the Rowset goes away.
//We want to receive and Display the ROWSET_RELEASE notifications
UnadviseListeners();
return S_OK;
}
////////////////////////////////////////////////////////////////
// CRowset::CreateConnection
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::CreateConnection(IUnknown* pIUnknown, ULONG cPropSets, DBPROPSET* rgPropSets, DWORD dwConnectOptions)
{
HRESULT hr = E_FAIL;
//DataSource - Connect using the passed in Instance
TESTC(hr = m_pCDataSource->Connect(pIUnknown));
//DataSource - SetProperties
if(dwConnectOptions & CONNECT_SETPROPERTIES)
TESTC(hr = m_pCDataSource->SetProperties(cPropSets, rgPropSets));
//DataSource - Initialize
if(dwConnectOptions & CONNECT_INITIALIZE)
{
//Initialize and Obtain datasource interfaces
TESTC(hr = m_pCDataSource->Initialize());
}
else
{
//Just obtain whatever datasource interfaces are avialable...
TESTC(hr = m_pCDataSource->CreateDataSource(m_pCDataSource));
}
//Enumerators don't have sessions or commands
if(!m_pCDataSource->m_pISourcesRowset)
{
//Session
if(dwConnectOptions & CONNECT_CREATESESSION)
TESTC(hr = m_pCSession->CreateSession());
//Command (optional - provider may not support commands)
if(dwConnectOptions & CONNECT_CREATECOMMAND)
m_pCCommand->CreateCommand();
}
CLEANUP:
return hr;
}
////////////////////////////////////////////////////////////////
// CRowset::CreateConnection
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::CreateConnection(CRowset* pCRowset, BOOL bNewSession)
{
ASSERT(pCRowset);
HRESULT hr = E_FAIL;
//DataSource - Connect using the passed in Instance and Properties...
TESTC(hr = m_pCDataSource->CreateDataSource(pCRowset->m_pCDataSource));
//Enumerators don't have sessions or commands
if(!m_pCDataSource->m_pISourcesRowset)
{
//Session
if(pCRowset->m_pCSession->m_pIUnknown)
{
if(bNewSession)
{
TESTC(hr = m_pCSession->CreateSession());
}
else
{
TESTC(hr = m_pCSession->CreateSession(pCRowset->m_pCSession));
}
}
//Command (optional - provider may not support commands)
if(pCRowset->m_pCCommand->m_pIUnknown)
m_pCCommand->CreateCommand();
}
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::AdviseListeners
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::AdviseListeners()
{
HRESULT hr = E_FAIL;
HWND hWnd = m_pCMDIChild->m_hWnd;
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
//IRowsetNotify Listener
//This is optional functionality so don't post error
if(m_pIUnknown && GetOptionsObj()->m_dwNotifyOpts & NOTIFY_IROWSETNOTIFY)
hr = m_pCRowsetNotify->Advise(m_pIUnknown);
//IDBAsynchNotify Listener
//This is optional functionality so don't post error
if(m_pIUnknown && GetOptionsObj()->m_dwNotifyOpts & NOTIFY_IDBASYNCHNOTIFY)
hr = m_pCAsynchNotify->Advise(m_pIUnknown);
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::UnadviseListeners
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::UnadviseListeners()
{
HRESULT hr = E_FAIL;
HWND hWnd = m_pCMDIChild->m_hWnd;
//IRowsetNotify Listener
//This is optional functionality so don't post error
if(m_pIUnknown)
hr = m_pCRowsetNotify->Unadvise(m_pIUnknown);
//IDBAsynchNotify Listener
//This is optional functionality so don't post error
if(m_pIUnknown)
hr = m_pCAsynchNotify->Unadvise(m_pIUnknown);
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::GetColInfo
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::GetColInfo(IColumnsInfo* pIColumnsInfo)
{
HRESULT hr = E_FAIL;
HWND hWnd = m_pCMDIChild->m_hWnd;
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
//Release an Previous Info
SAFE_FREE(m_rgColumnInfo);
SAFE_FREE(m_pStringBuffer);
//Default this this objects IColumnsInfo
if(pIColumnsInfo == NULL)
pIColumnsInfo = m_pIColumnsInfo;
if(pIColumnsInfo)
{
//Get column information from the command object via IColumnsInfo::GetColumnsInfo
TESTC(pCListBox->OutputPreMethod("IColumnsInfo::GetColumnInfo(&%d, &0x%08x, &0x%08x)", m_cColumns, m_rgColumnInfo, m_pStringBuffer));
XTEST(hWnd, hr = pIColumnsInfo->GetColumnInfo(&m_cColumns, &m_rgColumnInfo, &m_pStringBuffer));
TESTC(pCListBox->OutputPostMethod(hr, "IColumnsInfo::GetColumnInfo(&%d, &0x%08x, &0x%08x)", m_cColumns, m_rgColumnInfo, m_pStringBuffer));
//Indicate weither or not provider includes bookmark column
m_fContainsBmk = FALSE;
if(m_rgColumnInfo)
m_fContainsBmk = m_rgColumnInfo[0].iOrdinal==0;
}
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////
// WCHAR* CRowset::GetColName
//
/////////////////////////////////////////////////////////////////
WCHAR* CRowset::GetColName(ULONG iOrdinal)
{
HRESULT hr = E_FAIL;
static WCHAR* pwszNullName = L"<NULL>";
static WCHAR* pwszEmptyName = L"<Empty>";
static WCHAR* pwszBookmarkName = L"<Bookmark>";
//Providers are not required to return a Column Name for any column
//Useful information, but some columns (ie: Bookmarks) and others
//May not have a column name. So this method will either just return
//Whatever the provider returned or will generate an appropiate one if not...
//We really need a column name to help for the GUI headers
DBCOLUMNINFO* pColInfo = GetColInfo(iOrdinal);
if(pColInfo == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -