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

📄 mydataobject.cpp

📁 The ATL OLE DB Provider templates only seem to support read-only rowsets and making them support upd
💻 CPP
字号:
// MyDataObject.cpp : Implementation of CMyDataObject
#include "stdafx.h"
#include "SimpleDataObject.h"
#include "MyDataObject.h"
#include "DataObjectRowset.h"

#include <comdef.h>     // for _bstr_t
   
/////////////////////////////////////////////////////////////////////////////
// CMyDataObject


CMyDataObject::CMyDataObject()
   :  m_numCols(0),
      m_numRows(0),
      m_allocatedRows(0),
      m_rowSize(0),
      m_columnSize(10 + 1),
      m_pData(0)
{

}

CMyDataObject::~CMyDataObject()
{
   for (size_t i = 0; i < m_numCols; i++)
   {
      free(m_columnNames[i]);
   }

   delete [] m_pData;
}

HRESULT CMyDataObject::SetColumnSize(
   /* [in] */ long columnSize)
{
   if (m_pData != 0)
   {
      return E_UNEXPECTED; // too late!
   }
 
   m_columnSize = columnSize + 1;      // add one for null term

   return S_OK;
}


HRESULT CMyDataObject::AddColumn(
	/* [in] */ BSTR columnName, 
	/* [out, retval] */ long *index)
{
   if (m_pData != 0)
   {
      return E_UNEXPECTED; // too late!
   }

   if (!index)
   {
      return E_POINTER;
   }
 
   // add the column to the column map, 

   _bstr_t bstr(columnName);

   m_columnNames.Add(strdup((char*)bstr));

   *index = m_numCols++;

   return S_OK;
}

HRESULT CMyDataObject::GetColumnName(
	/* [in] */ long index,
	/* [out, retval] */ BSTR *columnName)
{
   if (!CheckColumnValid(index))
   {
      return E_INVALIDARG;
   }

   if (!columnName)
   {
      return E_POINTER;
   }

   char *pColumnName = m_columnNames[index - 1];

   CComBSTR bstr(pColumnName);

   *columnName = bstr.Detach();
   
   return S_OK;
}
	

HRESULT CMyDataObject::AddRow(
   /* [out, retval] */ long *index)
{
   if (m_numCols == 0)
   {
      return E_UNEXPECTED; // To early!
   }

   if (!index)
   {
      return E_POINTER;
   }

   *index = AddRow();

   return S_OK;
}

HRESULT CMyDataObject::RemoveRow(
   /* [in] */ long index)
{
   if (!CheckRowValid(index))
   {
      return E_INVALIDARG;
   }

   // remove a row from somewhere in the table...
   // all rows below shuffle up one
   // array is not made smaller...

   if ((size_t)index != m_numRows)  // if it's not the last row...
   {
      char *pThisRow = GetAt(index, 1);
      char *pNextRow = GetAt(index + 1, 1);

      memmove(pThisRow, pNextRow, (m_numRows - index) * m_rowSize);
   }

   m_numRows--;


   return S_OK;
}
	
HRESULT CMyDataObject::Depth(
   /* [out, retval] */ long *depth)
{
   if (!depth)
   {
      return E_POINTER;
   }

   *depth = m_numRows;

   return S_OK;
}

HRESULT CMyDataObject::Width(
   /* [out, retval] */ long *width)
{
   if (!width)
   {
      return E_POINTER;
   }

   *width = m_numCols;

   return S_OK;
}

HRESULT CMyDataObject::SetAt(
   /* [in] */ long rowIndex, 
	/*	[in] */ long columnIndex, 
	/*	[in] */ BSTR value)
{
   if (!CheckRowAndColumnValid(rowIndex, columnIndex))
   {
      return E_INVALIDARG;
   }

   _bstr_t bstr(value);

   if (bstr.length() >= m_columnSize)
   {
      return E_INVALIDARG;
   }

   SetAt(rowIndex, columnIndex, (char*)bstr, bstr.length());

   return S_OK;
}

void CMyDataObject::SetAt(
   const size_t row, 
   const size_t col, 
   const char *const pNewData,
   const size_t length)
{
   char *pData = GetAt(row, col);

   if (length > 0)
   {
      memcpy(pData, (char*)pNewData, length);
   }

   *(pData + length) = '\0';
}


HRESULT CMyDataObject::GetAt(
   /* [in] */ long rowIndex, 
   /* [in] */ long columnIndex, 
   /* [out, retval] */ BSTR *value)
{
   if (!CheckRowAndColumnValid(rowIndex, columnIndex))
   {
      return E_INVALIDARG;
   }

   if (!value)
   {
      return E_POINTER;
   }

   char *pData = GetAt(rowIndex, columnIndex);

   // convert to BSTR

   CComBSTR bstr(pData);

   *value = bstr.Detach();

   return S_OK;
}


char *CMyDataObject::GetAt(const size_t row, const size_t col)
{
   ATLASSERT(CheckRowAndColumnValid(row, col));

   return &m_pData[((row -1)  * m_rowSize) + ((col -1)* m_columnSize)];
}

char *CMyDataObject::CreateTable()
{
   char *pTable = new char[(m_allocatedRows + 1) * m_rowSize];

   memset(pTable, 0, (m_allocatedRows + 1) * m_rowSize);

   return pTable;
}

bool CMyDataObject::CheckRowAndColumnValid(
   const size_t row, 
   const size_t column)
{
   return CheckRowValid(row) && CheckColumnValid(column);
}

bool CMyDataObject::CheckRowValid(const size_t row)
{
   bool ok = true;

   if (row < 1 || row > m_numRows)
   {
      ok = false;
   }

   return ok;
}

bool CMyDataObject::CheckColumnValid(const size_t column)
{
   bool ok = true;

   if (column < 1 ||
       column > m_numCols)
   {
      ok = false;
   }

   return ok;
}


HRESULT CMyDataObject::AsRowset(
   /* [in] */ IUnknown *pUnkCreator,
   /* [in] */ IUnknown *pUnkOuter,	
	/* [in] */ REFIID riid,				
   /* [out] */ LONG *pcRowsAffected,					
	/* [out, iid_is(riid)] */ IUnknown **ppRowset)
{
   CDataObjectRowset *pRowset = 0;

   HRESULT hr = CreateRowset(pUnkCreator, pUnkOuter, riid, ppRowset, pRowset);

   if (SUCCEEDED(hr))
   {
      IUnknown *pUnknown = 0;
   	
      hr = QueryInterface(IID_IUnknown, (void**)&pUnknown);

      if (SUCCEEDED(hr))
      {
         hr = pRowset->LinkToObject(this, pUnknown, pcRowsAffected);    

         pUnknown->Release();
      }
   }
   return hr;
}


long CMyDataObject::AddRow()
{
   long rowIndex = m_numRows;
   
   if (m_allocatedRows == 0)
   {
      // First allocation

      m_rowSize = m_numCols * m_columnSize;

   }

   if (m_pData == 0)
   {
      // First row to be added.

      m_numRows++;
      m_allocatedRows++;

      m_pData = CreateTable();      
   }
   else if (m_numRows == m_allocatedRows)
   {
      // need to expand the row buffer

      char *pOldData = m_pData;

      m_numRows++;
      m_allocatedRows++;

      m_pData = CreateTable();

      memcpy(m_pData, pOldData, (m_numRows -1) * m_rowSize);

      delete [] pOldData;
   }
   else
   {
      m_numRows++;

      memset(GetAt(m_numRows, 1), 0, m_rowSize);
   }

   return rowIndex;
}
	

⌨️ 快捷键说明

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