TN054: เรียกดาวโดยตรงในขณะที่ใช้เรียน MFC DAO

เมื่อมีการใช้คลาสที่ฐานข้อมูล MFC DAO อาจมีกรณีที่จะต้องใช้ DAO โดยตรง โดยปกติแล้วจะไม่เป็นกรณี แต่ MFC ได้ให้กลไกช่วยเหลือบางอย่างเพื่อให้ง่ายต่อการทำโดยตรง DAO เรียกง่าย ๆ เมื่อรวมการใช้คลาสที่ MFC กับสาย DAO โดยตรง ทำให้ดาวโดยตรงไปยังวิธีการของวัตถุ DAO MFC-จัดการควรต้องเพียงไม่กี่บรรทัดของรหัส ถ้าคุณต้องการสร้าง และใช้วัตถุ DAO ที่ไม่มีจัดการ โดย MFC คุณจะต้องทำงานเพิ่มเติมเพียงเล็กน้อย โดยแท้จริงแล้ว โทรออกบนวัตถุ หมายเหตุทางเทคนิคนี้อธิบายถึงเมื่อคุณอาจต้องการเรียกใช้ DAO โดยตรง สิ่งที่ helpers MFC ที่สามารถทำได้เพื่อช่วยให้คุณ และวิธีการใช้อินเทอร์เฟซ DAO OLE สำหรับ สุดท้าย หมายเหตุนี้แสดงบางฟังก์ชันตัวอย่างแสดงวิธีการเรียกดาวโดยตรงสำหรับคุณลักษณะความปลอดภัยของ DAO?

เมื่อต้องโทรโดยตรง DAO

สถานการณ์ทั่วไปสำหรับการนำสายเรียกดาวเกิดขึ้นเมื่อคอลเลกชันต้องได้รับการฟื้นฟู หรือเมื่อคุณจะใช้คุณลักษณะที่ไม่ห่อ โดย MFC คุณลักษณะสำคัญที่ไม่เปิดเผย โดย MFC คือ ความปลอดภัย ถ้าคุณต้องการใช้คุณลักษณะด้านความปลอดภัย คุณจะต้องใช้วัตถุ DAO user (s)และกลุ่มโดยตรง นอกเหนือจากการรักษาความปลอดภัย ได้เพียงไม่กี่ดาวคุณลักษณะอื่น ๆ ไม่ได้รับการสนับสนุน โดย MFC รวมทั้งคุณลักษณะของชุดระเบียนที่รองรับการโคลนและฐานข้อมูลที่จำลองแบบรวมทั้งเพิ่มล่าช้าไม่กี่ดาว?

ภาพรวมโดยย่อของ DAO และการใช้งานของ MFC

MFC ของการตัดคำของทำให้ดาวที่ใช้ดาวได้ง่ายขึ้น โดยการจัดการรายละเอียดจำนวนมากดังนั้นคุณไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งเล็ก ๆ ซึ่งรวมถึงการเตรียมใช้งาน OLE การสร้าง และการจัดการวัตถุ DAO (โดยเฉพาะอย่างยิ่งการเก็บรวบรวมวัตถุ), ข้อผิดพลาดในการตรวจสอบ และให้ติดต่อที่ พิมพ์ขอ ง่ายกว่า (ไม่มีตัวแปรหรือBSTRอาร์กิวเมนต์) คุณสามารถโทร DAO โดยตรง และยัง ใช้ประโยชน์จากคุณลักษณะเหล่านี้ รหัสของคุณต้องทำทั้งหมดจะเรียกReleaseสำหรับวัตถุใด ๆ ที่สร้างขึ้น โดยการเรียกดาวโดยตรงและไม่ปรับเปลี่ยนตัวชี้ที่อินเทอร์เฟซที่ MFC อาจอาศัยภายใน ตัวอย่างเช่น ไม่ปรับเปลี่ยนสมาชิกm_pDAORecordsetของวัตถุCDaoRecordsetเปิดยกเว้นว่าคุณเข้าใจทั้งหมดสร้างภายใน อย่างไรก็ตาม คุณสามารถ ใช้อินเทอร์เฟซสำหรับm_pDAORecordsetเรียกดาวโดยตรงเพื่อรับชุดเขตข้อมูล ในกรณีนี้ สมาชิกm_pDAORecordsetจะไม่สามารถปรับเปลี่ยน คุณเพียงแค่มีการโทรออกบนวัตถุเก็บรวบรวมเขตข้อมูลเมื่อคุณดำเนินการเสร็จเรียบร้อยแล้วกับวัตถุ?

คำอธิบายของ Helpers ทำ DAO เรียกได้ง่ายขึ้น

Helpers ที่จัดเตรียมไว้ให้ทำการเรียกดาวได้ง่ายได้ที่ helpers เดียวกันที่ใช้เป็นการภายในในคลาสที่ฐานข้อมูล DAO MFC Helpers เหล่านี้จะใช้ในการตรวจสอบรหัสส่งคืนเมื่อทำการเรียกดาวโดยตรง การบันทึกผลลัพธ์การตรวจแก้จุดบกพร่อง การตรวจสอบข้อผิดพลาดที่คาดไว้ และโยนข้อยกเว้นที่เหมาะสมถ้าจำเป็น มีสองฟังก์ชันผู้ช่วยเหลือเป็นต้นและแมโครทั้งสี่ที่แมปกับ helpers สองเหล่านี้อย่างใดอย่างหนึ่ง คำอธิบายที่ดีที่สุดจะเพียงแค่อ่านรหัส ดูDAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEMและDAO_TRACEใน AFXDAOH เพื่อดูแมโค และดูAfxDaoCheckและAfxDaoTraceใน DAOCORECPP?

การใช้อินเทอร์เฟซ DAO OLE

มีกำหนดอินเทอร์เฟซการ OLE สำหรับแต่ละวัตถุในลำดับชั้นของวัตถุ DAO ในส่วนหัวของแฟ้ม DBDAOINTH ซึ่งอยู่ในไดเรกทอรี \Program Files\DevStudio\VC\include อินเทอร์เฟซเหล่านี้มีวิธีการที่ช่วยให้คุณสามารถจัดการลำดับชั้นดาวทั้งหมด?

สำหรับหลายวิธีในการอินเทอร์เฟซ DAO คุณจำเป็นต้องใช้วัตถุBSTR (หน้าความยาวสตใช้ใน OLE automation) BSTRวัตถุโดยทั่วไปคือ encapsulated ภายในชนิดข้อมูลแบบตัวแปร MFC คลาCOleVariantเองที่สืบทอดจากชนิดข้อมูลแบบตัวแปร ทั้งนี้ขึ้นอยู่กับว่าคุณสร้างโครงการของคุณสำหรับ ANSI หรือ Unicode อินเทอร์เฟซดาวจะกลับ s BSTRANSI หรือ Unicode สองแมโคV_BSTRและV_BSTRTมีประโยชน์สำหรับการค้าคลิกปุ่ม ๆ หนึ่งอินเทอร์เฟซ DAO รับBSTRชนิดคาดคิด?

V_BSTRจะแยกสมาชิกbstrVal COleVariant แมโครนี้โดยปกติจะใช้เมื่อคุณต้องการส่งต่อเนื้อหาของการCOleVariantวิธีการอินเทอร์เฟซแบบ DAO ส่วนรหัสต่อไปนี้จะแสดงการประกาศค่าและใช้งานจริงสำหรับสองวิธีของ DAO DAOUser interface ที่ใช้ประโยชน์จากแมโคV_BSTR:

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

/ / รหัส pUser กำหนดค่าไม่ถูกต้อง
DAOUser * pUser = NULL

/ / ประกาศเมธอดเหล่านี้ถูกนำมาจาก DBDAOINTH
/ / STDMETHOD(get_Name) (THIS_ BSTR ไกล * pbstr) ขาว
/ / STDMETHOD(put_Name) (THIS_ BSTR bstr) ขาว

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

หมายเหตุที่อาร์กิวเมนต์VT_BSTRTระบุไว้ในการกำหนดCOleVariantข้างยืนยันข้อมูลที่มี จะเป็น ANSI BSTRในCOleVariantหากคุณสร้างรุ่น ANSI ของโปรแกรมประยุกต์ของคุณและ Uunicode แบบBSTRสำหรับ Unicode รุ่นของโปรแกรมประยุกต์ของคุณ คาดว่าอะไรดาวจะเป็น?

อื่น ๆ แมV_BSTRTจะแยกเป็น ANSI หรือ Unicode bstrValสมาชิกCOleVariantทั้งนี้ขึ้นอยู่กับชนิดของการสร้าง (ANSI หรือ Unicode) รหัสต่อไปนี้สาธิตวิธีการแยกค่าBSTRจากCOleVariantเป็นแบบCString:

COleVariant varName (_T ("MyName"), VT_BSTRT);
CString str = V_BSTRT (แอมป์ varName)(&A)

แมV_BSTRTพร้อม ด้วยเคล็ดลับอื่น ๆ การถอดรหัสเปิดอื่น ๆ คือแสดงชนิดที่เก็บไว้ภายในCOleVariantตัวอย่างการ DAOVIEW ที่รวมอยู่ใน Visual c ++ซีดี โดยเฉพาะ การแปลนี้จะดำเนินในเมธอดCCrack::strVARIANT วิธีการนี้ เป็นไปได้ แปลค่าของCOleVariantเป็นอินสแตนซ์ของCString?

ตัวอย่างง่าย ๆ ของสายโดยตรงไปยังดาว

สถานการณ์อาจเกิดขึ้นเมื่อจำเป็นต้องฟื้นฟูวัตถุ DAO คอลเลกชันเป็นต้น โดยปกติแล้วไม่ควรจำเป็น แต่เป็นขั้นตอนง่าย ๆ ถ้าจำเป็น ตัวอย่างของเมื่อคอลเลกชันอาจจำเป็นต้องได้รับการฟื้นฟูคือเมื่อทำงานในสภาพแวดล้อมแบบผู้ใช้หลายคน มีผู้ใช้หลายคนที่สร้างใหม่ tabledefs ในกรณีนี้ คอลเลกชัน tabledefs อาจจะเก่า เมื่อต้องการฟื้นฟูการคอลเลกชัน คุณต้องการเรียกวิธีการฟื้นฟูของคอลเลกชันเฉพาะวัตถุ และการตรวจสอบข้อผิดพลาด:

DAO_CHECK (pMyDaoDatabase-gt
    m_pDAOTableDefs - > ฟื้นฟู ())

โปรดทราบว่า ขณะนี้อินเทอร์เฟซทั้งหมด DAO รวบรวมวัตถุสำหรับ รายละเอียดการใช้งานอย่างชาญฉลาดของคลาสที่ฐานข้อมูล MFC DAO?

ใช้ DAO โดยตรงสำหรับคุณลักษณะความปลอดภัยของ DAO

คลาสที่ฐานข้อมูล MFC DAO ตัดคุณลักษณะความปลอดภัยของ DAO คุณต้องเรียกใช้เมธอดของอินเทอร์เฟซ DAO เพื่อใช้คุณลักษณะความปลอดภัยบาง DAO ฟังก์ชันต่อไปนี้ฐานข้อมูลระบบตั้งค่า และเปลี่ยนแปลงรหัสผ่านของผู้ใช้แล้ว ฟังก์ชันนี้เรียกสามฟังก์ชันอื่น ๆ ซึ่งถูกกำหนดในภายหลัง?

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 );

   .
   .
   .

}

ตัวอย่างที่สี่ถัดไปสาธิตวิธีการ:

การตั้งค่าฐานข้อมูลระบบ

ข้างล่างนี้เป็นฟังก์ชันตัวอย่างการตั้งค่าระบบฐานข้อมูลที่จะถูกใช้ โดยโปรแกรมประยุกต์ ฟังก์ชันนี้ต้องถูกเรียกก่อนที่จะทำการเรียกดาวอื่น?

/ / ระบบฐานข้อมูลการตั้งค่าที่ตัว / / จะใช้กลไกจัดการฐานข้อมูล DAO

โมฆะ SetSystemDB (แอมป์ CString; strSystemMDB)
{
   COleVariant varSystemDB (strSystemMDB, VT_BSTRT);

/ / เตรียมใช้ DAO สำหรับ MFC
   AfxDaoInit ()
   DAODBEngine * pDBEngine = AfxDaoGetEngine ()

ASSERT (pDBEngine ! = NULL);

/ / เรียกใช้เมธอด put_SystemDB เพื่อตั้งค่าการ / / ระบบฐานข้อมูลสำหรับโปรแกรม DAO
   DAO_CHECK (pDBEngine - > put_SystemDB (varSystemDB.bstrVal));
}

ตั้งค่าเริ่มต้นผู้ใช้และรหัสผ่าน

ใช้ฟังก์ชันต่อไปนี้เพื่อตั้งค่าเริ่มต้นผู้ใช้และรหัสผ่านสำหรับระบบฐานข้อมูล:

โมฆะ SetDefaultUser (CString แอมป์ strUserName, CString และ strPassword)
{
  COleVariant varUserName (strUserName, VT_BSTRT);
  COleVariant varPassword (strPassword, VT_BSTRT);

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

/ / Set ผู้ใช้เริ่มต้น:
  DAO_CHECK (pDBEngine - > put_DefaultUser (varUserName.bstrVal));

/ / ตั้งค่ารหัสผ่านเริ่มต้น:
  DAO_CHECK (pDBEngine - > put_DefaultPassword (varPassword.bstrVal));
}

การเปลี่ยนรหัสผ่านของผู้ใช้

ใช้ฟังก์ชันต่อไปนี้เพื่อเปลี่ยนรหัสผ่านของผู้ใช้:

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( );
}

การเปลี่ยนรหัสผ่านของการไฟล์ MDB

เมื่อต้องการเปลี่ยนรหัสผ่านของการMDB แฟ้ม ใช้ฟังก์ชันต่อไปนี้:

โมฆะ SetDBPassword (LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword)
{
 nbsp CDaoDatabase db
   CString strConnect (_T ("; pwd ="));

/ / ต้องเปิดฐานข้อมูลที่เป็นเอกสิทธิ์เฉพาะบุคคล
   / / การตั้งค่ารหัสผ่าน
   dbเปิด (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)));

dbClose()
}

หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)

Index