| 域名空间 下载中心 社区论坛 信息公告 MY小屋 |
![]() |
联系我们 设为首页 加入收藏 |
|
首页 | 新闻资讯 | 编程开发 | 网页设计 | 图形图象 | 网络媒体 | 网站模板 | 数 据 库 | 投稿 论坛 | 操作系统 | 系统优化 | 网络安全 | 黑客技术 | 硬件学堂 | 硬件报价 | 服 务 器 | 地图 专题 | 应用软件 | 聊天通讯 | Q Q 专栏 | 建站经验 | 在线工具 | 站长Club | 注 册 表 | 旧版 社会 | 游戏娱乐 | 设计欣赏 | 疑难解答 | 社区论坛 | 韩国素材 | 素材图库 | 广告服务 | 服务 |
| 新版上线![旧版] | |||||
注:打开慢时请稍等
在VC中动态加载ODBC的方法http://www.iyit.net 日期:2006-5-23 11:37:35 来源:本站整理转载 点击: |
方法一:修改注册表 设计思路 一般情况下,当用户在控制面板中配置好ODBC数据源后,Windows系统便在注册表中加入了一些子键来存储用户的配置结果。当应用程序需要用到数据源时,Windows便会通知底层接口查阅注册表中该数据源的配置。如果用户删除了某个ODBC数据源,那么也会在注册表中有所反应。如果配置的数据源是用户数据源, Windows系统便会修改注册表的HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI子键;如果配置的数据源是系统数据源,Windows系统便会修改注册表的HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI主键。因此,我们可以在应用程序中使用Windows API中的注册表编辑函数来完成Windows所做的工作,这样就可以达到动态加载数据源的目的。 具体实现 对于不同类型的数据源,注册表的修改也各有不同,但基本上都要修改两个地方。一个是在 ODBC.INI子键下建立一个与数据源描述名同名的子键,并在该子键下建立与数据源配置相关的项;另一个是在ODBC.INI\ODBC 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, "ImplicitCommitSync", 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); //设置ODBC数据库引擎名称 lReturn=::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\ODBC\\ODBC.INI\\ODBC Data Sources", 0L, KEY_WRITE, &hKey); if(lReturn != ERROR_SUCCESS) return false; CString strDbType="Microsoft Access Driver (*.mdb)"; ::RegSetValueEx(hKey, strSourceName, 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strDbType), strDbType.GetLength()); return true; } 由于在动态加载中,一般只会改变数据库文件、数据源说明以及数据源描述,故上述函数可以实现应用中的大部分要求。如果应用中还需要作更多的改变,那么也可以通过改变函数参数的方式加以实现。对于需要动态加载多种类型数据源的情况,可以用具有不同参数的重载函数去实现。 方法二:利用DLL 设计思路 Windows系统子目录中的动态链接库Odbcinst.dll提供了一个可以动态地增加、修改和删除数据源的函数SQLConfigDataSource()。该函数的原型如下: BOOL SQLConfigDataSource(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes); hwndParent参数是父窗口句柄。如果该值为NULL,将不会显示与父窗口有关的对话框。 fRequest参数可以设置为下面的数值之一: ODBC_ADD_DSN:增加一个新的用户数据源; ODBC_CONFIG_DSN:修改(配置)一个已经存在的用户数据源; ODBC_REMOVE_DSN:删除一个已经存在的用户数据源; ODBC_ADD_SYS_DSN:增加一个新的系统数据源; ODBC_CONFIG_SYS_DSN:修改 (配置)一个已经存在的系统数据源; ODBC_REMOVE_SYS_DSN:删除一个已经存在的系统数据源。 lpszDriver参数用于传递数据库引擎的名字,等同于方法一中strDbType变量。 lpszAttirbutes参数是关键字的值,即一连串的"keyname=value"字符串,每两个字符串之间用 "\"隔开,如 DSN = Personnel Data\0UID=Smith\0DATABASE=Personnel。关于该参数的详细设置请参阅MSDN中SQLConfigDataSource()函数的帮助文档和各种ODBC驱动程序文档。 具体实现 由于VC的缺省库文件中不包含SQLConfigDataSource()函数,因此使用该函数之前需要将odbcinst.h文件包含在工程的头文件中,在工程的Settings属性对话框Link属性页的Object/library modules编辑框中增加odbccp32.lib,同时保证系统目录system32下有文件odbccp32.dll。 仍以Microsoft Access为例,设置数据源名为demo,数据源描述为"示例数据源",那么在需要动态加载数据源的地方加入下列代码即可: ::SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, "Microsoft Access Driver (*.mdb)", "DSN=demo\0Description=示例数据库"); 小结 上述两种方法都可以实现动态加载各种类型的ODBC数据源,并且在Windows95/98/NT/2000环境下调试通过。方法一在实现时需要较多的代码,方法二所需代码虽少,但需要额外文件的支持,而且随着数据源配置的灵活性的增加,为了形成lpszAttributes字符串,其代码长度也会相应增加。由于从控制面板配置数据源使得程序员可以获得更加直观的理解,所以对于注册表中各项值以及相应项名称的获得除了可以查阅相关驱动程序的文档外,程序员也可以在编程前先通过控制面板配置ODBC数据源,然后根据注册表中相应部分的内容进行编程。
文件下载: 点击下载 [18.5KB],[rar格式] 编辑:黑鹰 [发送给好友] [打印本页] [关闭窗口] [返回顶部] 上一篇:Visual C++ 中的ODBC编程 下一篇:多线程DAO处理 转载请注明来源:www.iyit.net 特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。 |
| 最新更新 | 热点排行 | 推荐新闻 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| 友情链接 | ||||||
| 设置首 页 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接 |
| |||||||