⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atldbcli.h

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 H
📖 第 1 页 / 共 5 页
字号:
		{
			pBinding->dwPart |= DBPART_STATUS;
			pBinding->obStatus = nStatusOffset;
		}
	}

	// Free memory if appropriate
	static inline void FreeType(DBTYPE wType, BYTE* pValue, IRowset* pRowset = NULL)
	{
		switch (wType)
		{
			case DBTYPE_BSTR:
				SysFreeString(*((BSTR*)pValue));
			break;
			case DBTYPE_VARIANT:
				VariantClear((VARIANT*)pValue);
			break;
			case DBTYPE_IUNKNOWN:
			case DBTYPE_IDISPATCH:
				(*(IUnknown**)pValue)->Release();
			break;
			case DBTYPE_ARRAY:
				SafeArrayDestroy((SAFEARRAY*)pValue);
			break;

			case DBTYPE_HCHAPTER:
				CComQIPtr<IChapteredRowset> spChapteredRowset = pRowset;
				if (spChapteredRowset != NULL)
					spChapteredRowset->ReleaseChapter(*(HCHAPTER*)pValue, NULL);
			break;
		}
		if ((wType & DBTYPE_VECTOR) && ~(wType & DBTYPE_BYREF))
			CoTaskMemFree(((DBVECTOR*)pValue)->ptr);
	}

	_ATL_ACCESSOR_INFO* m_pAccessorInfo;
	ULONG               m_nAccessors;
	BYTE*               m_pBuffer;
};

///////////////////////////////////////////////////////////////////////////
// class CRowset

class CRowset
{
// Constructors and Destructors
public:
	CRowset()
	{
		m_pAccessor = NULL;
		m_hRow      = NULL;
	}
	CRowset(IRowset* pRowset)
	{
		m_spRowset  = pRowset;
		CRowset();
	}
	~CRowset()
	{
		Close();
	}
	// Release any retrieved row handles and then release the rowset
	void Close()
	{
		if (m_spRowset != NULL)
		{
			ReleaseRows();
			m_spRowset.Release();
			m_spRowsetChange.Release();
		}
	}
	// Addref the current row
	HRESULT AddRefRows()
	{
		ATLASSERT(m_spRowset != NULL);
		return m_spRowset->AddRefRows(1, &m_hRow, NULL, NULL);
	}
	// Release the current row
	HRESULT ReleaseRows()
	{
		ATLASSERT(m_spRowset != NULL);
		HRESULT hr = S_OK;

		if (m_hRow != NULL)
		{
			hr = m_spRowset->ReleaseRows(1, &m_hRow, NULL, NULL, NULL);
			m_hRow = NULL;
		}
		return hr;
	}
	// Compare two bookmarks with each other
	HRESULT Compare(const CBookmarkBase& bookmark1, const CBookmarkBase& bookmark2,
		DBCOMPARE* pComparison) const
	{
		ATLASSERT(m_spRowset != NULL);
		CComPtr<IRowsetLocate> spLocate;
		HRESULT hr = m_spRowset.QueryInterface(&spLocate);
		if (FAILED(hr))
			return hr;

		return spLocate->Compare(NULL, bookmark1.GetSize(), bookmark1.GetBuffer(),
			bookmark2.GetSize(), bookmark2.GetBuffer(), pComparison);
	}
	// Compare the passed hRow with the current row
	HRESULT IsSameRow(HROW hRow) const
	{
		ATLASSERT(m_spRowset != NULL);
		CComPtr<IRowsetIdentity> spRowsetIdentity;
		HRESULT hr = m_spRowset.QueryInterface(&spRowsetIdentity);
		if (FAILED(hr))
			return hr;

		return spRowsetIdentity->IsSameRow(m_hRow, hRow);
	}
	// Move to the previous record
	HRESULT MovePrev()
	{
		return MoveNext(-2, true);
	}
	// Move to the next record
	HRESULT MoveNext()
	{
		return MoveNext(0, true);
	}
	// Move lSkip records forward or backward
	HRESULT MoveNext(LONG lSkip, bool bForward)
	{
		HRESULT hr;
		ULONG ulRowsFetched = 0;

		// Check the data was opened successfully and the accessor
		// has been set.
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);

		// Release a row if one is already around
		ReleaseRows();

		// Get the row handle
		HROW* phRow = &m_hRow;
		hr = m_spRowset->GetNextRows(NULL, lSkip, (bForward) ? 1 : -1, &ulRowsFetched, &phRow);
		if (hr != S_OK)
			return hr;

		// Get the data
		hr = GetData();
		if (FAILED(hr))
		{
			ATLTRACE2(atlTraceDBClient, 0, _T("GetData failed - HRESULT = 0x%X\n"),hr);
			ReleaseRows();
		}
		return hr;
	}
	// Move to the first record
	HRESULT MoveFirst()
	{
		HRESULT hr;

		// Check the data was opened successfully and the accessor
		// has been set.
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);

		// Release a row if one is already around
		ReleaseRows();

		hr = m_spRowset->RestartPosition(NULL);
		if (FAILED(hr))
			return hr;

		// Get the data
		return MoveNext();
	}
	// Move to the last record
	HRESULT MoveLast()
	{
		// Check the data was opened successfully and the accessor
		// has been set.
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);

		// Release a row if one is already around
		ReleaseRows();

		HRESULT hr;
		ULONG ulRowsFetched = 0;
		HROW* phRow = &m_hRow;
		// Restart the rowset position and then move backwards
		m_spRowset->RestartPosition(NULL);
		hr = m_spRowset->GetNextRows(NULL, -1, 1, &ulRowsFetched, &phRow);
		if (hr != S_OK)
			return hr;

		// Get the data
		hr = GetData();
		if (FAILED(hr))
		{
			ATLTRACE2(atlTraceDBClient, 0, _T("GetData from MoveLast failed - HRESULT = 0x%X\n"),hr);
			ReleaseRows();
		}

		return S_OK;
	}
	// Move to the passed bookmark
	HRESULT MoveToBookmark(const CBookmarkBase& bookmark, LONG lSkip = 0)
	{
		// Check the data was opened successfully and the accessor
		// has been set.
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);

		CComPtr<IRowsetLocate> spLocate;
		HRESULT hr = m_spRowset.QueryInterface(&spLocate);
		if (FAILED(hr))
			return hr;

		// Release a row if one is already around
		ReleaseRows();

		ULONG ulRowsFetched = 0;
		HROW* phRow = &m_hRow;
		hr = spLocate->GetRowsAt(NULL, NULL, bookmark.GetSize(), bookmark.GetBuffer(),
			lSkip, 1, &ulRowsFetched, &phRow);
		// Note we're not using SUCCEEDED here, because we could get DB_S_ENDOFROWSET
		if (hr != S_OK)
			return hr;

		// Get the data
		hr = GetData();
		if (FAILED(hr))
		{
			ATLTRACE2(atlTraceDBClient, 0, _T("GetData from Bookmark failed - HRESULT = 0x%X\n"),hr);
			ReleaseRows();
		}

		return S_OK;
	}
	// Get the data for the current record
	HRESULT GetData()
	{
		HRESULT hr = S_OK;
		ATLASSERT(m_pAccessor != NULL);

		ULONG nAccessors = m_pAccessor->GetNumAccessors();
		for (ULONG i=0; i<nAccessors; i++)
		{
			if (m_pAccessor->IsAutoAccessor(i))
			{
				hr = GetData(i);
				if (FAILED(hr))
					return hr;
			}
		}
		return hr;
	}
	// Get the data for the passed accessor. Use for a non-auto accessor
	HRESULT GetData(int nAccessor)
	{
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);
		ATLASSERT(m_hRow != NULL);

		// Note that we are using the specified buffer if it has been set,
		// otherwise we use the accessor for the data.
		return m_spRowset->GetData(m_hRow, m_pAccessor->GetHAccessor(nAccessor), m_pAccessor->GetBuffer());
	}
	// Get the data for the passed accessor. Use for a non-auto accessor
	HRESULT GetDataHere(int nAccessor, void* pBuffer)
	{
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);
		ATLASSERT(m_hRow != NULL);

		// Note that we are using the specified buffer if it has been set,
		// otherwise we use the accessor for the data.
		return m_spRowset->GetData(m_hRow, m_pAccessor->GetHAccessor(nAccessor), pBuffer);
	}
	HRESULT GetDataHere(void* pBuffer)
	{
		HRESULT hr = S_OK;

		ULONG nAccessors = m_pAccessor->GetNumAccessors();
		for (ULONG i=0; i<nAccessors; i++)
		{
			hr = GetDataHere(i, pBuffer);
			if (FAILED(hr))
				return hr;
		}
		return hr;
	}

	// Insert the current record
	HRESULT Insert(int nAccessor = 0, bool bGetHRow = false)
	{
		ATLASSERT(m_pAccessor != NULL);
		HRESULT hr;
		if (m_spRowsetChange != NULL)
		{
			HROW* pHRow;
			if (bGetHRow)
			{
				ReleaseRows();
				pHRow = &m_hRow;
			}
			else
				pHRow = NULL;

			hr = m_spRowsetChange->InsertRow(NULL, m_pAccessor->GetHAccessor(nAccessor),
					m_pAccessor->GetBuffer(), pHRow);

		}
		else
			hr = E_NOINTERFACE;

		return hr;
	}
	// Delete the current record
	HRESULT Delete() const
	{
		ATLASSERT(m_pAccessor != NULL);
		HRESULT hr;
		if (m_spRowsetChange != NULL)
			hr = m_spRowsetChange->DeleteRows(NULL, 1, &m_hRow, NULL);
		else
			hr = E_NOINTERFACE;

		return hr;
	}
	// Update the current record
	HRESULT SetData() const
	{
		ATLASSERT(m_pAccessor != NULL);
		HRESULT hr = S_OK;

		ULONG nAccessors = m_pAccessor->GetNumAccessors();
		for (ULONG i=0; i<nAccessors; i++)
		{
			hr = SetData(i);
			if (FAILED(hr))
				return hr;
		}
		return hr;
	}
	// Update the current record with the data in the passed accessor
	HRESULT SetData(int nAccessor) const
	{
		ATLASSERT(m_pAccessor != NULL);
		HRESULT hr;
		if (m_spRowsetChange != NULL)
		{
			hr = m_spRowsetChange->SetData(m_hRow, m_pAccessor->GetHAccessor(nAccessor),
				m_pAccessor->GetBuffer());
		}
		else
			hr = E_NOINTERFACE;

		return hr;
	}

	// Get the data most recently fetched from or transmitted to the data source.
	// Does not get values based on pending changes.
	HRESULT GetOriginalData()
	{
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(m_pAccessor != NULL);

		HRESULT hr = S_OK;
		CComPtr<IRowsetUpdate> spRowsetUpdate;
		hr = m_spRowset->QueryInterface(&spRowsetUpdate);
		if (FAILED(hr))
			return hr;

		ULONG nAccessors = m_pAccessor->GetNumAccessors();
		for (ULONG i = 0; i < nAccessors; i++)
		{
			hr = spRowsetUpdate->GetOriginalData(m_hRow, m_pAccessor->GetHAccessor(i), m_pAccessor->GetBuffer());
			if (FAILED(hr))
				return hr;
		}
		return hr;
	}
	// Get the status of the current row
	HRESULT GetRowStatus(DBPENDINGSTATUS* pStatus) const
	{
		ATLASSERT(m_spRowset != NULL);
		ATLASSERT(pStatus != NULL);

		CComPtr<IRowsetUpdate> spRowsetUpdate;
		HRESULT hr = m_spRowset->QueryInterface(&spRowsetUpdate);
		if (FAILED(hr))
			return hr;

		return spRowsetUpdate->GetRowStatus(NULL, 1, &m_hRow, pStatus);
	}
	// Undo any changes made to the current row since it was last fetched or Update
	// was called for it
	HRESULT Undo(ULONG* pcRows = NULL, HROW* phRow = NULL, DBROWSTATUS* pStatus = NULL)
	{
		ATLASSERT(m_spRowset != NULL);

		CComPtr<IRowsetUpdate> spRowsetUpdate;
		HRESULT hr = m_spRowset->QueryInterface(&spRowsetUpdate);
		if (FAILED(hr))
			return hr;

		HROW*           prgRows;
		DBROWSTATUS*    pRowStatus;
		if (phRow != NULL)
			hr = spRowsetUpdate->Undo(NULL, 1, &m_hRow, pcRows, &prgRows, &pRowStatus);
		else
			hr = spRowsetUpdate->Undo(NULL, 1, &m_hRow, pcRows, NULL, &pRowStatus);
		if (FAILED(hr))
			return hr;

		if (phRow != NULL)
		{
			*phRow = *prgRows;
			CoTaskMemFree(prgRows);
		}
		if (pStatus != NULL)
			*pStatus = *pRowStatus;

		CoTaskMemFree(pRowStatus);
		return hr;
	}
	// Transmits any pending changes made to a row since it was last fetched or Update was
	// called for it. Also see SetData.
	HRESULT Update(ULONG* pcRows = NULL, HROW* phRow = NULL, DBROWSTATUS* pStatus = NULL)
	{
		ATLASSERT(m_spRowset != NULL);

		CComPtr<IRowsetUpdate> spRowsetUpdate;
		HRESULT hr = m_spRowset->QueryInterface(&spRowsetUpdate);
		if (FAILED(hr))
			return hr;

		HROW*           prgRows;
		DBROWSTATUS*    pRowStatus;
		if (phRow != NULL)
			hr = spRowsetUpdate->Update(NULL, 1, &m_hRow, pcRows, &prgRows, &pRowStatus);
		else
			hr = spRowsetUpdate->Update(NULL, 1, &m_hRow, pcRows, NULL, &pRowStatus);
		if (FAILED(hr))
			return hr;

		if (phRow != NULL)
		{
			*phRow = *prgRows;
			CoTaskMemFree(prgRows);
		}
		if (pStatus != NULL)
			*pStatus = *pRowStatus;

		CoTaskMemFree(pRowStatus);
		return hr;
	}

	// Get the approximate position of the row corresponding to the passed bookmark
	HRESULT GetApproximatePosition(const CBookmarkBase* pBookmark, ULONG* pPosition, ULONG* pcRows)
	{
		ATLASSERT(m_spRowset != NULL);

		CComPtr<IRowsetScroll> spRowsetScroll;
		HRESULT hr = m_spRowset->QueryInterface(&spRowsetScroll);
		if (SUCCEEDED(hr))
		{
			if (pBookmark != NULL)
				hr = spRowsetScroll->GetApproximatePosition(NULL, pBookmark->GetSize(), pBookmark->GetBuffer(),
						pPosition, pcRows);
			else
				hr = spRowsetScroll->GetApproximatePosition(NULL, 0, NULL, pPosition, pcRows);

		}
		return hr;

	}
	// Move to a fractional position in the rowset
	HRESULT MoveToRatio(ULONG nNumerator, ULONG nDenominator, bool bForward = true)
	{
		ATLASSERT(m_spRowset != NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -