PRB: Using CEdit SetModify/GetModify Returns Invalid Values (155224)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Editions 4.0
- Microsoft Visual C++, 32-bit Editions 4.1
- Microsoft Visual C++, 32-bit Enterprise Edition 4.2
- Microsoft Visual C++, 32-bit Professional Edition 4.2
This article was previously published under Q155224 SYMPTOMS
The CEdit::GetModify() and CEdit::SetModify() methods may be unreliable
when the CEdit object is part of CEditView. Further, using these methods on
a CEdit object that is part of a CEditView object may cause
CEditView::LockBuffer(), CEditView::GetBufferLength(), and other CEditView
methods to return invalid values.
CAUSE
Under Windows 95 and Win32s, CEditView uses CEdit::GetModify() and
CEdit::SetModify() to indicate when an internal buffer--which mirrors the
contents of the edit control--is current. As a result, you can experience
unpredictable behavior if the class you derive from CEditView also uses
this flag, for example:
RESOLUTION
The easiest workaround is to ignore the edit control's internal modified
flag and define your own in the class you derived from CEditView:
class CMyEditView : public CEditView
{
public:
BOOL GetModify() { return m_bModified; }
void SetModify(BOOL bModified) { m_bModified = bModified; }
// Additional public members...
protected:
BOOL m_bModified;
// Additional protected members...
};
Keep this flag current by overriding OnChange() in the class you derived
from CEditView. OnChange() is called any time the contents of the
underlying edit control changes:
void CMyEditView::OnChange()
{
m_bModified = TRUE;
//Call base class's EN_CHANGE handler
CEditView::OnEditChange();
}
MORE INFORMATION
CEdit::GetModify() and CEdit::SetModify() access an internal "dirty" flag
that is maintained by the standard Windows edit control. These methods are
useful in determining if the contents of an edit control have been modified
since this flag was cleared.
Due to limitations under Win32s and Windows 95, the MFC classes set an
internal flag, afxData.bWin32s, to TRUE during initialization under either
of these systems. When this flag is TRUE, CEditView uses a modified method
to obtain the contents of the underlying edit control. Instead of reading
data from the edit control each time you need it, CEditView maintains an
internal buffer that mirrors the contents of the edit control. To ensure
this buffer is updated when the contents of the edit control change,
CEditView uses CEdit::GetModify() and CEdit::SetModify(). This can cause
serious conflicts if your application also uses these methods.
The problem is clearly demonstrated in the source code for
CEditView::LockBuffer(). Instead of accessing the control directly each
time, CEditView::LockBuffer() copies the edit control's contents to a local
buffer. Then CEditView::LockBuffer() calls CEdit::SetModify() with an
argument of FALSE to clear the dirty flag. If your program calls
CEditView::LockBuffer() or one of the many CEditView members that call it,
the buffer is updated only if CEdit::GetModify() returns TRUE (which
indicates the edit control's contents have changed and the local buffer is
no longer current).
Because CEditView::LockBuffer() clears the edit control's modified flag,
your program no longer relies on this flag. Please note, if your program
clears this flag, CEditView::LockBuffer() returns the contents of the local
buffer even if the contents of the edit control has changed.
CEditView::LockBuffer() is also called by other CEditView members, such as
GetBufferLength() and FindText().
Modification Type: | Major | Last Reviewed: | 12/10/2003 |
---|
Keywords: | kbEditCtrl kbprb KbUIDesign KB155224 |
---|
|