📄 setup.c
字号:
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind *//*** SETUP.C - This is the ODBC sample driver code for** setup.**** This code is furnished on an as-is basis as part of the ODBC SDK and is** intended for example purposes only.***//*-------------------------------------------------------------------------- setup.c -- Sample ODBC setup This code demonstrates how to interact with the ODBC Installer. These functions may be part of your ODBC driver or in a separate DLL. The ODBC Installer allows a driver to control the management of data sources by calling the ConfigDSN entry point in the appropriate DLL. When called, ConfigDSN receives four parameters: hwndParent ---- Handle of the parent window for any dialogs which may need to be created. If this handle is NULL, then no dialogs should be displayed (that is, the request should be processed silently). fRequest ------ Flag indicating the type of request (add, configure (edit), or remove). lpszDriver ---- Far pointer to a null-terminated string containing the name of your driver. This is the same string you supply in the ODBC.INF file as your section header and which ODBC Setup displays to the user in lieu of the actual driver filename. This string needs to be passed back to the ODBC Installer when adding a new data source name. lpszAttributes- Far pointer to a list of null-terminated attribute keywords. This list is similar to the list passed to SQLDriverConnect, except that each key-value pair is separated by a null-byte rather than a semicolon. The entire list is then terminated with a null-byte (that is, two consecutive null-bytes mark the end of the list). The keywords accepted should be those for SQLDriverConnect which are applicable, any new keywords you define for ODBC.INI, and any additional keywords you decide to document. ConfigDSN should return TRUE if the requested operation succeeds and FALSE otherwise. The complete prototype for ConfigDSN is: BOOL FAR PASCAL ConfigDSN(HWND hwndParent, WORD fRequest, LPSTR lpszDriver, LPCSTR lpszAttributes) Your setup code should not write to ODBC.INI directly to add or remove data source names. Instead, link with ODBCINST.LIB (the ODBC Installer library) and call SQLWriteDSNToIni and SQLRemoveDSNFromIni. Use SQLWriteDSNToIni to add data source names. If the data source name already exists, SQLWriteDSNToIni will delete it (removing all of its associated keys) and rewrite it. SQLRemoveDSNToIni removes a data source name and all of its associated keys. For NT compatibility, the driver code should not use the Get/WritePrivateProfileString windows functions for ODBC.INI, but instead, use SQLGet/SQLWritePrivateProfileString functions that are macros (16 bit) or calls to the odbcinst.dll (32 bit).--------------------------------------------------------------------------*/// Includes ----------------------------------------------------------------#include "myodbc.h" // Local include files#undef VOID // Because of ctl3d.h#define VOID void#include <ctl3d.h>#include "odbcinst.h" // ODBC installer prototypes#include <string.h> // C include files#include "dialogs.h"// Constants ---------------------------------------------------------------const char EMPTYSTR []= "";const char OPTIONON []= "Yes";const char OPTIONOFF []= "No";// ODBC.INI keywordsconst char ODBC_INI []="ODBC.INI"; // ODBC initialization fileconst char INI_KDESC []="Description"; // Data source descriptionconst char INI_KDB []="Database";const char INI_KSERVER []="Server";const char INI_KUSER []="User"; // Second optionconst char INI_KPASSWORD[] = "Password";const char INI_KPORT [] = "Port";const char INI_KFLAG [] = "Flag";const char INI_SDEFAULT[]= "Default";const char szTranslateName[] = "TranslationName";const char szTranslateDLL[] = "TranslationDLL";const char szTranslateOption[] = "TranslationOption";const char szUnkTrans[] = "Unknown Translator";// Attribute string look-up table (maps keys to associated indexes)static struct { char szKey[MAXKEYLEN]; int iKey;} s_aLookup[] = { "DSN", KEY_DSN, "DESC", KEY_DESC, "Description",KEY_DESC, "Database", KEY_DB, "DB", KEY_DB, "Server", KEY_SERVER, "UID", KEY_USER, "User", KEY_USER, "Password", KEY_PASSWORD, "PWD", KEY_PASSWORD, "Port", KEY_PORT, "Flag", KEY_FLAG, "",0};static void INTFUNC CenterDialog (HWND hdlg);int CALLBACK ConfigDlgProc (HWND hdlg,WORD wMsg,WPARAM wParam, LPARAM lParam);BOOL CALLBACK SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);/* ConfigDSN --------------------------------------------------------------- Description: ODBC Setup entry point This entry point is called by the ODBC Installer (see file header for more details) Input : hwnd ----------- Parent window handle fRequest ------- Request type (i.e., add, config, or remove) lpszDriver ----- Driver name lpszAttributes - data source attribute string Output : TRUE success, FALSE otherwise--------------------------------------------------------------------------*/BOOL EXPFUNC ConfigDSN (HWND hwnd, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes){ BOOL fSuccess; // Success/fail flag GLOBALHANDLE hglbAttr; LPSETUPDLG lpsetupdlg; // Allocate attribute array hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG)); if (!hglbAttr) return FALSE; lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr); // Parse attribute string if (lpszAttributes) ParseAttributes(lpszAttributes, lpsetupdlg); // Save original data source name if (lpsetupdlg->aAttr[KEY_DSN].fSupplied) lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->aAttr[KEY_DSN].szAttr); else lpsetupdlg->szDSN[0] = '\0'; // Remove data source if (ODBC_REMOVE_DSN == fRequest) { // Fail if no data source name was supplied if (!lpsetupdlg->aAttr[KEY_DSN].fSupplied) fSuccess = FALSE; // Otherwise remove data source from ODBC.INI else fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->aAttr[KEY_DSN].szAttr); } // Add or Configure data source else { // Save passed variables for global access (e.g., dialog access) lpsetupdlg->hwndParent = hwnd; lpsetupdlg->lpszDrvr = lpszDriver; lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest); lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->aAttr[KEY_DSN].szAttr, INI_SDEFAULT); // Display the appropriate dialog (if parent window handle supplied) if (hwnd) { // Display dialog(s) fSuccess = (IDOK == DialogBoxParam(s_hModule, MAKEINTRESOURCE(CONFIGDSN), hwnd, ConfigDlgProc, (LONG)(LPSTR)lpsetupdlg)); } else if (lpsetupdlg->aAttr[KEY_DSN].fSupplied) fSuccess = SetDSNAttributes(hwnd, lpsetupdlg); else fSuccess = FALSE; } GlobalUnlock(hglbAttr); GlobalFree(hglbAttr); return fSuccess;}/* CenterDialog ------------------------------------------------------------ Description: Center the dialog over the frame window Input : hdlg -- Dialog window handle Output : None--------------------------------------------------------------------------*/static void INTFUNC CenterDialog(HWND hdlg){ HWND hwndFrame; RECT rcDlg, rcScr, rcFrame; int cx, cy; hwndFrame = GetParent(hdlg); GetWindowRect(hdlg, &rcDlg); cx = rcDlg.right - rcDlg.left; cy = rcDlg.bottom - rcDlg.top; GetClientRect(hwndFrame, &rcFrame); ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left)); ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right)); rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1); rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1); rcDlg.bottom = rcDlg.top + cy; rcDlg.right = rcDlg.left + cx; GetWindowRect(GetDesktopWindow(), &rcScr); if (rcDlg.bottom > rcScr.bottom) { rcDlg.bottom = rcScr.bottom; rcDlg.top = rcDlg.bottom - cy; } if (rcDlg.right > rcScr.right) { rcDlg.right = rcScr.right; rcDlg.left = rcDlg.right - cx; } if (rcDlg.left < 0) rcDlg.left = 0; if (rcDlg.top < 0) rcDlg.top = 0; MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE); return;}/* ConfigDlgProc ----------------------------------------------------------- Description: Manage add data source name dialog Input : hdlg --- Dialog window handle wMsg --- Message wParam - Message parameter lParam - Message parameter Output : TRUE if message processed, FALSE otherwise--------------------------------------------------------------------------*/int CALLBACK ConfigDlgProc (HWND hdlg,WORD wMsg,WPARAM wParam,LPARAM lParam){ switch (wMsg) { // Initialize the dialog case WM_INITDIALOG: { LPSETUPDLG lpsetupdlg; Ctl3dRegister (s_hModule); SetWindowLong(hdlg, DWL_USER, lParam);#ifdef WIN32 Ctl3dSubclassDlg(hdlg, CTL3D_ALL);#else Ctl3dSubclassDlgEx(hdlg, CTL3D_ALL);#endif CenterDialog(hdlg); // Center dialog lpsetupdlg = (LPSETUPDLG) lParam; set_attributes(lpsetupdlg); // Initialize dialog fields // NOTE: Values supplied in the attribute string will always // override settings in ODBC.INI SetDlgItemText(hdlg, IDC_DSNAME, lpsetupdlg->aAttr[KEY_DSN].szAttr); SetDlgItemText(hdlg, IDC_DESC, lpsetupdlg->aAttr[KEY_DESC].szAttr); SetDlgItemText(hdlg, IDC_DB, lpsetupdlg->aAttr[KEY_DB].szAttr); SetDlgItemText(hdlg, IDC_SERVER, lpsetupdlg->aAttr[KEY_SERVER].szAttr); SetDlgItemText(hdlg, IDC_USER, lpsetupdlg->aAttr[KEY_USER].szAttr); SetDlgItemText(hdlg, IDC_PASSWORD, lpsetupdlg->aAttr[KEY_PASSWORD].szAttr); SetDlgItemText(hdlg, IDC_PORT, lpsetupdlg->aAttr[KEY_PORT].szAttr); SetDlgItemText(hdlg, IDC_FLAG, lpsetupdlg->aAttr[KEY_FLAG].szAttr); if (lpsetupdlg->fDefault) { EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE); EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE); } else SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L); SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L); SendDlgItemMessage(hdlg, IDC_DB, EM_LIMITTEXT, (WORD)(NAME_LEN), 0L); SendDlgItemMessage(hdlg, IDC_SERVER, EM_LIMITTEXT, (WORD)(MAXSERVER-1), 0L); SendDlgItemMessage(hdlg, IDC_USER, EM_LIMITTEXT, (WORD)(MAXUSER-1), 0L); SendDlgItemMessage(hdlg, IDC_PASSWORD, EM_LIMITTEXT, (WORD)(MAXPASSWORD-1), 0L); SendDlgItemMessage(hdlg, IDC_PORT, EM_LIMITTEXT, (WORD) 5, 0L); SendDlgItemMessage(hdlg, IDC_FLAG, EM_LIMITTEXT, (WORD) 5, 0L); return TRUE; // Focus was not set }#ifdef WIN32 case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: return (BOOL)Ctl3dCtlColorEx(wMsg, wParam, lParam); case WM_SETTEXT: case WM_NCPAINT: case WM_NCACTIVATE: SetWindowLong(hdlg, DWL_MSGRESULT, Ctl3dDlgFramePaint(hdlg, wMsg, wParam, lParam)); return TRUE;#endif case WM_SYSCOLORCHANGE: return Ctl3dColorChange(); // Process buttons case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { // Ensure the OK button is enabled only when a data source name // is entered case IDC_DSNAME: if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) { char szItem[MAXDSNAME]; // Edit control text // Enable/disable the OK button EnableWindow(GetDlgItem(hdlg, IDOK), GetDlgItemText(hdlg, IDC_DSNAME, szItem, sizeof(szItem))); return TRUE; } break; // Accept results case IDOK:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -