TN054: La chiamata DAO direttamente durante l'utilizzo di classi DAO MFC

Quando si utilizzano le classi di database DAO MFC, ci possono essere situazioni in cui è necessario utilizzare direttamente DAO. Di solito questo non sarà il caso, ma MFC ha fornito alcuni meccanismi di supporto per facilitare facendo chiamate dirette DAO semplice quando si combinano l'uso delle classi MFC con chiamate dirette di DAO. Rendendo DAO diretto chiamate ai metodi di un oggetto gestito MFC DAO dovrebbero richiedere solo poche righe di codice. Se bisogno di creare e utilizzare oggetti DAO che sono non gestito da MFC, si dovrà fare un po' più di lavoro chiamando in realtà Release sull'oggetto. Questa nota tecnica spiega quando potrebbe voler chiamare direttamente DAO, cosa possono fare per aiutare gli helper MFC e come utilizzare le interfacce DAO OLE. Questa nota, infine, fornisce alcune funzioni di esempio che mostra come chiamare DAO direttamente per la funzionalità di protezione DAO.

Quando effettuare chiamate dirette DAO

Le situazioni più comuni per la fabbricazione di indirizzare le chiamate DAO si verificano quando raccolte hanno bisogno di essere aggiornata o quando si implementa funzionalità non avvolto da MFC. La caratteristica più significativa non esposta da MFC è sicurezza. Se si desidera implementare le funzioni di protezione, è necessario utilizzare gli oggetti utente DAO e informazioni direttamente. Oltre alla sicurezza, ci sono solo pochi altri DAO funzionalità non supportate da MFC. Questi includono funzionalità di replica di clonazione e database recordset, come pure alcune aggiunte tarda a DAO.

Una breve panoramica di DAO e implementazione di MFC

Avvolgimento di MFC di DAO rende utilizzando DAO più semplice da gestire molti dei dettagli, così non devi preoccuparti per le piccole cose. Ciò include l'inizializzazione di OLE, la creazione e la gestione degli oggetti DAO (soprattutto gli oggetti collection), errore di controllo e grazie a un'interfaccia tipizzato in modo sicuro, più semplice (senza argomenti variante o BSTR ). È possibile effettuare chiamate dirette DAO e ancora approfittare di queste caratteristiche. Tutto il codice deve fare è chiamare Release eventuali oggetti creati dalle chiamate dirette DAO e non modificare i puntatori a interfaccia MFC può contare su internamente. Ad esempio, non modificare il membro m_pDAORecordset di un oggetto CDaoRecordset aperto a meno che non capire tutte le ramificazioni interne. Si potrebbe, tuttavia, usa l'interfaccia m_pDAORecordset per chiamare DAO direttamente per ottenere l'insieme di campi. In questo caso il membro m_pDAORecordset non verrebbe modificato. Devi semplicemente chiamare Release sull'oggetto di raccolta campi quando hai finito con l'oggetto.

Descrizione di aiutanti per rendere DAO chiama più facile

Gli helper forniti per creare la chiamata più facile DAO sono le stesse helper che vengono utilizzati internamente nelle classi di Database DAO MFC. Questi aiutanti vengono utilizzati per controllare i codici restituiti quando si effettua una chiamata diretta DAO, registrazione output di debug, il controllo per errori previsti e generazione di eccezioni appropriate se necessario. Ci sono due funzioni di supporto sottostante e quattro macro che mapping a uno di questi due aiutanti. La migliore spiegazione sarebbe semplicemente leggere il codice. Vedere DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEMe DAO_TRACE in AFXDAO.H per vedere le macro e AfxDaoCheck e AfxDaoTrace in DAOCORE.CPP.

Utilizzo delle interfacce DAO OLE

Le interfacce OLE per ogni oggetto nella gerarchia di oggetti DAO sono definite nel file di intestazione DBDAOINT.H, che si trova nella directory \Program Files\DevStudio\VC\include. Queste interfacce forniscono metodi che consentono di manipolare l'intera gerarchia DAO.

Per molti dei metodi delle interfacce DAO, sarà necessario modificare un oggetto BSTR (con prefisso di lunghezza stringa utilizzata nell'automazione OLE). L'oggetto BSTR in genere viene incapsulata all'interno del tipo di dati VARIANT . La classe MFC COleVariant sé eredita dal tipo di dati VARIANT . Dipende se si compila il progetto per ANSI o Unicode, le interfacce DAO restituirà s BSTRANSI o Unicode. Due macro, V_BSTR e V_BSTRT, sono utili per assicurare che l'interfaccia DAO ottiene la BSTR del tipo previsto.

V_BSTR estrarrà il membro bstrVal di un COleVariant. Questa macro viene in genere utilizzata quando è necessario passare il contenuto di un COleVariant a un metodo di un'interfaccia di DAO. Frammento di codice seguente mostra le dichiarazioni e la uso effettivo per i due metodi dell'interfaccia DAOUser DAO che sfruttano la macro V_BSTR:

COleVariant varOldName;
COleVariant varNewName (_T("NewUser"), VT_BSTRT);

/ / Codice per assegnare pUser su un valore valido omesso
DAOUser * pUser = NULL;

/ / Queste dichiarazioni di metodo sono state prese dal DBDAOINT.H
/ / STDMETHOD(get_Name) (THIS_ estremo di BSTR * pbstr) PURE;
/ / STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE;

DAO_CHECK (pUser-gt; get_Name (& V_BSTR (e varOldName)));
DAO_CHECK (pUser - > put_Name (V_BSTR (e varNewName)))

Si noti che l'argomento VT_BSTRT specificato nel costruttore COleVariant sopra assicura che non ci sarà un ANSI BSTR nella COleVariant se si costruisce una versione ANSI di applicazione e un Uunicode BSTR per una versione Unicode della vostra applicazione. Questo è ciò che si aspetta DAO.

La macro, V_BSTRT, verrà estratto un ANSI o Unicode bstrVal membro del COleVariant a seconda del tipo di build (ANSI o Unicode). Il codice riportato di seguito viene illustrato come estrarre il valore BSTR un COleVariant in un CString:

COleV&ariant varName ( t ("nome"), VT_BSTRT);
CString str = V_BSTRT (amp; varName)

La macro V_BSTRT , insieme ad altri trucchi di crack aprire altri tipi archiviati all'interno di COleVariant, è dimostrato nell'esempio DAOVIEW incluso nel CD di Visual C++. In particolare, questa traduzione viene eseguita nel metodo CCrack::strVARIANT . Questo metodo, ove possibile, si traduce il valore di un COleVariant in un'istanza di CString.

Semplice esempio di una chiamata diretta a DAO

Situazioni possono sorgere quando è necessario aggiornare gli oggetti sottostanti per la collezione DAO. Normalmente questo non dovrebbe essere necessario, ma è una procedura semplice se necessario. Un esempio di quando una raccolta potrebbe essere necessario essere aggiornati è quando si opera in un ambiente multiutente con più utenti, la creazione di nuovi oggetti TableDef. In questo caso la vostra collezione di oggetti TableDef potrebbe diventare stantio. Per aggiornare l'insieme, semplicemente bisogno di chiamare il metodo Refresh dell'oggetto insieme particolare e controllare gli errori:

DAO_CHECK (pMyDaoDatabase-gt;
    m_pDAOTableDefs - > Refresh ())

Si noti che attualmente tutte le DAO collezione oggetto interfacce sono i dettagli di implementazione non documentati di classi di database DAO MFC.

Utilizzo DAO direttamente per la funzionalità di protezione DAO

Le classi di database DAO MFC non avvolgere la funzionalità di protezione DAO. È necessario chiamare i metodi delle interfacce DAO per utilizzare alcune funzionalità di protezione DAO. La seguente funzione imposta il database di sistema e quindi modifica la password dell'utente. Questa funzione chiama tre altre funzioni, che successivamente vengono definite.

void ChangeUserPassword( )
{
   // Specify path to the Microsoft Access
   // system database
   CString strSystemDB = 
     _T( "c:\\Program Files\\MSOffice\\access\\System.mdw" );

   // Set system database before MFC initilizes DAO
   // NOTE: An MFC module uses only one instance 
   // of a DAO database engine object. If you have 
   // called a DAO object in your application prior 
   // to calling the function below, you must call 
   // AfxDaoTerm to destroy the existing database 
   // engine object. Otherwise, the database engine 
   // object already in use will be reused, and setting
   // a system datbase will have no effect.
   //
   // If you have used a DAO object prior to calling 
   // this function it is important that DAO be 
   // terminated with AfxDaoTerm since an MFC
   // module only gets one copy of the database engine 
   // and that engine will be reused if it hasn't been 
   // terminated. In other words, if you do not call 
   // AfxDaoTerm and there is currently a database 
   // initialized, setting the system database will 
   // have no affect.

   SetSystemDB( strSystemDB );

   // User name and password manually added
   // by using Microsoft Access
   CString strUserName = _T( "NewUser" );
   CString strOldPassword = _T( "Password" );
   CString strNewPassword = _T( "NewPassword" );

   // Set default user so that MFC will be able
   // to log in by default using the user name and 
   // password from the system database
   SetDefaultUser( strUserName, strOldPassword );

   // Change the password. You should be able to
   // call this function from anywhere in your 
   // MFC application
   ChangePassword( strUserName, strOldPassword, 
                   strNewPassword );

   .
   .
   .

}

Gli esempi seguenti quattro come:

L'impostazione di Database di sistema

Di seguito è riportato un esempio di funzione per impostare il database di sistema che verrà utilizzato da un'applicazione. Questa funzione deve essere chiamata prima che vengano apportate altre chiamate di DAO.

/ / Imposta il database di sistema che il / / userà il motore di database DAO

public static void SetSystemDB (CString amp; strSystemMDB)
{
   COleVariant varSystemDB (strSystemMDB, VT_BSTRT);

/ / Initialize DAO per MFC
   AfxDaoInit ();
   DAODBEngine * pDBEngine = AfxDaoGetEngine ();

ASSERT (pDBEngine! = NULL);

/ / Chiama il metodo put_SystemDB per impostare il / / sistema di database per motore DAO
   DAO_CHECK (pDBEngine - > put_SystemDB (varSystemDB.bstrVal));
}

L'impostazione di Default User e Password

Per impostare l'utente predefinito e la password per un database di sistema, utilizzare la seguente funzione:

public static void SetDefaultUser (CString amp; strUserName, CString & strPassword)
{
  COleVariant varUserName (strUserName, VT_BSTRT);
  COleVariant varPassword (strPassword, VT_BSTRT);

DAODBEngine * pDBEngine = AfxDaoGetEngine ();
  ASSERT (pDBEngine! = NULL);

/ / Set default user:
  DAO_CHECK (pDBEngine - > put_DefaultUser (varUserName.bstrVal));

/ / Imposta la password di default:
  DAO_CHECK (pDBEngine - > put_DefaultPassword (varPassword.bstrVal));
}

Cambiare la Password di un utente

Per modificare la password di un utente, utilizzare la seguente funzione:

void ChangePassword( CString &strUserName, 
                     CString &strOldPassword, 
                     CString &strNewPassword )
{
   // Create (open) a workspace
   CDaoWorkspace wsp;
   CString strWspName = _T( "Temp Workspace" );

   wsp.Create( strWspName, strUserName,
               strOldPassword );
   wsp.Append( );

   // Determine how many objects there are
   // in the Users collection
   short nUserCount;
   short nCurrentUser;
   DAOUser *pUser  = NULL;
   DAOUsers *pUsers = NULL;

   // Side-effect is implicit OLE AddRef( ) 
   // on DAOUser object:
   DAO_CHECK( wsp.m_pDAOWorkspace->get_Users( &pUsers ) );

   // Side-effect is implicit OLE AddRef( ) 
   // on DAOUsers object
    DAO_CHECK( pUsers->get_Count( &nUserCount ) );

   // Traverse through the list of users 
   // and change password for the userid
   // used to create/open the workspace
   for( nCurrentUser = 0; nCurrentUser < nUserCount;
        nCurrentUser++ )
   {
       COleVariant varIndex( nCurrentUser, VT_I2 );
       COleVariant varName;

       // Retrieve information for user nCurrentUser
       DAO_CHECK( pUsers->get_Item( varIndex, &pUser ) );

       // Retrieve name for user nCurrentUser
       DAO_CHECK( pUser->get_Name( &V_BSTR( &varName ) ) );

       CString strTemp = V_BSTRT( &varName );

       // If there is a match, change the password
       if( strTemp == strUserName )
       {
           COleVariant varOldPwd( strOldPassword, 
                                  VT_BSTRT );
           COleVariant varNewPwd( strNewPassword, 
                                  VT_BSTRT );

           DAO_CHECK( pUser->NewPassword( V_BSTR( &varOldPwd ),
                      V_BSTR( &varNewPwd ) ) );

           TRACE( "\t Password is changed\n" );
       }
   }

   // Clean up: decrement the usage count
   // on the OLE objects
   pUser->Release( );
   pUsers->Release( );

   wsp.Close( );
}

Modifica della Password di un.File MDB

Per modificare la password di un.MDB file, utilizzare la seguente funzione:

public static void SetDBPassword (LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword)
{
 nbsp; Db CDaoDatabase;
   CString strConnect ( t ("; pwd ="));

/ / il database deve essere aperto come esclusivo
   / / per impostare una password
   DB.Aperto (pDB, TRUE, FALSE, strConnect + pszOldPassword);

COleVariant NewPassword (pszNewPassword, VT_BSTRT),
               OldPassword (pszOldPassword, VT_BSTRT);

DAO_CHECK (db.m_pDAODatabase - > NewPassword (V_BSTR (& OldPassword),
              V_BSTR (& NewPassword)));

DB.Close ();
}

&Note tecniche per numero |nbsp; Note tecniche per la categoria

Index