]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/db/dbtest.cpp
interface additions (mostly for new generic/toolwin)
[wxWidgets.git] / samples / db / dbtest.cpp
index b859661ca3d573b092145608295c2098cb4106d7..9643f3dff5aa2097586bf9455ec0ac0bf2416c00 100644 (file)
@@ -16,7 +16,7 @@
     donated by the development team at Remstar International.
 
     The table this sample is based on is developer contact table, and shows
-    some of the simple uses of the database classes wxDB and wxTable.
+    some of the simple uses of the database classes wxDb and wxDbTable.
 
  *  SYNOPSIS END
  */
@@ -42,9 +42,9 @@
 #include <stdio.h>                  /* Included strictly for reading the text file with the database parameters */
 
 #include <wx/db.h>                  /* Required in the file which will get the data source connection */
-#include <wx/dbtable.h>             /* Has the wxTable object from which all data objects will inherit their data table functionality */
+#include <wx/dbtable.h>             /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
 
-extern DbList WXDLLEXPORT *PtrBegDbList;    /* from db.cpp, used in getting back error results from db connections */
+extern wxDbList WXDLLEXPORT *PtrBegDbList;    /* from db.cpp, used in getting back error results from db connections */
 
 #include "dbtest.h"                 /* Header file for this demonstration program */
 #include "listdb.h"                 /* Code to support the "Lookup" button on the editor dialog */
@@ -61,28 +61,29 @@ DatabaseDemoFrame *DemoFrame;       /* Pointer to the main frame */
  * for user login names and passwords, getting workstation settings, etc.
  * ---> IMPORTANT <---
  * 
- *        For each database object created which uses this wxDB pointer
+ *        For each database object created which uses this wxDb pointer
  *    connection to the database, when a CommitTrans() or RollBackTrans()
- *    will commit or rollback EVERY object which uses this wxDB pointer.
+ *    will commit or rollback EVERY object which uses this wxDb pointer.
  *
- *    To allow each table object (those derived from wxTable) to be 
+ *    To allow each table object (those derived from wxDbTable) to be 
  *    individually committed or rolled back, you MUST use a different
- *    instance of wxDB in the constructor of the table.  Doing so creates 
+ *    instance of wxDb in the constructor of the table.  Doing so creates 
  *        more overhead, and will use more database connections (some DBs have
  *    connection limits...), so use connections sparringly.
  *
  *        It is recommended that one "main" database connection be created for
  *        the entire program to use for READ-ONLY database accesses, but for each
  *        table object which will do a CommitTrans() or RollbackTrans() that a
- *        new wxDB object be created and used for it.
+ *        new wxDb object be created and used for it.
  */
  
-wxDB    *READONLY_DB;
+wxDb    *READONLY_DB;
 
 /*
  * This function will return the exact string(s) from the database engine
  * indicating all error conditions which have just occured during the
- * last call to the database engine.
+ * last call to the database engine for the database connection pointed
+ * to by pDb.
  *
  * This demo uses the returned string by displaying it in a wxMessageBox.  The
  * formatting therefore is not the greatest, but this is just a demo, not a
@@ -91,9 +92,10 @@ wxDB    *READONLY_DB;
  * NOTE: The value returned by this function is for temporary use only and
  *       should be copied for long term use
  */
-char *GetExtendedDBErrorMsg(char *ErrFile, int ErrLine)
+const char *GetExtendedDBErrorMsg(wxDb *pDb, char *ErrFile, int ErrLine)
 {
     static wxString msg;
+    msg = "";
 
     wxString tStr;
 
@@ -103,35 +105,30 @@ char *GetExtendedDBErrorMsg(char *ErrFile, int ErrLine)
         msg += ErrFile;
         msg += "   Line: ";
         tStr.Printf("%d",ErrLine);
-        msg += tStr.GetData();
+        msg += tStr.c_str();
         msg += "\n";
     }
 
     msg.Append ("\nODBC errors:\n");
     msg += "\n";
     
-    /* Scan through each database connection displaying 
-     * any ODBC errors that have occured. */
-    for (DbList *pDbList = PtrBegDbList; pDbList; pDbList = pDbList->PtrNext)
-    {
-        // Skip over any free connections
-        if (pDbList->Free)
-            continue;
-        // Display errors for this connection
-        int i;
-        for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
+    // Display errors for this connection
+    int i;
+    for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
+    {
+        if (pDb->errorList[i])
         {
-            if (pDbList->PtrDb->errorList[i])
-            {
-                msg.Append(pDbList->PtrDb->errorList[i]);
-                if (strcmp(pDbList->PtrDb->errorList[i],"") != 0)
-                    msg.Append("\n");
-            }
+            msg.Append(pDb->errorList[i]);
+            if (wxStrcmp(pDb->errorList[i],"") != 0)
+                msg.Append("\n");
+            // Clear the errmsg buffer so the next error will not
+            // end up showing the previous error that have occurred
+            wxStrcpy(pDb->errorList[i],"");
         }
     }
     msg += "\n";
 
-    return (char*) (const char*) msg;
+    return msg.c_str();
 }  // GetExtendedDBErrorMsg
 
 
@@ -145,7 +142,9 @@ bool DatabaseDemoApp::OnInit()
 
     // Make a menubar
     wxMenu *file_menu = new wxMenu;
-    file_menu->Append(FILE_CREATE, "&Create contact table");
+    file_menu->Append(FILE_CREATE, "&Create CONTACT table");
+    file_menu->Append(FILE_RECREATE_TABLE, "&Recreate CONTACT table");
+    file_menu->Append(FILE_RECREATE_INDEXES, "&Recreate CONTACT indexes");
     file_menu->Append(FILE_EXIT, "E&xit");
 
     wxMenu *edit_menu = new wxMenu;
@@ -172,6 +171,9 @@ bool DatabaseDemoApp::OnInit()
     params.Password[0]   = 0;
     params.DirPath[0]    = 0;
 
+    // Show the frame
+    DemoFrame->Show(TRUE);
+
     FILE *paramFile;
     if ((paramFile = fopen(paramFilename, "r")) == NULL)
     {
@@ -186,37 +188,37 @@ bool DatabaseDemoApp::OnInit()
 
     char buffer[1000+1];
     fgets(buffer, sizeof(params.ODBCSource), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.ODBCSource,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.ODBCSource,buffer);
 
     fgets(buffer, sizeof(params.UserName), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.UserName,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.UserName,buffer);
 
     fgets(buffer, sizeof(params.Password), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.Password,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.Password,buffer);
 
     fgets(buffer, sizeof(params.DirPath), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.DirPath,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.DirPath,buffer);
 
     fclose(paramFile);
 
     // Connect to datasource
-    strcpy(DbConnectInf.Dsn,        params.ODBCSource);    // ODBC data source name (created with ODBC Administrator under Win95/NT)
-    strcpy(DbConnectInf.Uid,        params.UserName);      // database username - must already exist in the data source
-    strcpy(DbConnectInf.AuthStr,    params.Password);      // password database username
-    strcpy(DbConnectInf.defaultDir, params.DirPath);       // path where the table exists (needed for dBase)
+    wxStrcpy(DbConnectInf.Dsn,        params.ODBCSource);    // ODBC data source name (created with ODBC Administrator under Win95/NT)
+    wxStrcpy(DbConnectInf.Uid,        params.UserName);      // database username - must already exist in the data source
+    wxStrcpy(DbConnectInf.AuthStr,    params.Password);      // password database username
+    wxStrcpy(DbConnectInf.defaultDir, params.DirPath);       // path where the table exists (needed for dBase)
 
-    READONLY_DB = GetDbConnection(&DbConnectInf);
+    READONLY_DB = wxDbGetConnection(&DbConnectInf);
     if (READONLY_DB == 0)
     {
         wxMessageBox("Unable to connect to the data source.\n\nCheck the name of your data source to verify it has been correctly entered/spelled.\n\nWith some databases, the user name and password must\nbe created with full rights to the CONTACT table prior to making a connection\n(using tools provided by the database manufacturer)", "DB CONNECTION ERROR...",wxOK | wxICON_EXCLAMATION);
         DemoFrame->BuildParameterDialog(NULL);
-        strcpy(DbConnectInf.Dsn,        "");
-        strcpy(DbConnectInf.Uid,        "");
-        strcpy(DbConnectInf.AuthStr,    "");
+        wxStrcpy(DbConnectInf.Dsn,        "");
+        wxStrcpy(DbConnectInf.Uid,        "");
+        wxStrcpy(DbConnectInf.AuthStr,    "");
         wxMessageBox("Now exiting program.\n\nRestart program to try any new settings.","Notice...",wxOK | wxICON_INFORMATION);
         return(FALSE);
     }
@@ -224,36 +226,77 @@ bool DatabaseDemoApp::OnInit()
     DemoFrame->BuildEditorDialog();
 
     // Show the frame
-    DemoFrame->Show(TRUE);
+    DemoFrame->Refresh();
 
     return TRUE;
 }  // DatabaseDemoApp::OnInit()
 
+
 BEGIN_EVENT_TABLE(DatabaseDemoFrame, wxFrame)
     EVT_MENU(FILE_CREATE, DatabaseDemoFrame::OnCreate)
+    EVT_MENU(FILE_RECREATE_TABLE, DatabaseDemoFrame::OnRecreateTable)
+    EVT_MENU(FILE_RECREATE_INDEXES, DatabaseDemoFrame::OnRecreateIndexes)
     EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
     EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
     EVT_MENU(ABOUT_DEMO, DatabaseDemoFrame::OnAbout)
     EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
 END_EVENT_TABLE()
 
+
 // DatabaseDemoFrame constructor
 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
-  const wxPoint& pos, const wxSize& size):
-  wxFrame(frame, -1, title, pos, size)
+                                     const wxPoint& pos, const wxSize& size):
+                                        wxFrame(frame, -1, title, pos, size)
 {
-// Put any code in necessary for initializing the main frame here
-}
+    // Put any code in necessary for initializing the main frame here
+    pEditorDlg = NULL;
+    pParamDlg  = NULL;
+}  // DatabaseDemoFrame constructor
+
 
 void DatabaseDemoFrame::OnCreate(wxCommandEvent& event)
 {
-    CreateDataTable();
-}
+    CreateDataTable(FALSE);
+}  // DatabaseDemoFrame::OnCreate()
+
+
+void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& event)
+{
+    CreateDataTable(TRUE);
+}  // DatabaseDemoFrame::OnRecreate()
+
+
+void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent& event)
+{
+    // Using a new connection to the database so as not to disturb
+    // the current cursors on the table in use in the editor dialog
+    Ccontact *Contact = new Ccontact();
+
+    if (!Contact)
+    {
+        wxEndBusyCursor();
+        wxMessageBox("Error allocating memory for 'Ccontact'object.\n\nTable could not be opened.","Error...",wxOK | wxICON_EXCLAMATION);
+        return;
+    }
+
+    if (!Contact->CreateIndexes())
+    {
+       wxEndBusyCursor();
+       wxString tStr;
+       tStr  = "Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n";
+       tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+       wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+    }
+
+    delete Contact;
+    Contact = NULL;
+}  // DatabaseDemoFrame::OnRecreateIndexes()
 
 void DatabaseDemoFrame::OnExit(wxCommandEvent& event)
 {
-    this->Destroy();
-}
+    Close();
+}  // DatabaseDemoFrame::OnExit()
+
 
 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
 {
@@ -261,25 +304,49 @@ void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
         BuildParameterDialog(this);
     else
         wxMessageBox("Cannot change database parameters while creating or editing a record","Notice...",wxOK | wxICON_INFORMATION);
-}
+}  // DatabaseDemoFrame::OnEditParameters()
+
 
 void DatabaseDemoFrame::OnAbout(wxCommandEvent& event)
 {
     wxMessageBox("wxWindows sample program for database classes\n\nContributed on 27 July 1998","About...",wxOK | wxICON_INFORMATION);
-}
+}  // DatabaseDemoFrame::OnAbout()
+
 
 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
 {
     // Put any additional checking necessary to make certain it is alright
     // to close the program here that is not done elsewhere
 
+    // Clean up time
+    if (pEditorDlg && pEditorDlg->Close())
+        pEditorDlg = NULL;
+    else
+    {
+        if (pEditorDlg)
+        {
+            event.Veto();
+            return;
+        }
+    }
+
+    // This function will close all the connections to the database that have been
+    // previously cached.
+    wxDbCloseConnections();
+
+    // Cleans up the environment space allocated for the SQL/ODBC connection handle
+    SQLFreeEnv(DbConnectInf.Henv);
+
     this->Destroy();
+
 }  // DatabaseDemoFrame::OnCloseWindow()
 
 
-void DatabaseDemoFrame::CreateDataTable()
+void DatabaseDemoFrame::CreateDataTable(bool recreate)
 {
-    bool Ok = (wxMessageBox("Any data currently residing in the table will be erased.\n\nAre you sure?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
+    bool Ok = TRUE;
+    if (recreate)
+       Ok = (wxMessageBox("Any data currently residing in the table will be erased.\n\nAre you sure?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
 
     if (!Ok)
         return;
@@ -296,23 +363,23 @@ void DatabaseDemoFrame::CreateDataTable()
         return;
     }
 
-    if (!Contact->CreateTable(FALSE))
+    if (!Contact->CreateTable(recreate))
     {
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "Error creating CONTACTS table.\nTable was not created.\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         success = FALSE;
     }
-     else
+    else
     {
         if (!Contact->CreateIndexes())
         {
             wxEndBusyCursor();
             wxString tStr;
             tStr  = "Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             success = FALSE;
         }
@@ -321,6 +388,7 @@ void DatabaseDemoFrame::CreateDataTable()
         wxEndBusyCursor();
 
     delete Contact;
+     Contact = NULL;
 
     if (success)
         wxMessageBox("Table and index(es) were successfully created.","Notice...",wxOK | wxICON_INFORMATION);
@@ -329,9 +397,24 @@ void DatabaseDemoFrame::CreateDataTable()
 
 void DatabaseDemoFrame::BuildEditorDialog()
 {
+    pEditorDlg = NULL;
     pEditorDlg = new CeditorDlg(this);
-    if (!pEditorDlg)
+    if (pEditorDlg)
+    {
+        pEditorDlg->Initialize();
+        if (!pEditorDlg->initialized)
+        {
+            pEditorDlg->Close();
+            delete pEditorDlg;
+            wxMessageBox("Unable to initialize the editor dialog for some reason","Error...",wxOK | wxICON_EXCLAMATION);
+            DemoFrame->Close();
+        }
+    } 
+    else
+    {
         wxMessageBox("Unable to create the editor dialog for some reason","Error...",wxOK | wxICON_EXCLAMATION);
+        DemoFrame->Close();
+    }
 }  // DatabaseDemoFrame::BuildEditorDialog()
 
 
@@ -345,24 +428,24 @@ void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
 
 
 /*
- * Constructor note: If no wxDB object is passed in, a new connection to the database
+ * Constructor note: If no wxDb object is passed in, a new connection to the database
  *     is created for this instance of Ccontact.  This can be a slow process depending
  *     on the database engine being used, and some database engines have a limit on the
  *     number of connections (either hard limits, or license restricted) so care should 
  *     be used to use as few connections as is necessary.  
  *
- * IMPORTANT: Objects which share a wxDB pointer are ALL acted upon whenever a member 
+ * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member 
  *     function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying 
  *     or creating a table objects which use the same pDb, know that all the objects
  *     will be committed or rolled back when any of the objects has this function call made.
  */
-Ccontact::Ccontact (wxDB *pwxDB) : wxTable(pwxDB ? pwxDB : GetDbConnection(&DbConnectInf),CONTACT_TABLE_NAME,CONTACT_NO_COLS,NULL,!QUERY_ONLY,DbConnectInf.defaultDir)
+Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(&DbConnectInf),CONTACT_TABLE_NAME,CONTACT_NO_COLS,NULL,!wxDB_QUERY_ONLY,DbConnectInf.defaultDir)
 {
     // This is used to represent whether the database connection should be released
     // when this instance of the object is deleted.  If using the same connection
     // for multiple instance of database objects, then the connection should only be 
     // released when the last database instance using the connection is deleted
-    freeDbConn = !pwxDB;
+    freeDbConn = !pwxDb;
     
     SetupColumns();
 
@@ -396,11 +479,11 @@ Ccontact::~Ccontact()
 {
     if (freeDbConn)
     {
-        if (!FreeDbConnection(pDb))
+        if (!wxDbFreeConnection(GetDb()))
         {
             wxString tStr;
             tStr  = "Unable to Free the Ccontact data table handle\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         }
     }
@@ -408,7 +491,7 @@ Ccontact::~Ccontact()
 
 
 /*
- * Handles setting up all the connections for the interface from the wxTable
+ * Handles setting up all the connections for the interface from the wxDbTable
  * functions to interface to the data structure used to store records in 
  * memory, and for all the column definitions that define the table structure
  */
@@ -436,19 +519,19 @@ bool Ccontact::CreateIndexes(void)
     // This index could easily be accomplished with an "orderBy" clause, 
     // but is done to show how to construct a non-primary index.
     wxString    indexName;
-    CidxDef     idxDef[2];
+    wxDbIdxDef  idxDef[2];
 
     bool        Ok = TRUE;
 
-    strcpy(idxDef[0].ColName, "IS_DEV");
+    wxStrcpy(idxDef[0].ColName, "IS_DEV");
     idxDef[0].Ascending = TRUE;
 
-    strcpy(idxDef[1].ColName, "NAME");
+    wxStrcpy(idxDef[1].ColName, "NAME");
     idxDef[1].Ascending = TRUE;
 
-    indexName = CONTACT_TABLE_NAME;
+    indexName = GetTableName();
     indexName += "_IDX1";
-    Ok = CreateIndex((char*) (const char*) indexName, TRUE, 2, idxDef);
+    Ok = CreateIndex(indexName.c_str(), TRUE, 2, idxDef);
 
     return Ok;
 }  // Ccontact::CreateIndexes()
@@ -462,8 +545,8 @@ bool Ccontact::CreateIndexes(void)
 bool Ccontact::FetchByName(char *name)
 {
     whereStr.Printf("NAME = '%s'",name);
-    where = (char*) (const char*) this->whereStr;
-    orderBy = 0;
+    SetWhereClause(whereStr.c_str());
+    SetOrderByClause("");
 
     if (!Query())
         return(FALSE);
@@ -492,180 +575,34 @@ bool Ccontact::FetchByName(char *name)
  
 BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
     EVT_BUTTON(-1,  CeditorDlg::OnButton)
+    EVT_CLOSE(CeditorDlg::OnCloseWindow)
 END_EVENT_TABLE()
  
-CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 1, 1, 460, 455)
+CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 480)
 {
     // Since the ::OnCommand() function is overridden, this prevents the widget
     // detection in ::OnCommand() until all widgets have been initialized to prevent
     // uninitialized pointers from crashing the program
     widgetPtrsSet = FALSE;
 
-    // Create the data structure and a new database connection.  
-    // (As there is not a pDb being passed in the constructor, a new database
-    // connection is created)
-    Contact = new Ccontact();
-
-    if (!Contact)
-    {
-        wxMessageBox("Unable to instantiate an instance of Ccontact","Error...",wxOK | wxICON_EXCLAMATION);
-        return;
-    }
-
-    // Check if the table exists or not.  If it doesn't, ask the user if they want to 
-    // create the table.  Continue trying to create the table until it exists, or user aborts
-    while (!Contact->pDb->TableExists((char *)CONTACT_TABLE_NAME,DbConnectInf.Uid,DbConnectInf.defaultDir))
-    {
-        wxString tStr;
-        tStr.Printf("Unable to open the table '%s'.\n\nTable may need to be created...?\n\n",CONTACT_TABLE_NAME);
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-
-        bool createTable = (wxMessageBox("Do you wish to try to create/clear the CONTACTS table?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
-
-        if (!createTable)
-        {
-            delete Contact;
-            Close();
-            DemoFrame->Close();
-            return;
-        }
-        else
-            DemoFrame->CreateDataTable();
-    }
-
-    // Tables must be "opened" before anything other than creating/deleting table can be done
-    if (!Contact->Open())
-    {
-        // Table does exist, there was some problem opening it.  Currently this should
-        // never fail, except in the case of the table not exisiting.  Open() basically
-        // only sets up variable/pointer values, other than checking for table existence.
-        if (Contact->pDb->TableExists((char *)CONTACT_TABLE_NAME))
-        {
-            wxString tStr;
-            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-            delete Contact;
-            Close();
-            DemoFrame->Close();
-            return;
-        }
-    }
-
-    // Build the dialog
-
-    (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, "",  wxPoint(15, 1), wxSize(497,  69), 0, "FunctionGrp");
-    (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, "", wxPoint(417, 1), wxSize(95, 242), 0, "SearchGrp");
-
-    pCreateBtn      = new wxButton(this, EDITOR_DIALOG_CREATE,           "&Create",     wxPoint( 25,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CreateBtn");
-    pEditBtn        = new wxButton(this, EDITOR_DIALOG_EDIT,             "&Edit",       wxPoint(102,  21), wxSize( 70,  35), 0, wxDefaultValidator, "EditBtn");
-    pDeleteBtn      = new wxButton(this, EDITOR_DIALOG_DELETE,           "&Delete",     wxPoint(179,  21), wxSize( 70,  35), 0, wxDefaultValidator, "DeleteBtn");
-    pCopyBtn        = new wxButton(this, EDITOR_DIALOG_COPY,             "Cop&y",       wxPoint(256,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CopyBtn");
-    pSaveBtn        = new wxButton(this, EDITOR_DIALOG_SAVE,             "&Save",       wxPoint(333,  21), wxSize( 70,  35), 0, wxDefaultValidator, "SaveBtn");
-    pCancelBtn      = new wxButton(this, EDITOR_DIALOG_CANCEL,           "C&ancel",     wxPoint(430,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CancelBtn");
-    pPrevBtn        = new wxButton(this, EDITOR_DIALOG_PREV,             "<< &Prev",    wxPoint(430,  81), wxSize( 70,  35), 0, wxDefaultValidator, "PrevBtn");
-    pNextBtn        = new wxButton(this, EDITOR_DIALOG_NEXT,             "&Next >>",    wxPoint(430, 121), wxSize( 70,  35), 0, wxDefaultValidator, "NextBtn");
-    pQueryBtn       = new wxButton(this, EDITOR_DIALOG_QUERY,            "&Query",      wxPoint(430, 161), wxSize( 70,  35), 0, wxDefaultValidator, "QueryBtn");
-    pResetBtn       = new wxButton(this, EDITOR_DIALOG_RESET,            "&Reset",      wxPoint(430, 200), wxSize( 70,  35), 0, wxDefaultValidator, "ResetBtn");
-    pNameMsg        = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG,     "Name:",       wxPoint( 17,  80), wxSize( -1,  -1), 0, "NameMsg");
-    pNameTxt        = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT,      "",            wxPoint( 17,  97), wxSize(308,  25), 0, wxDefaultValidator, "NameTxt");
-    pNameListBtn    = new wxButton(this, EDITOR_DIALOG_LOOKUP,           "&Lookup",     wxPoint(333,  99), wxSize( 70,  24), 0, wxDefaultValidator, "LookupBtn");
-    pAddress1Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, "Address:",    wxPoint( 17, 130), wxSize( -1,  -1), 0, "Address1Msg");
-    pAddress1Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 147), wxSize(308,  25), 0, wxDefaultValidator, "Address1Txt");
-    pAddress2Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, "Address:",    wxPoint( 17, 180), wxSize( -1,  -1), 0, "Address2Msg");
-    pAddress2Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 197), wxSize(308,  25), 0, wxDefaultValidator, "Address2Txt");
-    pCityMsg        = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG,     "City:",       wxPoint( 17, 230), wxSize( -1,  -1), 0, "CityMsg");
-    pCityTxt        = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT,      "",            wxPoint( 17, 247), wxSize(225,  25), 0, wxDefaultValidator, "CityTxt");
-    pStateMsg       = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG,    "State:",      wxPoint(250, 230), wxSize( -1,  -1), 0, "StateMsg");
-    pStateTxt       = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT,     "",            wxPoint(250, 247), wxSize(153,  25), 0, wxDefaultValidator, "StateTxt");
-    pCountryMsg     = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG,  "Country:",    wxPoint( 17, 280), wxSize( -1,  -1), 0, "CountryMsg");
-    pCountryTxt     = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT,   "",            wxPoint( 17, 297), wxSize(225,  25), 0, wxDefaultValidator, "CountryTxt");
-    pPostalCodeMsg  = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG,   "Postal Code:",wxPoint(250, 280), wxSize( -1,  -1), 0, "PostalCodeMsg");
-    pPostalCodeTxt  = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT,    "",            wxPoint(250, 297), wxSize(153,  25), 0, wxDefaultValidator, "PostalCodeTxt");
-
-    wxString choice_strings[5];
-    choice_strings[0] = "English";
-    choice_strings[1] = "French";
-    choice_strings[2] = "German";
-    choice_strings[3] = "Spanish";
-    choice_strings[4] = "Other";
-
-    pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE,                        wxPoint( 17, 346), wxSize(277,  -1), 5, choice_strings);
-    pNativeLangMsg    = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG,   "Native language:", wxPoint( 17, 330), wxSize( -1,  -1), 0, "NativeLangMsg");
+    initialized = FALSE;
 
-    wxString radio_strings[2];
-    radio_strings[0]  = "No";
-    radio_strings[1]  = "Yes";
-    pDeveloperRadio   = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER,     "Developer:",       wxPoint(303, 330), wxSize( -1,  -1), 2, radio_strings, 2, wxHORIZONTAL);
-    pJoinDateMsg      = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG,   "Date joined:",     wxPoint( 17, 380), wxSize( -1,  -1), 0, "JoinDateMsg");
-    pJoinDateTxt      = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT,    "",                 wxPoint( 17, 397), wxSize(150,  25), 0, wxDefaultValidator, "JoinDateTxt");
-    pContribMsg       = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,"Contributions:",   wxPoint(175, 380), wxSize( -1,  -1), 0, "ContribMsg");
-    pContribTxt       = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, "",                 wxPoint(175, 397), wxSize(120,  25), 0, wxDefaultValidator, "ContribTxt");
-    pLinesMsg         = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG,  "Lines of code:",   wxPoint(303, 380), wxSize( -1,  -1), 0, "LinesMsg");
-    pLinesTxt         = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT,   "",                 wxPoint(303, 397), wxSize(100,  25), 0, wxDefaultValidator, "LinesTxt");
+    Contact = NULL;
 
-    // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to 
-    // handle all widget processing
-    widgetPtrsSet = TRUE;
-
-    // Setup the orderBy and where clauses to return back a single record as the result set, 
-    // as there will only be one record being shown on the dialog at a time, this optimizes
-    // network traffic by only returning a one row result
-    
-    Contact->orderBy = "NAME";  // field name to sort by
-
-    // The wxString "whereStr" is not a member of the wxTable object, it is a member variable
-    // specifically in the Ccontact class.  It is used here for simpler construction of a varying
-    // length string, and then after the string is built, the wxTable member variable "where" is
-    // assigned the pointer to the constructed string.
-    //
-    // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s" 
-    // to achieve a single row (in this case the first name in alphabetical order).
-    
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
-    {
-        Contact->whereStr.sprintf("NAME = (SELECT MIN(NAME) FROM %s)",Contact->tableName);
-        // NOTE: (const char*) returns a pointer which may not be valid later, so this is short term use only
-        Contact->where = (char*) (const char*) Contact->whereStr;
-    }
-    else
-        Contact->where = 0;
-
-    // Perform the Query to get the result set.  
-    // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.  
-    //       Only if there is a database error will Query() come back as FALSE
-    if (!Contact->Query())
-    {
-        wxString tStr;
-        tStr  = "ODBC error during Query()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-        GetParent()->Close();
-        return;
-    }
-
-    // Since Query succeeded, now get the row that was returned
-    if (!Contact->GetNext())
-        // If the GetNext() failed at this point, then there are no rows to retrieve, 
-        // so clear the values in the members of "Contact" so that PutData() blanks the 
-        // widgets on the dialog
-        Contact->Initialize();
-
-    SetMode(mView);
-    PutData();
-
-    Show(TRUE);
+    Show(FALSE);
 }  // CeditorDlg constructor
 
 
 void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 {
     // Clean up time
-     if ((mode != mCreate) && (mode != mEdit))
+    if ((mode != mCreate) && (mode != mEdit))
     {
         if (Contact)
+        {
             delete Contact;
+            Contact = NULL;
+        }
         this->Destroy();
     }
     else
@@ -676,11 +613,11 @@ void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 }  // CeditorDlg::OnCloseWindow()
 
 
-void CeditorDlg::OnButton( wxCommandEvent &event )
+void CeditorDlg::OnButton(wxCommandEvent &event)
 {
-  wxWindow *win = (wxWindow*) event.GetEventObject();
-  OnCommand( *win, event );
-}
+    wxWindow *win = (wxWindow*) event.GetEventObject();
+    OnCommand( *win, event );
+}  // CeditorDlg::OnButton()
 
 
 void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
@@ -715,6 +652,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         SetMode(mCreate);
         pNameTxt->SetValue("");
         pNameTxt->SetFocus();
+
         return;
     }
 
@@ -733,7 +671,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             //       of Ccontact is deleted.  If the Commit wasn't performed, the 
             //       database will automatically Rollback the changes when the database
             //       connection is terminated
-            Contact->pDb->CommitTrans();
+            Contact->GetDb()->CommitTrans();
 
             // Try to get the row that followed the just deleted row in the orderBy sequence
             if (!GetNextRec())
@@ -751,7 +689,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         }
         else
             // Delete failed
-            Contact->pDb->RollbackTrans();
+            Contact->GetDb()->RollbackTrans();
 
         SetMode(mView);
         return;
@@ -770,7 +708,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (!Ok)
             return;
 
-        if (!strcmp((const char*) saveName,""))
+        if (!wxStrcmp((const char*) saveName,""))
         {
             Contact->Initialize();
             PutData();
@@ -789,21 +727,21 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         }
 
         // Previous record not available, retrieve first record in table
-        if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+        if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
         {
             Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
-            Contact->whereStr += Contact->tableName;
+            Contact->whereStr += Contact->GetTableName();
             Contact->whereStr += ")";
-            Contact->where = (char*) (const char*) Contact->whereStr;
+            Contact->SetWhereClause(Contact->whereStr.c_str());
         }
         else
-            Contact->where = 0;
+            Contact->SetWhereClause("");
 
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             SetMode(mView);
             return;
@@ -839,19 +777,18 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         // Display the query dialog box
         char qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
-        strcpy(qryWhere, (const char*) Contact->qryWhereStr);
+        wxStrcpy(qryWhere, (const char*) Contact->qryWhereStr);
         char *tblName[] = {(char *)CONTACT_TABLE_NAME, 0};
-        new CqueryDlg(GetParent(), Contact->pDb, tblName, qryWhere);
+        new CqueryDlg(GetParent(), Contact->GetDb(), tblName, qryWhere);
 
         // Query the first record in the new record set and
         // display it, if the query string has changed.
-        if (strcmp(qryWhere, (const char*) Contact->qryWhereStr))
+        if (wxStrcmp(qryWhere, (const char*) Contact->qryWhereStr))
         {
             Contact->whereStr = "";
-            Contact->orderBy  = "NAME";
+            Contact->SetOrderByClause("NAME");
 
-            if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+            if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
             {
                 Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
                 Contact->whereStr += CONTACT_TABLE_NAME;
@@ -859,20 +796,20 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             
             // Append the query where string (if there is one)
             Contact->qryWhereStr  = qryWhere;
-            if (strlen(qryWhere))
+            if (wxStrlen(qryWhere))
             {
                 Contact->whereStr += " WHERE ";
                 Contact->whereStr += Contact->qryWhereStr;
             }
             // Close the expression with a right paren
-            // Contact->whereStr += ")";
+            Contact->whereStr += ")";
             // Requery the table
-            Contact->where = (char*) (const char*) Contact->whereStr;
+            Contact->SetWhereClause(Contact->whereStr.c_str());
             if (!Contact->Query())
             {
                 wxString tStr;
                 tStr  = "ODBC error during Query()\n\n";
-                tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 return;
             }
@@ -893,21 +830,21 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         // Clear the additional where criteria established by the query feature
         Contact->qryWhereStr = "";
-        Contact->orderBy        = "NAME";
+        Contact->SetOrderByClause("NAME");
 
-        if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+        if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
         {
             Contact->whereStr        = "NAME = (SELECT MIN(NAME) FROM ";
             Contact->whereStr        += CONTACT_TABLE_NAME;
             Contact->whereStr        += ")";
         }
 
-        Contact->where            = (char*) (const char*) Contact->whereStr;
+        Contact->SetWhereClause(Contact->whereStr.c_str());
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
@@ -931,7 +868,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
                        /* char      *orderBy       */ "NAME",
                        /* bool      distinctValues */ TRUE);
 
-        if (ListDB_Selection && strlen(ListDB_Selection))
+        if (ListDB_Selection && wxStrlen(ListDB_Selection))
         {
             wxString w = "NAME = '";
             w += ListDB_Selection;
@@ -941,10 +878,182 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 
         return;
     }
-
 }  // CeditorDlg::OnCommand()
 
 
+bool CeditorDlg::Initialize()
+{
+    // Create the data structure and a new database connection.  
+    // (As there is not a pDb being passed in the constructor, a new database
+    // connection is created)
+    Contact = new Ccontact();
+
+    if (!Contact)
+    {
+        wxMessageBox("Unable to instantiate an instance of Ccontact","Error...",wxOK | wxICON_EXCLAMATION);
+        return FALSE;
+    }
+
+    // Check if the table exists or not.  If it doesn't, ask the user if they want to 
+    // create the table.  Continue trying to create the table until it exists, or user aborts
+    while (!Contact->GetDb()->TableExists((char *)CONTACT_TABLE_NAME,DbConnectInf.Uid,DbConnectInf.defaultDir))
+    {
+        wxString tStr;
+        tStr.Printf("Unable to open the table '%s'.\n\nTable may need to be created...?\n\n",CONTACT_TABLE_NAME);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+
+        bool createTable = (wxMessageBox("Do you wish to try to create/clear the CONTACTS table?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
+
+        if (!createTable)
+        {
+//            Close();
+            return FALSE;
+        }
+        else
+            DemoFrame->CreateDataTable(TRUE);
+    }
+
+    // Tables must be "opened" before anything other than creating/deleting table can be done
+    if (!Contact->Open())
+    {
+        // Table does exist, or there was some problem opening it.  Currently this should
+        // never fail, except in the case of the table not exisiting or the current 
+        // user has insufficent privileges to access the table
+#if 0
+// This code is experimenting with a new function that will hopefully be available
+// in the 2.4 release.  This check will determine whether the open failing was due
+// to the table not existing, or the users privileges being insufficient to
+// open the table.
+        if (!Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME,"SELECT",Contact->GetDb()->GetUsername(),DbConnectInf.defaultDir))
+        {
+            wxString tStr;
+            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+        }
+        else 
+#endif
+        if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,Contact->GetDb()->GetUsername(),DbConnectInf.defaultDir))
+        {
+            wxString tStr;
+            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+        }
+
+        return FALSE;
+    }
+
+    // Build the dialog
+
+    (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, "",  wxPoint(15, 1), wxSize(497,  69), 0, "FunctionGrp");
+    (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, "", wxPoint(417, 1), wxSize(95, 242), 0, "SearchGrp");
+
+    pCreateBtn      = new wxButton(this, EDITOR_DIALOG_CREATE,           "&Create",     wxPoint( 25,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CreateBtn");
+    pEditBtn        = new wxButton(this, EDITOR_DIALOG_EDIT,             "&Edit",       wxPoint(102,  21), wxSize( 70,  35), 0, wxDefaultValidator, "EditBtn");
+    pDeleteBtn      = new wxButton(this, EDITOR_DIALOG_DELETE,           "&Delete",     wxPoint(179,  21), wxSize( 70,  35), 0, wxDefaultValidator, "DeleteBtn");
+    pCopyBtn        = new wxButton(this, EDITOR_DIALOG_COPY,             "Cop&y",       wxPoint(256,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CopyBtn");
+    pSaveBtn        = new wxButton(this, EDITOR_DIALOG_SAVE,             "&Save",       wxPoint(333,  21), wxSize( 70,  35), 0, wxDefaultValidator, "SaveBtn");
+    pCancelBtn      = new wxButton(this, EDITOR_DIALOG_CANCEL,           "C&ancel",     wxPoint(430,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CancelBtn");
+    pPrevBtn        = new wxButton(this, EDITOR_DIALOG_PREV,             "<< &Prev",    wxPoint(430,  81), wxSize( 70,  35), 0, wxDefaultValidator, "PrevBtn");
+    pNextBtn        = new wxButton(this, EDITOR_DIALOG_NEXT,             "&Next >>",    wxPoint(430, 121), wxSize( 70,  35), 0, wxDefaultValidator, "NextBtn");
+    pQueryBtn       = new wxButton(this, EDITOR_DIALOG_QUERY,            "&Query",      wxPoint(430, 161), wxSize( 70,  35), 0, wxDefaultValidator, "QueryBtn");
+    pResetBtn       = new wxButton(this, EDITOR_DIALOG_RESET,            "&Reset",      wxPoint(430, 200), wxSize( 70,  35), 0, wxDefaultValidator, "ResetBtn");
+    pNameMsg        = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG,     "Name:",       wxPoint( 17,  80), wxSize( -1,  -1), 0, "NameMsg");
+    pNameTxt        = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT,      "",            wxPoint( 17,  97), wxSize(308,  25), 0, wxDefaultValidator, "NameTxt");
+    pNameListBtn    = new wxButton(this, EDITOR_DIALOG_LOOKUP,           "&Lookup",     wxPoint(333,  97), wxSize( 70,  24), 0, wxDefaultValidator, "LookupBtn");
+    pAddress1Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, "Address:",    wxPoint( 17, 130), wxSize( -1,  -1), 0, "Address1Msg");
+    pAddress1Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 147), wxSize(308,  25), 0, wxDefaultValidator, "Address1Txt");
+    pAddress2Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, "Address:",    wxPoint( 17, 180), wxSize( -1,  -1), 0, "Address2Msg");
+    pAddress2Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 197), wxSize(308,  25), 0, wxDefaultValidator, "Address2Txt");
+    pCityMsg        = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG,     "City:",       wxPoint( 17, 230), wxSize( -1,  -1), 0, "CityMsg");
+    pCityTxt        = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT,      "",            wxPoint( 17, 247), wxSize(225,  25), 0, wxDefaultValidator, "CityTxt");
+    pStateMsg       = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG,    "State:",      wxPoint(250, 230), wxSize( -1,  -1), 0, "StateMsg");
+    pStateTxt       = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT,     "",            wxPoint(250, 247), wxSize(153,  25), 0, wxDefaultValidator, "StateTxt");
+    pCountryMsg     = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG,  "Country:",    wxPoint( 17, 280), wxSize( -1,  -1), 0, "CountryMsg");
+    pCountryTxt     = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT,   "",            wxPoint( 17, 297), wxSize(225,  25), 0, wxDefaultValidator, "CountryTxt");
+    pPostalCodeMsg  = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG,   "Postal Code:",wxPoint(250, 280), wxSize( -1,  -1), 0, "PostalCodeMsg");
+    pPostalCodeTxt  = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT,    "",            wxPoint(250, 297), wxSize(153,  25), 0, wxDefaultValidator, "PostalCodeTxt");
+
+    wxString choice_strings[5];
+    choice_strings[0] = "English";
+    choice_strings[1] = "French";
+    choice_strings[2] = "German";
+    choice_strings[3] = "Spanish";
+    choice_strings[4] = "Other";
+
+    pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE,                        wxPoint( 17, 346), wxSize(277,  -1), 5, choice_strings);
+    pNativeLangMsg    = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG,   "Native language:", wxPoint( 17, 330), wxSize( -1,  -1), 0, "NativeLangMsg");
+
+    wxString radio_strings[2];
+    radio_strings[0]  = "No";
+    radio_strings[1]  = "Yes";
+    pDeveloperRadio   = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER,     "Developer:",       wxPoint(303, 330), wxSize( -1,  -1), 2, radio_strings, 2, wxHORIZONTAL);
+    pJoinDateMsg      = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG,   "Date joined:",     wxPoint( 17, 380), wxSize( -1,  -1), 0, "JoinDateMsg");
+    pJoinDateTxt      = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT,    "",                 wxPoint( 17, 397), wxSize(150,  25), 0, wxDefaultValidator, "JoinDateTxt");
+    pContribMsg       = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,"Contributions:",   wxPoint(175, 380), wxSize( -1,  -1), 0, "ContribMsg");
+    pContribTxt       = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, "",                 wxPoint(175, 397), wxSize(120,  25), 0, wxDefaultValidator, "ContribTxt");
+    pLinesMsg         = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG,  "Lines of code:",   wxPoint(303, 380), wxSize( -1,  -1), 0, "LinesMsg");
+    pLinesTxt         = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT,   "",                 wxPoint(303, 397), wxSize(100,  25), 0, wxDefaultValidator, "LinesTxt");
+
+    // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to 
+    // handle all widget processing
+    widgetPtrsSet = TRUE;
+
+    // Setup the orderBy and where clauses to return back a single record as the result set, 
+    // as there will only be one record being shown on the dialog at a time, this optimizes
+    // network traffic by only returning a one row result
+    
+    Contact->SetOrderByClause("NAME");  // field name to sort by
+
+    // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
+    // specifically in the Ccontact class.  It is used here for simpler construction of a varying
+    // length string, and then after the string is built, the wxDbTable member variable "where" is
+    // assigned the pointer to the constructed string.
+    //
+    // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s" 
+    // to achieve a single row (in this case the first name in alphabetical order).
+    
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
+    {
+        Contact->whereStr.sprintf("NAME = (SELECT MIN(NAME) FROM %s)",Contact->GetTableName());
+        // NOTE: (const char*) returns a pointer which may not be valid later, so this is short term use only
+        Contact->SetWhereClause(Contact->whereStr.c_str());
+    }
+    else
+       Contact->SetWhereClause("");
+
+    // Perform the Query to get the result set.  
+    // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.  
+    //       Only if there is a database error will Query() come back as FALSE
+    if (!Contact->Query())
+    {
+        wxString tStr;
+        tStr  = "ODBC error during Query()\n\n";
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+//        GetParent()->Close();
+        return FALSE;
+    }
+
+    // Since Query succeeded, now get the row that was returned
+    if (!Contact->GetNext())
+        // If the GetNext() failed at this point, then there are no rows to retrieve, 
+        // so clear the values in the members of "Contact" so that PutData() blanks the 
+        // widgets on the dialog
+        Contact->Initialize();
+
+    SetMode(mView);
+    PutData();
+
+    Show(TRUE);
+
+    initialized = TRUE;
+    return TRUE;
+}  // CeditorDlg::Initialize()
+
+
 void CeditorDlg::FieldsEditable()
 {
     pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
@@ -966,7 +1075,7 @@ void CeditorDlg::FieldsEditable()
 
 void CeditorDlg::SetMode(enum DialogModes m)
 {
-    bool    edit = FALSE;
+    bool edit = FALSE;
 
     mode = m;
     switch (mode)
@@ -986,9 +1095,9 @@ void CeditorDlg::SetMode(enum DialogModes m)
     if (widgetPtrsSet)
     {
         pCreateBtn->Enable( !edit );
-        pEditBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
-        pDeleteBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
-        pCopyBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
+        pEditBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
+        pDeleteBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
+        pCopyBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
         pSaveBtn->Enable( edit );
         pCancelBtn->Enable( edit );
         pPrevBtn->Enable( !edit );
@@ -1045,7 +1154,7 @@ bool CeditorDlg::GetData()
 
     wxString tStr;
     tStr = pNameTxt->GetValue();
-    if (!strcmp((const char*) tStr,""))
+    if (!wxStrcmp((const char*) tStr,""))
     {
         wxMessageBox("A name is required for entry into the contact table","Notice...",wxOK | wxICON_INFORMATION);
         return FALSE;
@@ -1117,13 +1226,13 @@ bool CeditorDlg::GetData()
     }
 
     tStr = pNameTxt->GetValue();
-    strcpy(Contact->Name,(const char*) tStr);
-    strcpy(Contact->Addr1,pAddress1Txt->GetValue());
-    strcpy(Contact->Addr2,pAddress2Txt->GetValue());
-    strcpy(Contact->City,pCityTxt->GetValue());
-    strcpy(Contact->State,pStateTxt->GetValue());
-    strcpy(Contact->Country,pCountryTxt->GetValue());
-    strcpy(Contact->PostalCode,pPostalCodeTxt->GetValue());
+    wxStrcpy(Contact->Name,(const char*) tStr);
+    wxStrcpy(Contact->Addr1,pAddress1Txt->GetValue());
+    wxStrcpy(Contact->Addr2,pAddress2Txt->GetValue());
+    wxStrcpy(Contact->City,pCityTxt->GetValue());
+    wxStrcpy(Contact->State,pStateTxt->GetValue());
+    wxStrcpy(Contact->Country,pCountryTxt->GetValue());
+    wxStrcpy(Contact->PostalCode,pPostalCodeTxt->GetValue());
 
     Contact->Contributions = atoi(pContribTxt->GetValue());
     Contact->LinesOfCode = atol(pLinesTxt->GetValue());
@@ -1170,7 +1279,7 @@ bool CeditorDlg::Save()
                 {
                     wxString tStr;
                     tStr  = "A duplicate key value already exists in the table.\nUnable to save record\n\n";
-                    tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                    tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
                 else
@@ -1178,7 +1287,7 @@ bool CeditorDlg::Save()
                     // Some other unexpexted error occurred
                     wxString tStr;
                     tStr  = "Database insert failed\n\n";
-                    tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                    tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
             }
@@ -1189,7 +1298,7 @@ bool CeditorDlg::Save()
             {
                 wxString tStr;
                 tStr  = "Database update failed\n\n";
-                tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 failed = TRUE;
             }
@@ -1197,11 +1306,11 @@ bool CeditorDlg::Save()
 
         if (!failed)
         {
-            Contact->pDb->CommitTrans();
+            Contact->GetDb()->CommitTrans();
             SetMode(mView);  // Sets the dialog mode back to viewing after save is successful
         }
         else
-            Contact->pDb->RollbackTrans();
+            Contact->GetDb()->RollbackTrans();
 
         wxEndBusyCursor();
     }
@@ -1219,10 +1328,10 @@ bool CeditorDlg::GetNextRec()
 {
     wxString w;
 
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
     {
         w  = "NAME = (SELECT MIN(NAME) FROM ";
-        w += Contact->tableName;
+        w += Contact->GetTableName();
         w += " WHERE NAME > '";
     }
     else
@@ -1254,10 +1363,10 @@ bool CeditorDlg::GetPrevRec()
 {
     wxString w;
 
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
     {
         w  = "NAME = (SELECT MAX(NAME) FROM ";
-        w += Contact->tableName;
+        w += Contact->GetTableName();
         w += " WHERE NAME < '";
     }
     else
@@ -1287,14 +1396,14 @@ bool CeditorDlg::GetPrevRec()
  */
 bool CeditorDlg::GetRec(char *whereStr)
 {
-    Contact->where = whereStr;
-    Contact->orderBy = "NAME";
+    Contact->SetWhereClause(whereStr);
+    Contact->SetOrderByClause("NAME");
 
     if (!Contact->Query())
     {
         wxString tStr;
         tStr  = "ODBC error during Query()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
 
         return(FALSE);
@@ -1359,21 +1468,27 @@ void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
     if (!saved)
     {
         bool Ok = (wxMessageBox("No changes have been saved.\n\nAre you sure you wish exit the parameter screen?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
-
+        
         if (!Ok)
         {
             event.Veto();
             return;
         }
-
+        
         wxGetApp().params = savedParamSettings;
     }
 
     if (GetParent() != NULL)
         GetParent()->SetFocus();
-    this->Destroy();
 
-}  // Cparameter::OnCloseWindow()
+    while (wxIsBusy())
+        wxEndBusyCursor();
+
+    Show(FALSE);
+    SetReturnCode(0);  // added so BoundsChecker would not report use of uninitialized variable
+
+    this->Destroy();
+}  // CparameterDlg::OnCloseWindow()
 
 
 void CparameterDlg::OnButton( wxCommandEvent &event )
@@ -1382,6 +1497,7 @@ void CparameterDlg::OnButton( wxCommandEvent &event )
     OnCommand( *win, event );
 }
 
+
 void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
     wxString widgetName;
@@ -1442,7 +1558,7 @@ bool CparameterDlg::GetData()
             wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
             return FALSE;
         }
-        strcpy(wxGetApp().params.ODBCSource, tStr);
+        wxStrcpy(wxGetApp().params.ODBCSource, tStr);
     }
     else
         return FALSE;
@@ -1455,7 +1571,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.UserName, tStr);
+    wxStrcpy(wxGetApp().params.UserName, tStr);
 
     tStr = pParamPasswordTxt->GetValue();
     if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
@@ -1465,7 +1581,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.Password,tStr);
+    wxStrcpy(wxGetApp().params.Password,tStr);
 
     tStr = pParamDirPathTxt->GetValue();
     tStr.Replace("\\","/");
@@ -1476,7 +1592,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.DirPath,tStr);
+    wxStrcpy(wxGetApp().params.DirPath,tStr);
     return TRUE;
 }  // CparameterDlg::GetData()
 
@@ -1519,7 +1635,7 @@ void CparameterDlg::FillDataSourceList()
     char DsDesc[255];
     wxStringList strList;
 
-    while(GetDataSource(DbConnectInf.Henv, Dsn, SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
+    while (wxDbGetDataSource(DbConnectInf.Henv, Dsn, SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
         strList.Add(Dsn);
 
     strList.Sort();
@@ -1527,8 +1643,10 @@ void CparameterDlg::FillDataSourceList()
     char **p = strList.ListToArray();
 
     int i;
-    for (i = 0; strlen(p[i]); i++)
+    for (i = 0; wxStrlen(p[i]); i++)
         pParamODBCSourceList->Append(p[i]);
+
+     delete p;
 }  // CparameterDlg::CparameterDlg::FillDataSourceList()
 
 
@@ -1536,9 +1654,10 @@ BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
     EVT_BUTTON(-1,  CqueryDlg::OnButton)
     EVT_CLOSE(CqueryDlg::OnCloseWindow)
 END_EVENT_TABLE()
+
  
 // CqueryDlg() constructor
-CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereArg) : wxDialog (parent, QUERY_DIALOG, "Query", wxPoint(-1, -1), wxSize(480, 360))
+CqueryDlg::CqueryDlg(wxWindow *parent, wxDb *pDb, char *tblName[], char *pWhereArg) : wxDialog (parent, QUERY_DIALOG, "Query", wxPoint(-1, -1), wxSize(480, 360))
 {
     wxBeginBusyCursor();
 
@@ -1550,7 +1669,7 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
 
     // Initialize the WHERE clause from the string passed in
     pWhere = pWhereArg;                                            // Save a pointer to the output buffer
-    if (strlen(pWhere) > DB_MAX_WHERE_CLAUSE_LEN)        // Check the length of the buffer passed in
+    if (wxStrlen(pWhere) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)  // Check the length of the buffer passed in
     {
         wxString s;
         s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
@@ -1583,7 +1702,7 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
     pQuerySqlWhereMtxt      = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT,     "",                     wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, "QuerySqlWhereMtxt");
     pQueryAddBtn            = new wxButton(this, QUERY_DIALOG_ADD,              "&Add",                 wxPoint(406,  24), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAddBtn");
     pQueryAndBtn            = new wxButton(this, QUERY_DIALOG_AND,              "A&nd",                 wxPoint(406,  58), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAndBtn");
-    pQueryOrBtn                = new wxButton(this, QUERY_DIALOG_OR,            "&Or",                  wxPoint(406,  92), wxSize( 56,  26), 0, wxDefaultValidator, "QueryOrBtn");
+    pQueryOrBtn             = new wxButton(this, QUERY_DIALOG_OR,               "&Or",                  wxPoint(406,  92), wxSize( 56,  26), 0, wxDefaultValidator, "QueryOrBtn");
     pQueryLParenBtn         = new wxButton(this, QUERY_DIALOG_LPAREN,           "(",                    wxPoint(406, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryLParenBtn");
     pQueryRParenBtn         = new wxButton(this, QUERY_DIALOG_RPAREN,           ")",                    wxPoint(436, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryRParenBtn");
     pQueryDoneBtn           = new wxButton(this, QUERY_DIALOG_DONE,             "&Done",                wxPoint(406, 185), wxSize( 56,  26), 0, wxDefaultValidator, "QueryDoneBtn");
@@ -1607,17 +1726,17 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "ODBC error during GetColumns()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(pDb,__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         return;
     }
 
     int i;
-    for (i = 0; colInf[i].colName && strlen(colInf[i].colName); i++)
+    for (i = 0; colInf[i].colName && wxStrlen(colInf[i].colName); i++)
     {
         // If there is more than one table being queried, qualify
         // the column names with the table name prefix.
-        if (tblName[1] && strlen(tblName[1]))
+        if (tblName[1] && wxStrlen(tblName[1]))
         {
             qualName.Printf("%s.%s", colInf[i].tableName, colInf[i].colName);
             pQueryCol1Choice->Append(qualName);
@@ -1646,15 +1765,20 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
     // Display the dialog window
     Centre(wxBOTH);
     ShowModal();
-
 }  // CqueryDlg() constructor
 
 
-void CqueryDlg::OnButton( wxCommandEvent &event )
+CqueryDlg::~CqueryDlg()
+{
+}  // CqueryDlg::~CqueryDlg() destructor
+
+
+void CqueryDlg::OnButton(wxCommandEvent &event)
 {
   wxWindow *win = (wxWindow*) event.GetEventObject();
   OnCommand( *win, event );
-}
+}  // CqueryDlg::OnButton()
+
 
 void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
@@ -1672,33 +1796,33 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         // Set the help text
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpEQ:
-            pQueryHintMsg->SetLabel(langQRY_EQ);
-            break;
-        case qryOpLT:
-            pQueryHintMsg->SetLabel(langQRY_LT);
-            break;
-        case qryOpGT:
-            pQueryHintMsg->SetLabel(langQRY_GT);
-            break;
-        case qryOpLE:
-            pQueryHintMsg->SetLabel(langQRY_LE);
-            break;
-        case qryOpGE:
-            pQueryHintMsg->SetLabel(langQRY_GE);
-            break;
-        case qryOpBEGINS:
-            pQueryHintMsg->SetLabel(langQRY_BEGINS);
-            break;
-        case qryOpCONTAINS:
-            pQueryHintMsg->SetLabel(langQRY_CONTAINS);
-            break;
-        case qryOpLIKE:
-            pQueryHintMsg->SetLabel(langQRY_LIKE);
-            break;
-        case qryOpBETWEEN:
-            pQueryHintMsg->SetLabel(langQRY_BETWEEN);
-            break;
+            case qryOpEQ:
+                pQueryHintMsg->SetLabel(langQRY_EQ);
+                break;
+            case qryOpLT:
+                pQueryHintMsg->SetLabel(langQRY_LT);
+                break;
+            case qryOpGT:
+                pQueryHintMsg->SetLabel(langQRY_GT);
+                break;
+            case qryOpLE:
+                pQueryHintMsg->SetLabel(langQRY_LE);
+                break;
+            case qryOpGE:
+                pQueryHintMsg->SetLabel(langQRY_GE);
+                break;
+            case qryOpBEGINS:
+                pQueryHintMsg->SetLabel(langQRY_BEGINS);
+                break;
+            case qryOpCONTAINS:
+                pQueryHintMsg->SetLabel(langQRY_CONTAINS);
+                break;
+            case qryOpLIKE:
+                pQueryHintMsg->SetLabel(langQRY_LIKE);
+                break;
+            case qryOpBETWEEN:
+                pQueryHintMsg->SetLabel(langQRY_BETWEEN);
+                break;
         }
 
         // Hide the value2 widget
@@ -1708,57 +1832,57 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         // Disable the NOT operator for <, <=, >, >=
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpLT:
-        case qryOpGT:
-        case qryOpLE:
-        case qryOpGE:
-            pQueryNotCheck->SetValue(0);
-            pQueryNotCheck->Enable(FALSE);
-            break;
-        default:
-            pQueryNotCheck->Enable(TRUE);
-            break;
+            case qryOpLT:
+            case qryOpGT:
+            case qryOpLE:
+            case qryOpGE:
+                pQueryNotCheck->SetValue(0);
+                pQueryNotCheck->Enable(FALSE);
+                break;
+            default:
+                pQueryNotCheck->Enable(TRUE);
+                break;
         }
 
         // Manipulate the dialog to handle the selected operator
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpEQ:
-        case qryOpLT:
-        case qryOpGT:
-        case qryOpLE:
-        case qryOpGE:
-            pQueryCol2Choice->Enable(TRUE);
-            if (pQueryCol2Choice->GetSelection())    // Column name is highlighted
-            {
-                pQueryValue1Msg->Show(FALSE);
-                pQueryValue1Txt->Show(FALSE);
-            }
-            else                                                // "Value" is highlighted
-            {
+            case qryOpEQ:
+            case qryOpLT:
+            case qryOpGT:
+            case qryOpLE:
+            case qryOpGE:
+                pQueryCol2Choice->Enable(TRUE);
+                if (pQueryCol2Choice->GetSelection())    // Column name is highlighted
+                {
+                    pQueryValue1Msg->Show(FALSE);
+                    pQueryValue1Txt->Show(FALSE);
+                }
+                else                                                // "Value" is highlighted
+                {
+                    pQueryValue1Msg->Show(TRUE);
+                    pQueryValue1Txt->Show(TRUE);
+                    pQueryValue1Txt->SetFocus();
+                }
+                break;
+            case qryOpBEGINS:
+            case qryOpCONTAINS:
+            case qryOpLIKE:
+                pQueryCol2Choice->SetSelection(0);
+                pQueryCol2Choice->Enable(FALSE);
                 pQueryValue1Msg->Show(TRUE);
                 pQueryValue1Txt->Show(TRUE);
                 pQueryValue1Txt->SetFocus();
-            }
-            break;
-        case qryOpBEGINS:
-        case qryOpCONTAINS:
-        case qryOpLIKE:
-            pQueryCol2Choice->SetSelection(0);
-            pQueryCol2Choice->Enable(FALSE);
-            pQueryValue1Msg->Show(TRUE);
-            pQueryValue1Txt->Show(TRUE);
-            pQueryValue1Txt->SetFocus();
-            break;
-        case qryOpBETWEEN:
-            pQueryCol2Choice->SetSelection(0);
-            pQueryCol2Choice->Enable(FALSE);
-            pQueryValue2Msg->Show(TRUE);
-            pQueryValue2Txt->Show(TRUE);
-            pQueryValue1Msg->Show(TRUE);
-            pQueryValue1Txt->Show(TRUE);
-            pQueryValue1Txt->SetFocus();
-            break;
+                break;
+            case qryOpBETWEEN:
+                pQueryCol2Choice->SetSelection(0);
+                pQueryCol2Choice->Enable(FALSE);
+                pQueryValue2Msg->Show(TRUE);
+                pQueryValue2Txt->Show(TRUE);
+                pQueryValue1Msg->Show(TRUE);
+                pQueryValue1Txt->Show(TRUE);
+                pQueryValue1Txt->SetFocus();
+                break;
         }
 
         return;
@@ -1780,7 +1904,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             pQueryValue1Txt->SetFocus();
         }
         return;
-
     }  // Column 2 choice
 
     // Add button
@@ -1788,7 +1911,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         ProcessAddBtn();
         return;
-
     }  // Add button
 
     // And button
@@ -1796,7 +1918,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(" AND\n");
         return;
-
     }  // And button
 
     // Or button
@@ -1804,7 +1925,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(" OR\n");
         return;
-
     }  // Or button
 
     // Left Paren button
@@ -1812,7 +1932,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere("(");
         return;
-
     }  // Left Paren button
 
     // Right paren button
@@ -1820,14 +1939,13 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(")");
         return;
-
     }  // Right Paren button
 
     // Done button
     if (widgetName == pQueryDoneBtn->GetName())
     {
         // Be sure the where clause will not overflow the output buffer
-        if (strlen(pQuerySqlWhereMtxt->GetValue()) > DB_MAX_WHERE_CLAUSE_LEN)
+        if (wxStrlen(pQuerySqlWhereMtxt->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)
         {
             wxString s;
             s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
@@ -1838,10 +1956,9 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (!ValidateWhereClause())
             return;
         // Copy the where clause to the output buffer and exit
-        strcpy(pWhere, pQuerySqlWhereMtxt->GetValue());
+        wxStrcpy(pWhere, pQuerySqlWhereMtxt->GetValue());
         Close();
         return;
-
     }  // Done button
 
     // Clear button
@@ -1852,7 +1969,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (Ok)
             pQuerySqlWhereMtxt->SetValue("");
         return;
-
     }  // Clear button
 
     // Count button
@@ -1862,7 +1978,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         ProcessCountBtn();
         wxEndBusyCursor();
         return;
-
     }  // Count button
 
 }  // CqueryDlg::OnCommand
@@ -1887,17 +2002,18 @@ void CqueryDlg::OnCloseWindow(wxCloseEvent& event)
     while (wxIsBusy())
         wxEndBusyCursor();
 
-    this->Destroy();
+    Show(FALSE);
+    SetReturnCode(1);  // added so BoundsChecker would not report use of uninitialized variable
 
+    this->Destroy();
 }  // CqueryDlg::OnCloseWindow()
 
 
 void CqueryDlg::AppendToWhere(char *s)
 {
-        wxString whereStr = pQuerySqlWhereMtxt->GetValue();
-        whereStr += s;
-        pQuerySqlWhereMtxt->SetValue(whereStr);
-
+    wxString whereStr = pQuerySqlWhereMtxt->GetValue();
+    whereStr += s;
+    pQuerySqlWhereMtxt->SetValue(whereStr);
 }  // CqueryDlg::AppendToWhere()
 
 
@@ -1909,7 +2025,7 @@ void CqueryDlg::ProcessAddBtn()
     if (pQueryCol2Choice->GetSelection() == 0)            // "Value" is selected
     {
         // Verify that value 1 is filled in
-        if (strlen(pQueryValue1Txt->GetValue()) == 0)
+        if (wxStrlen(pQueryValue1Txt->GetValue()) == 0)
         {
             wxBell();
             pQueryValue1Txt->SetFocus();
@@ -1917,7 +2033,7 @@ void CqueryDlg::ProcessAddBtn()
         }
         // For the BETWEEN operator, value 2 must be filled in as well
         if (oper == qryOpBETWEEN &&
-             strlen(pQueryValue2Txt->GetValue()) == 0)
+             wxStrlen(pQueryValue2Txt->GetValue()) == 0)
         {
             wxBell();
             pQueryValue2Txt->SetFocus();
@@ -2007,29 +2123,32 @@ void CqueryDlg::ProcessCountBtn()
     if (!ValidateWhereClause())
         return;
 
-    if (dbTable == 0)  // wxTable object needs to be created and opened
+    if (dbTable == 0)  // wxDbTable object needs to be created and opened
     {
-        if (!(dbTable = new wxTable(pDB, masterTableName, 0, NULL, !QUERY_ONLY, DbConnectInf.defaultDir)))
+        if (!(dbTable = new wxDbTable(pDB, masterTableName, 0, NULL, !wxDB_QUERY_ONLY, DbConnectInf.defaultDir)))
         {
-            wxMessageBox("Memory allocation failed creating a wxTable object.","Error...",wxOK | wxICON_EXCLAMATION);
+            wxMessageBox("Memory allocation failed creating a wxDbTable object.","Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
         if (!dbTable->Open())
         {
             wxString tStr;
             tStr  = "ODBC error during Open()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(dbTable->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
     }
 
     // Count() with WHERE clause
-    dbTable->where = (char*) (const char*) pQuerySqlWhereMtxt->GetValue();
+    wxString whereStr;
+
+    whereStr = pQuerySqlWhereMtxt->GetValue();
+    dbTable->SetWhereClause(whereStr.c_str());
     ULONG whereCnt = dbTable->Count();
 
     // Count() of all records in the table
-    dbTable->where = 0;
+    dbTable->SetWhereClause("");
     ULONG totalCnt = dbTable->Count();
 
     if (whereCnt > 0 || totalCnt == 0)
@@ -2070,3 +2189,29 @@ bool CqueryDlg::ValidateWhereClause()
     return(TRUE);
 
 }  // CqueryDlg::ValidateWhereClause()
+
+
+
+
+/*
+    TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
+
+        int result = 0;
+        result = wxDbCreateDataSource("Microsoft Access Driver (*.mdb)","GLT-TEST2","GLT-Descrip",FALSE,"",this);
+        if (!result)
+        {
+            // check for errors caused by ConfigDSN based functions
+            DWORD retcode = 0;
+            WORD cb;
+            wxChar errMsg[500+1];
+            errMsg[0] = '\0';
+
+            SQLInstallerError(1,&retcode,errMsg,500,&cb);
+
+            wxMessageBox("FAILED creating data source","FAILED");
+        }
+        else
+            wxMessageBox("SUCCEEDED creating data source","SUCCESS");
+*/
+
+