For rapid data entry, the normal solution with a drop down list where earlier entries can be selected is not always of any help. A drop down is far too interactive, and demands - in my opinion - quite a lot of concentration on the part of the user.
This class is far simpler - close to annoyingly basic. It stores the entries from the edit box in a
CStringArray, and this list can be navigated by pressing the page up or page down keys. As an added feature, pressing the right-arrow key when the cursor is located at the right end of the text will - if appropriate - add the character at this same position in the last history string to the edit box.
Ctrl+PgUp will find the previous item of the history in alphabetical order,
Ctrl++PgDn the previous. If the appropriate style is set, the history will be circular (wrap around) and/or sorted (non-case sensitive). It might also be autocompleting, and the max size of the history can be set.
Using the code
CBufferedEdit is a simple
CEdit-derived class. It can be instantiated dynamically, by calling Create, or from a dialog template.
The class has a private
m_history, which holds the earlier strings. The current contents of the edit box is added to this array as soon as
WM_SETTEXT is sent to the control (such as when
SetWindowText is called), The class also contains a private
int member -
m_current - holding the current position in the list.
WM_CHAR is mapped, of course, for handling
As the history strings are set, a few contortions has to be made in the code to remove them from the history list - otherwise,
SetWindowText would have triggered the
WM_SETTEXT-mapping, and strings would have been added to the history by just navigating it. This is accomplished in
Clears the history buffer and resets the current pointer
void CBufferedEdit::SetBufferStyle( int style )
Sets the buffer style for the control. Styles can be ORed together. The styles are:
BES_CIRCULAR - when the current pointer reaches either the start or end of the history, the pointer is moved to the other end of the history array.
BES_AUTOCOMPLETE - The control tries to complete the current input from the history after each keypress.
BES_SORT - The history is sorted at all times. No duplicates are added.
The history will be cleared, so this function should normally be called during startup.
void CBufferedEdit::SetBufferMax( int max )
Sets the maximum number of history strings. Set to 0 if no max is to be used. The history will be cleared, so this function should normally be called during startup.
Returns the current style of the control
Returns the current max number of history entries.
Points of Interest
This was not a difficult class to write, as far as the implementation goes. Tricky was to get it to work intuitively, however. Should the text be selected when a new history string is displayed? Should the right arrow show the last history string, or the current? As it works now, it is perfectly adapted for my intended use, but it goes to show that it is perhaps not the programming itself that is a problem, but rather creating something that works in a productive manner.
- 2004/06/15 -
As per a suggestion from Clevedon_Peanut (thanks for the feedback!), I've added automatic handling of the
ENTER-key by adding a new style,
BES_AUTOFILL. If this style is set, the ENTER-key empties the edit field and adds the string to the buffer. This avoids having a default key for the updates, and thus works better for several edits on the same dialog, or in a form view.
- 2004/04/22 - The ico and rc2 added to the res-directory, and as per a suggestion, I added a release-build exe.
- 2004/04/16 - Added history entry max, circular buffer, sorted buffer, sorted navigation and autocompletion.
- 2004/04/10 - Initial version.