Microsoft KB Archive/116409

{|
 * width="100%"|

FIX: Edit After Requery May Produce Incorrect Results

 * }

Q116409

1.50 WINDOWS kbprg kbfixlist kbbuglist -- The information in this article applies to: - The Microsoft Foundation Classes (MFC), included with: - Microsoft Visual C++ for Windows, version 1.5 -- SYMPTOMS ======== In an MFC database application using CRecordsets: 1. Open a recordset and look at the contents of the first record. 2. Call Edit on the recordset object to place it in Edit mode. 3. Change the parameters for the query. 4. Call Requery on the recordset with a different query so that a different record appears as the first record. 5. Call Edit on the new recordset and notice that the fields are loaded with the values from the first record of the first recordset. 6. Inspect the field variables of the recordset and note that they contain the values of the original query instead of the new values you would expect. CAUSE ===== The reason for this behavior is that Requery does not reset the m_nEditMode variable that gets set when you call Edit, nor does it flush the CMemFile-based record cache. The second time Edit is called, m_nEditMode indicates that the recordset is in Edit mode and therefore is reset, with the cache restored to the record fields. This behavior of the second call to Edit is expected according to the specification of the function [see the Edit function description in the "MFC Library Reference"]. RESOLUTION ========== To work around this, override CRecordset::Requery in your derived CRecordset class and call the ReleaseCopyBuffer function. This resets the Edit-mode member variable, m_nEditMode, and also flushes the record cache. The sample code in the "MORE INFORMATION" section, below, includes an example of an overridden Requery. STATUS ====== Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This problem was corrected in MFC version 2.51, included with Visual C++ version 1.51. MORE INFORMATION ================ The CRecordset class contains two member variables called "m_pmemfile" and "m_par". m_pmemfile is a pointer to a CMemFile object used to hold the current record; m_par is a pointer to an archive used to hold the CMemFile. m_pmemfile is the cache that remains persistent between calls to "Edit" if no reopen or requery is done. "ReleaseCopyBuffer" frees the objects associated with these pointers and thus flushes any values that might be restored on a second edit call. Edit then reallocates the CMemFile object and archive and reloads the cache buffer. Sample Code --- // CMyRecordset is derived from CRecordset. BOOL CMyRecordset::Requery { BOOL bRC = CRecordset::Requery; ReleaseCopyBuffer; return bRC; } REFERENCES ========== For other articles pertaining to problems with CRecordset::Requery, query on "Requery" and "CRecordset". Additional reference words: InitRecord 1.50 2.50 KBCategory: kbprg kbfixlist kbbuglist KBSubcategory: MfcDatabase

Keywords : kb16bitonly kbDatabase kbMFC kbODBC kbVC

Issue type :

Technology : kbAudDeveloper kbMFC