游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2490|回复: 2

ATL与STL.ADO完美演绎 2 wxh zt

[复制链接]

1367

主题

1993

帖子

2118

积分

金牌会员

Rank: 6Rank: 6

积分
2118
发表于 2004-11-10 19:26:00 | 显示全部楼层 |阅读模式
   最近我们公司开发有关电力方面的软件,分成了几个大模块,由于种种原因.大家所使用的开发工具比较杂,很是头痛,大家想了很多的办法,一直没能很好的解决这个问题!我们的开发工具有Microsoft Visual C++ 6.0,Microsoft Visual Basic ,Borland C++ Builder,一开始如果只用Microsoft 开发工具的话,可能会好解决一些,但是这样的情况不大好弄,如果让大家换工具,这样这个项目就会被耽误了!

   一开始大家想做成普通的DLL来解决,可是由于Microsoft VC的DLL的格式与C++ Builder 格式不一样,它们进出栈的顺序也不一样,虽然也有方法解决这个问题,但似乎不怎么方便,最后决定核心的几个模块做成COM组件!由于我对VC比较熟悉吧,这几个核心组件由Me 来完成,下面我在这里谈谈有关用ATL 与STL,ADO 的组合使用.

    ATL ,这个大家应用不陌生了吧,很多人都谈过,的确用它来写COM组件,很方便,但是对你的要求也要高一些,有困难,咱不怕,学习吗!特别用ATL写一些涉及GUI的ActiveX 控件,你就不能依靠MFC,当然你也可以用MFC ,如果这样大大削弱ATL的优势!没有了MFC中CTypedPtrList,CObList,我怎么处理大量的数据,而且我写的是处理数据库的呀,这样STL 的优势就可以展示,STL一开始学起来不太容易,但是你能熟练的用它时,我猜你会放弃用什么CTypedPtrList,CObList,CArray了,因为STL的功能太强大了的呀!

  另外写数据库的组件,你可以用很多的方式,但是我比较喜欢用ADO,原因是一方面基于COM,处理速率比较快,还有一个主要原因用起来很灵活,也很简单的呀!

  废话说了这么多,下面说一下我的代码:

  这个COM组件主要提供了一些接口连接各种数据库如常见的Access,SQL Server,Oracle 也可以是ODBC数据源,你可以调用一个方法,并提供一些参数可以连接上数据库了,连接以后你可以直接执行SQL语句,也可以设置是否需要事务处理,以及查询数据库中有哪些表以及表中哪些字段,你也可以获得数据等等,大家看了代码就知道了,由于时间原因,更多功能我没有写来!

  代码中注释还有一些,有些地方可能不太理解,如下面:


//-------------------------------------
//By the row and col to get the value.
//Parameter:nRow ,nCol .the start row and col is 0 ,not 1.
STDMETHODIMP CDBInterface::GetRecordValue(int nRow, int nCol, OLECHAR *pValue)
{
USES_CONVERSION;
//Verify the nRow can’t greater than max record
//the nCol can’t greater than number of the field
int nRowCount,nColCount;
int nHasRead=0;
HRESULT hr;
string strTemp;
RecordIter iter;
RecordValue list;

nHasRead=GetTwentyRecord(m_pRst);
hr=GetRecordCount(&nRowCount);
if (FAILED(hr))
  return E_FAIL;
hr=GetFieldCount(&nColCount);
if (FAILED(hr))
  return E_FAIL;

if (nRow>=nRowCount || nCol>=nColCount)
  return E_FAIL;

//When the row is less than MAX_RECORD ,we get the record directly from the memory
//that we have store,or else we read record from database until we have read greater
//or equal the query row.
if (nRow<MAX_RECORD)
{

  list=m_RecordValue[nRow];
  iter=list.begin();
  for(int i=0;i<=nCol && iter!=list.end();i++)
  {
   iter++;
  }
  
  if (iter!=list.end())
  {
   strTemp=*iter;
   wcscpy(pValue,T2OLE(strTemp.c_str()));
  }
  else
   *pValue=L’0’;
}
else
{
  int nTemp=0;
  while(nHasRead<=nRow)
  {
   nTemp=GetTwentyRecord(m_pRst);
   if (nTemp==0)
   {
    *pValue=L’0’;
    return E_FAIL;
   }
   else
    nHasRead+=nTemp;
  }

  //Find which row we need

  int nRowTemp=nRow%MAX_RECORD;
  list=m_RecordValue[nRowTemp];
  iter=list.begin();

  for(int i=0;i<=nCol && iter!=list.end();i++)
  {
   iter++;
  }
  
  if (iter!=list.end())
  {
   strTemp=*iter;
   wcscpy(pValue,T2OLE(strTemp.c_str()));
  }
  else
  {
   *pValue=L’0’;
  }


  
}

//If we has compelete one query ,then make sure the record pointer to the
//first ,so that promise the next query.
m_pRst->MoveFirst();

return S_OK;
}

//-------------------------------------
//Considering  too many record will cost too many memeory
//There ,we only store twenty record ,
//Before ,we stroe the next record ,first ,we must clear the vector and list
//Return Value:The record number that we have actually read
int CDBInterface::GetTwentyRecord(_RecordsetPtr pRst)
{
if (!m_bExecuted)
  return 0;

//clear pervious record
RecordValue list;
string strValue;
for (int i=0;i<m_RecordValue.size();i++)
{
  list=m_RecordValue;
  list.clear();
}
m_RecordValue.clear();


int nHasStore=0;
_variant_t varValue;
_bstr_t bstrValue;
FieldPtr fieldCtl;

while (!pRst->EndofFile && nHasStore++<MAX_RECORD)
{
  list.clear();
  fieldCtl=pRst->Fields->GetItem(long(0));
  varValue=fieldCtl->Value;
  if (varValue.vt==VT_NULL)
  {
   bstrValue="";
  }
  else
  {
   bstrValue=varValue;
  }
  strValue=(char *)bstrValue;
  list.push_back(strValue);


  //Get each field value and then push to the list
  //After get all the field value, push the vector
  for (int j=1;j<pRst->Fields->Count;j++)
  {
   fieldCtl=pRst->Fields->GetItem(long(j));
   varValue=fieldCtl->Value;

   //If this field is NULL,we must set it NULL,
   //or else ,maybe runtime error!
   if (varValue.vt==VT_NULL)
   {
    bstrValue="";
   }
   else
   {
    bstrValue=varValue;
   }
   strValue=(char*)bstrValue;
   list.push_back(strValue);
  }
  m_RecordValue.push_back(list);
  pRst->MoveNext();
}

return nHasStore;
}


一些变量大家看了代码就知道,上面我考虑到使用内存和速度问题,大家只要更改一下MAX_RECORD就可以,我的意思是当用户调用这个方法,我先从database中读MAX_RECORD存入到内存中,如果要Query 在内存中,可以直接返回,否则每次从数据库中读出MAX_RECORD,大家还要注意的就是STL在这其中的运用,我也是个初学者,大家互相学习吗!


33

主题

669

帖子

669

积分

高级会员

Rank: 4

积分
669
QQ
发表于 2004-11-11 10:33:00 | 显示全部楼层

Re:ATL与STL.ADO完美演绎 2 wxh zt

晕了

28

主题

685

帖子

703

积分

高级会员

Rank: 4

积分
703
发表于 2004-11-11 13:17:00 | 显示全部楼层

atl中可能没必要用STL,直接用ATL的一些模板也足够了,

有些情况比STL还要快。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-23 05:41

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表