When using VC, VB, Delphi, and other advanced languages to write database applications, you often need to configure ODBC data sources on the control panel. It may be difficult for users to configure ODBC data sources. Moreover, in practical applications, users often require access to different data sources in the same application. Therefore, the general loading method has insurmountable defects. To facilitate the use of applications, this article uses VC as the development environment to introduce two methods for dynamic loading of ODBC system data sources in applications. Method 1: Modify the Registry Design Concept Generally, after you configure the ODBC data source in the control panel, the Windows System adds some sub-keys to the Registry to store the user's configuration results. When the application needs to use the data source, Windows notifies the underlying interface to check the configuration of the data source in the registry. If you delete an ODBC data source, it will also respond in the registry. If the configured data source is a user data source, Windows will modify the HKEY_CURRENT_USER/software/ODBC in the registry. INI subkey; if the configured data source is a system data source, Windows will modify the HKEY_LOCAL_MACHINE/software/ODBC in the registry. INI primary key. Therefore, we can use the registry editing function in the Windows API in the application to complete windows work, so that we can dynamically load the data source. Implementation For different types of data sources, the Registry must be modified in two ways. One is in ODBC. create a sub-key with the same name as the data source description under the INI sub-key, and create items related to the data source configuration under the sub-key; the other is in ODBC. create a new item under the INI/ODBC Data Sources subkey to inform the driver manager of the ODBC data source type. The following code uses the configuration of a Microsoft Access Data source as an example to describe the function to implement this function. /* Strsourcename is the name of the data source to be created, strsourcedb is the database storage path, and strdescription is the description string of the data source. */ Bool cloadodbcdlg: loaddbsource (cstring strsourcename, cstring strsourcedb, cstring strdescription) { // Store the opened registry key Hkey; DWORD dw; // Stores the returned values of registry API function execution Long lreturn; // Store the sub-keys to be opened Cstring strsubkey; // Check whether Ms access ODBC driver: odbcjt32.dll is installed // Obtain the Windows System directory Char Sysdir [max_path]; Char drvname [] = "// odbcjt32.dll "; : Getsystemdirectory (Sysdir, max_path ); Strcat (Sysdir, drvname ); Cfilefind findfile; If (! Findfile. findfile (Sysdir )) { Afxmessagebox ("your computer system does not have the ODBC driver odbcjt32.dll with MS Access installed, you will not be able to load this type of data source. ", Mb_ OK | mb_iconstop ); Return false; } Strsubkey = "software // ODBC. ini //" + strsourcename; // Create a subkey for the ODBC data source in the Registry Lreturn =: regcreatekeyex (HKEY_LOCAL_MACHINE, (lpctstr) strsubkey, 0, null, reg_option_non_volatile, key_write, null, & hkey, & DW ); If (lreturn! = Error_success) Return false; // Set parameters of the Data Source 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 ); // Create a jet subkey for the ODBC Data Source 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; // Set parameters for this subkey 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 ); // Set the ODBC database engine name Lreturn =: regopenkeyex (HKEY_LOCAL_MACHINE, "software // 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; } In dynamic loading, only the database files, data source descriptions, and data source descriptions are changed. Therefore, the above functions can meet most of the requirements in applications. If more changes are required in the application, you can also change the function parameters. You can use overload functions with different parameters to dynamically load multiple types of data sources. Method 2: Use DLL Design Concept The dynamic link library odbcinst. dll in the Windows system subdirectory provides a function sqlconfigdatasource () that can dynamically add, modify, and delete data sources (). The function is prototype as follows: Bool sqlconfigdatasource (hwnd hwndparent, word frequest, lpcstr lpszdriver, lpcstr lpszattributes ); The hwndparent parameter is the parent window handle. If the value is null, the dialog box related to the parent window is not displayed. The frequest parameter can be set to one of the following values: Odbc_add_dsn: adds a new user data source; Odbc_config_dsn: Modify (configure) an existing user data source; Odbc_remove_dsn: delete an existing user data source; Odbc_add_sys_dsn: Add a new system data source; Odbc_config_sys_dsn: modifies (configures) an existing system data source; Odbc_remove_sys_dsn: delete an existing system data source. The lpszdriver parameter is used to pass the database engine name, which is equivalent to the strdbtype variable in method 1. The lpszattirbutes parameter is the value of a keyword, that is, a series of "keyname = value" strings separated, for example, DSN = Personnel Data/0uid = Smith/0 database = personnel. For detailed settings of this parameter, see the help documentation of sqlconfigdatasource () function and various ODBC driver documentation in msdn. Implementation Because the default library file of VC does not contain the sqlconfigdatasource () function, before using this function, you need. the H file is included in the header file of the project. In the settings Properties dialog box of the project, add odbccp32.lib to the object/library modules edit box on the Link property page, and ensure that the file odbccp32.dll is under system32. Take Microsoft Access as an example. Set the data source name to demo and the data source description to "Sample Data Source". Then, add the following code where the data source needs to be dynamically loaded: : Sqlconfigdatasource (null, odbc_add_sys_dsn, "Microsoft Access Driver (*. mdb)", "DSN = demo/0 description = Sample Database "); Summary Both methods can dynamically load various types of ODBC data sources and pass debugging in Windows 95/98/NT/2000. Method 1 requires a lot of code for implementation. method 2 requires less code, but requires support for additional files. As the flexibility of data source configuration increases, in order to form the lpszattributes string, the code length is also increased. Since the data source is configured on the control panel, the programmer can get a more intuitive understanding of the values in the Registry and the corresponding item names, in addition to reading the relevant driver documentation, programmers can configure the ODBC data source through the control panel before programming, and then program according to the corresponding part of the Registry. |