能捎带介绍一下ATL的资料,感激不尽!

解决方案 »

  1.   

    我现在作一b/s系统,使用asp,访问sql的时候有点困惑,不知到是该使用com,还是直接使用script.一来对com不熟悉,有点困难,二来不知道能否不用com,而是作一script文件实现com所提供的接口,用的时候仅仅include一下。如果可行的话具体如何操作呢?
      

  2.   

    Sure! MSDN ATL and ADO.
      

  3.   

    随便找一本VC中使用ADO的例子看看,在ATL中使用的方法一样。
    我的一个例子:// StationINFO.h: interface for the CStationINFO class.
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_STATIONINFO_H__20B3282D_488E_49AF_908D_BA06605FBD39__INCLUDED_)
    #define AFX_STATIONINFO_H__20B3282D_488E_49AF_908D_BA06605FBD39__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000//ADO
    #define INITGUID
    #import "E:\program files\common files\system\ado\msado15.dll" rename ("EOF","adoEOF") no_namespace
    #include <icrsint.h>#define CREATEiNSTANCE(sp,riid) { HRESULT _hr =sp .CreateInstance( __uuidof( riid ) ); \
                                      if (FAILED(_hr)) _com_issue_error(_hr); }
    #define RsITEM(rs,x) rs->Fields->Item[_variant_t(x)]->Value
    #define UC (_TCHAR *)typedef struct tagStation
    {
    _TCHAR StatID[6];
    _TCHAR StatName[20];
    INT ProvinceID;
    _TCHAR Canton[10];
    FLOAT Longitude;
    FLOAT Latitude;
    FLOAT Altitude;
    FLOAT ShowLevel; //显示级别
    }StationTable;typedef struct tagProvince
    {
    INT ID;
    _TCHAR Province[10];
    }ProvinceTable;class CStationRS: public CADORecordBinding
    {
    BEGIN_ADO_BINDING(CStationRS)
    //ADO_NUMERIC_ENTRY2(Ordinal, DataType, Buffer, Precision, Scale, Modify)
    //ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, StatID,sizeof(StatID), StatID_Status, false)
    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, StatName,sizeof(StatName), StatName_Status, false)
    ADO_NUMERIC_ENTRY2(4, adInteger, ProvinceID,5, 0, false)
    ADO_VARIABLE_LENGTH_ENTRY2(5, adVarChar, Canton,sizeof(Canton), Canton_Status, false)
    ADO_NUMERIC_ENTRY2(6, adSingle, Latitude,8, 2, false)
    ADO_NUMERIC_ENTRY2(7, adSingle, Longitude,8,2, false)
    ADO_NUMERIC_ENTRY2(8, adSingle, Altitude,8, 2, false)
    ADO_NUMERIC_ENTRY2(9, adSingle, ShowLevel,8,2, false)
    END_ADO_BINDING()
    public:
    _TCHAR StatID[6];
    ULONG StatID_Status;  //记录对应错误代码
    _TCHAR StatName[20];
    ULONG StatName_Status;  //记录对应错误代码
    INT ProvinceID;
    ULONG ProvinceID_Status;  //记录对应错误代码
    _TCHAR Canton[10];
    ULONG Canton_Status;  //记录对应错误代码
    FLOAT Longitude;
    ULONG Longitude_Status;  //记录对应错误代码
    FLOAT Latitude;
    ULONG Latitude_Status;  //记录对应错误代码
    FLOAT Altitude;
    ULONG Altitude_Status;  //记录对应错误代码
    FLOAT ShowLevel; //显示级别
    ULONG ShowLevel_Status;  //记录对应错误代码
    };class CStationINFO
    {
    public:
    CStationINFO();
    virtual ~CStationINFO();
    StationTable *cpStations;
    ProvinceTable *cpProvince;
    INT StationCount;
    INT ProvinceCount; INT GetInfoFromDB();
    BOOL GetInfoStd();private:
    BOOL InfoStd;
    };#endif // !defined(AFX_STATIONINFO_H__20B3282D_488E_49AF_908D_BA06605FBD39__INCLUDED_)____________________________________________________________________________________________________________________________________________________________________// StationINFO.cpp: implementation of the CStationINFO class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "StationINFO.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    //#define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CStationINFO::CStationINFO():cpProvince(NULL),cpStations(NULL),InfoStd(FALSE)
    {
    //MessageBox(NULL,_T("StdInfo"),_T("Enter"),MB_OK);
    //读取数据由CMIDView构造函数执行
    }INT CStationINFO::GetInfoFromDB()
    {
    MessageBox(NULL,_T("Getting Stdinfo"),_T(""),MB_OK);
        _RecordsetPtr   spRS;
        _ConnectionPtr  spCON;
        try{
            CREATEiNSTANCE(spCON,Connection);
            spCON->ConnectionString =_Module.DBCLIENTCONNSTR;
            spCON->Open("","","", -1 );
            CREATEiNSTANCE(spRS,Recordset) 
            spRS->PutRefActiveConnection(spCON );
            spRS->Open("select * from [StationInfo]", vtMissing,adOpenKeyset,
                        adLockBatchOptimistic, adCmdUnspecified);
    HRESULT hr;
    IADORecordBinding *picRS; //指向COM接口的指针
    CStationRS rs; if(FAILED(hr=spRS->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRS))) //接口IADORecordBinding是记录集的一部分
    _com_issue_error(hr);
    if(FAILED(hr=picRS->BindToRecordset(&rs)))_com_issue_error(hr); //绑定到记录集 if (spRS->RecordCount>0)
    {
    spRS->MoveLast();
    spRS->MoveFirst();
    StationCount=spRS->RecordCount;
    cpStations=new StationTable[StationCount];
    StationTable *pStations=cpStations; while(spRS->adoEOF == false){
    _tcscpy((_TCHAR *)pStations->StatName,rs.StatName_Status==adFldOK?rs.StatName:_T(""));
    _tcscpy((_TCHAR *)pStations->StatID,rs.StatID_Status==adFldOK?rs.StatID:_T(""));
    _tcscpy((_TCHAR *)pStations->Canton,rs.Canton_Status==adFldOK?rs.Canton:_T(""));
    pStations->Altitude =rs.Altitude;
    pStations->Latitude =rs.Latitude*1000.f;
    pStations->Longitude =rs.Longitude*1000.f;
    pStations->ProvinceID =rs.ProvinceID;
    pStations->ShowLevel  =rs.ShowLevel;
    ATLTRACE(_T("%S,%S,%S\n"),rs.StatName,rs.StatID,rs.Canton );
    spRS->MoveNext();
    pStations++;
    }
    spRS->Close();
            } spCON->Close();
    InfoStd=TRUE;
    return  1;
    }
        catch( _com_error &e)
    {
            _bstr_t bstrSource(e.Source());
            _bstr_t bs =  _bstr_t(" Error: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") 
                + _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ") 
                + _bstr_t(e.Description());
            
            MessageBox(0,bs,bstrSource, MB_OK);
    InfoStd=FALSE;
    return 0;
        }           
    }BOOL CStationINFO::GetInfoStd()
    {
    return InfoStd;
    }CStationINFO::~CStationINFO()
    {
    if(cpProvince!=NULL)delete [] cpProvince;
    if(cpStations!=NULL)delete [] cpStations; 
    //MessageBox(NULL,_T("Stdinfo"),_T("leave"),MB_OK);
    }
    #undef UC
      

  4.   

    #import "C:\Program Files\Common Files\SYSTEM\ADO\MSADO15.DLL" no_namespace rename("EOF","ADOEOF")
      

  5.   

    直接在IDL文件中导入msado15.idl文件
    import "msado15.idl"
    然后就可以用_Connection _Recordset来定义变量了
      

  6.   

    我感觉你的困惑是对com功能定位上.  
    现在谈的三层构架解决方案 com就能很好的担任中间层--商业逻辑层.
    比如你当前的b/s系统:
    web是表示层,用来接收客户信息并返回数据信息.
    商业逻辑层,在国外你会见到大多是用一系列组件来处理,它负责于个分布式的
        数据库大交道,负责提供各种接口供表示层调取.
    一些安全性高或大型的系统,常是这种路子.  
    以前国内的b/s通常是asp代码担任了逻辑层的角色,这样做简单,快捷,但安全性
    能相对薄弱. 比方人家读破你的asp,那你的数据库服务器就裸露待人攻击了.
    而若是你用组件来替代相关的asp代码,效果不言而寓,象招商银行就是这么干的.
    使用ado:
    atl的接口文件(.idl) 你可不用去管它,在stdafx.h中,象上面的虾哥虾弟们那样:
    #import "C:\Program Files\Common Files\SYSTEM\ADO\MSADO15.DLL" no_namespace rename("EOF","ADOEOF")然后在接口函数实现里,调用ado就成,具体方法搜下坛子.
      

  7.   

    谢谢大家。
    对于bojinyu(沙鱼) 的代码,我正在研究,感谢您的慷慨。
    to fanchka(狼仔) :您的感觉非常正确,我实际上是得到了一套b/s系统,数据库结构和script代码都有,但是其逻辑层正如您所说,使用了dll,我现在想偷懒:),借鉴其数据库和script代码开发自己的系统,但是在怎么实现逻辑层上有困惑。能不能用别的办法代替dll,而不需要大的改动script呢?安全方面暂且放在一边。因为对开发dll确实是一窍不通。一定会给几位加分的。分数不够我就再开帖子:)
      

  8.   

    to: royya(阿瑟)dll的实质,你就可以把它当作一些函数的集合. 调用dll,调用接口方法,
    就如同调用集合中的函数一样,没什么太奇妙的.  如果,你想通过脚本
    来替代dll的逻辑,没什么好的方法,查看接口的实现代码,再把他的思路转
    成脚本代码. 呵呵,我说的都感到麻烦,你做的怕更要烦. 若是系统小,这样子
    该是可以,若是系统大,那你可要和老板多蹭点时间.good luck.