Last updated:
22. July 2001

User Interface Programming

(Start main menu) Home ­ Articles ­ Book ­ Resources (End main menu)

Enter with Care (Tech Tip)

(Start sub-menu)


User Interface Programming Column


Tech Tips


Code Archive

Range Slider

Splitter Controls and Dialog Resizing



My blog »

(End sub-menu)

I’d like to draw your attention to a user in­ter­fa­ce bug that runs rampant through the world of Win­dows app­li­ca­t­ions. It involves the in­ter­ac­tion of multiline edit con­t­rols and default pushbuttons.

Early versions of Win­dows came equipped with the multiline edit con­t­rol. Entering multiple lines was cumbersome, as it required you to press Ctrl+Enter instead of just Enter. This was especially unfortunate when a default pushbutton was also op­era­tive: users would hit Enter to start a new line and promptly lose the whole dia­log box (along with their peace of mind). This Ctrl+Enter business was so ob­scu­re that many app­li­ca­t­ions added extra text to educate users in proper pro­ce­du­re, e.g., “Hit Ctrl+Enter for new line.” Mistakes were nevertheless common, even among experienced users.

This is the best Win­dows 3.1 link I’ve been able to find on Microsoft’s site.

Poor little orphan…

Along came Windows 3.1 and the ES_WANTRETURN style, and all was well with the world. Or was it? The problem was now turned on its head; users would type some text and then press Enter to invoke the default pushbutton. What they got was a new line (along with a fresh set of aggravations). The old style of in­ter­ac­tion was merely bad. The new style, when used in the wrong context, was an ac­tu­al bug in the user in­ter­fa­ce. That bug has been with us ever since.

There are three approaches to fixing the problem:

  1. Have the software read the user’s mind to decide which action is app­ro­p­ria­te—a new line or a but­ton push.
  2. Resurrect the Ctrl+Enter kludge.
  3. Remove the fat border from the default but­ton whenever a multiline edit con­t­rols with the ES_WANTRETURN style has the keyboard focus.

The first solution is beyond the current state of the art. The second solution is easy; just remove the ES_WANTRETURN style from the edit con­t­rols. Un­for­tu­nately, this results in a bad user in­ter­fa­ce. The third solution is the only sensible way to handle the problem. Some app­li­ca­t­ions use it, others don’t. Still others are in­con­sis­tent; this last group even includes luminaries such as WinWord 97.

In fact, I did develop a gen­e­ral solution two years later; see the Default But­ton Handling article.

“Gen­e­ral” turned out to be better after all.

There are two possibilities: either create a gen­e­ral and reusable solution, or handle it on a case-by-case basis. If the goal is to keep total complexity at a minimum, I think most projects will benefit from a case-by-case handling. What little code is involved is very straightforward, and probably easier to understand than any in­ter­fa­ce to a gen­e­ral solution would be. (Though if you already have a common dia­log base class in your project, you might consider a gen­e­ral solution.)

Figure 1 shows a code fragment that illustrates how one might go about im­p­le­ment­ing this in a simple fashion. The example uses MFC; non-MFC code should handle the EN_SETFOCUS and EN_KILLFOCUS notifications from the multiline edit con­t­rols. These notifications are delivered through the WM_COMMAND mes­sage.

A final caveat: The Visual Studio documentation includes an article entitled “Dia­log Box Keyboard Interface.” I advise you to read this carefully before you start tam­pe­r­ing with default buttons in your own code. If you only read the documentation on DM_SETDEFID, you’ll be left with the inaccurate impression that this is a straightforward business. For example, do you really need to both set the dia­log’s default ID and change the style of the but­ton? Yes, you do. The in­ter­ac­tion bet­ween dialogs, default buttons and the keyboard is a complex and not terribly well-designed business.

(Start bottom menu)

Win­dows De­vel­oper Maga­zineR&D BooksCMP Books Petter Hesselberg

(End bottom menu)

Figure 1: Code Fragment