VC中动态加载ODBC的方法

分类: VC.NET   出处:iocblog整理  更新时间:2009-08-17   添加到收藏  

  在使用 vc、 vb、 delphi等高级语言编写数据库应用程序时,往往需要用户自己在控制面板中配置 odbc数据源。对于一般用户而言,配置 odbc数据源可能是一件比较困难的工作。而且,在实际应用中,用户往往要求在同一个应用程序中访问不同的数据源,因此采用一般的加载方法就有了无法克服的缺陷。为能在程序中完成这一工作,方便应用程序的使用,本文以 vc为开发环境介绍两种在应用程序中动态加载 odbc系统数据源的方法。

  方法一:修改注册表

  设计思路

  一般情况下,当用户在控制面板中配置好 odbc数据源后, windows系统便在注册表中加入了一些子键来存储用户的配置结果。当应用程序需要用到数据源时, windows便会通知底层接口查阅注册表中该数据源的配置。如果用户删除了某个 odbc数据源,那么也会在注册表中有所反应。如果配置的数据源是用户数据源, windows系统便会修改注册表的 hkey_current_usersoftwareodbcodbc.ini子键;如果配置的数据源是系统数据源, windows系统便会修改注册表的 hkey_local_machinesoftwareodbcodbc.

  ini主键。因此,我们可以在应用程序中使用 windows api中的注册表编辑函数来完成 windows所做的工作,这样就可以达到动态加载数据源的目的。具体实现对于不同类型的数据源,注册表的修改也各有不同,但基本上都要修改两个地方。一个是在 odbc.ini子键下建立一个与数据源描述名同名的子键,并在该子键下建立与数据源配置相关的项;另一个是在 odbc.iniodbc data sources子键下建立一个新项以便告诉驱动程序管理器 odbc数据源的类型。下面以配置一个 microsoft access数据源为例给出实现此功能的函数的代码。

/* strsourcename是要创建的数据源名, strsourcedb是数据库存放路径, strdescription是数据源的描述字符串。* /

bool cloadodbcdlg:: loaddbsource(cstring strsourcename,cstring strsourcedb, cstring strdescription)

{

//存放打开的注册表键

hkey hkey;

dword dw;

//存放注册表 api函数执行的返回值

long lreturn;

//存放要打开的子键

cstring strsubkey;

//检测是否安装了 ms access odbc driver:odbcjt32.dll

//获得 windows系统目录

char sysdir[max_path];

char drvname[]=" \odbcjt32.dll" ;

::getsystemdirectory (sysdir,max_path);

strcat(sysdir,drvname);

cfilefind findfile;

if(!findfile.findfile (sysdir))

{

afxmessagebox("您的计算机系统中没有安装 ms access的 odbc驱动程序 odbcjt32.dll,您将无法加载该类数据源。 " ,mb_ok|mb_iconstop);

return false;

}

strsubkey=" software\odbc\odbc.ini\"+ strsourcename;
//创建 ODBC数据源在注册表中的子键

lReturn=::RegCreateKeyEx(HKEY_LOCAL_

MACHINE,(LPCTSTR)strSubKey,0,NULL,REG_OPTION

_NON_VOLATILE,KEY_WRITE,NULL,& hKey,& dw);

if(lReturn != ERROR_SUCCESS)

return false;

//设置数据源的各项参数

CString strDbq=strSourceDb;

CString strDriver=sysDir;

DWORD dwDriverId=25;

CString strFil=" MS Access" ;

CString strPwd=strSourceName;

DWORD dwSafeTransactions=0;

CString strUid=strSourceName;

::RegSetValueEx (hKey," DBQ" ,0L,REG_SZ,

(CONST BYTE* )((LPCTSTR) strDbq),strDbq .GetLength ()) ; ::RegSetValueEx (hKey," Description" ,0L,REG_SZ,(CONST BYTE* )((LPCTSTR)strDescription),strDescription.GetLength());

::RegSetValueEx (hKey," Driver" ,0L,REG_SZ,(CONST BYTE* )((LPCTSTR)strDriver),strDriver .GetLength ());

::RegSetValueEx (hKey," DriverId" ,0L,REG_DWORD,(CONST BYTE* )(& dwDriverId),sizeof(dw));

::RegSetValueEx (hKey," FIL" ,0L,REG_SZ,

(CONST BYTE* )((LPCTSTR) strFil),strFil .GetLength ());

::RegSetValueEx (hKey," PWD" ,0L,REG_SZ,

(CONST BYTE* )((LPCTSTR)strPwd),strPwd.GetLength ()) ; ::RegSetValueEx (hKey," SafeTransactions" ,0L,

REG_DWORD,(CONST BYTE* )(& dwSafeTransactions),sizeof(dw));

::RegSetValueEx (hKey," UID" ,0L,REG_SZ,

(CONST BYTE* )((LPCTSTR)strUid),strUid .GetLength ()); ::RegCloseKey(hKey);

//创建 ODBC数据源的 Jet子键

strSubKey+ =" \\Engines\\Jet" ;

lReturn=::RegCreateKeyEx (HKEY_LOCAL_MACHINE ,(LPCTSTR)strSubKey,0,NULL,REG_OPTION_NON_

VOLATILE,KEY_WRITE,NULL,& hKey,& dw);

if(lReturn != ERROR_SUCCESS)

return false;

//设置该子键下的各项参数

CString strImplict=" " ;

CString strUserCommit=" Yes" ;

DWORD dwPageTimeout=5;

DWORD dwThreads=3;

DWORD dwMaxBufferSize=2048;

::RegSetValueEx (hKey," ImplictCommitSync" ,0L,REG_SZ,(CONST BYTE* )((LPCTSTR)strImplict),strImplict.GetLength ()+ 1);

::RegSetValueEx (hKey," MaxBufferSize" ,0L,REG_DWORD,(CONST BYTE* )(& dwMaxBufferSize),sizeof(dw));

::RegSetValueEx (hKey," PageTimeout" ,0L,REG_DWORD,(CONST BYTE* )(& dwPageTimeout),sizeof(dw));

::RegSetValueEx (hKey," Threads" ,0L,REG_DWORD,(CONST BYTE* )(& dwThreads),sizeof(dw));

::RegSetValueEx (hKey," UserCommitSync" ,0L,REG_SZ,(CONST BYTE* )((LPCTSTR)strUserCommit),strUserCommit.GetLength ());

::RegCloseKey (hKey);(来源www.iocblog.net)

[1] [2] 下一页


Tag: ODBC



文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。