Date: | December 14, 2004 / year-entry #421 |
Tags: | history |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20041214-00/?p=37013 |
Comments: | 13 |
Summary: | When you use a dialog editor and insert new controls, they typically are assigned control IDs starting at around 100. Why? Because the small numbers are already taken. /* * Dialog Box Command IDs */ #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO... |
When you use a dialog editor and insert new controls, they typically are assigned control IDs starting at around 100. Why? Because the small numbers are already taken. /* * Dialog Box Command IDs */ #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7 #define IDCLOSE 8 #define IDHELP 9 #define IDTRYAGAIN 10 #define IDCONTINUE 11 The dialog manager knows about these special values and assumes that if your dialog box has a control whose ID matches one of these special values, then it also behaves in a certain way. The dialog manager assumes that a control whose ID is IDOK is an OK button. If the user hits Enter, the default button will be pushed; if no default button can be found, then the OK button is pushed. Similarly, a control whose ID is IDCANCEL is assumed to be a Cancel button. If the user hits ESC or clicks the X button in the corner, then the Cancel button is pushed. If your dialog box has OK and Cancel buttons, make sure to give them the IDOK and IDCANCEL control IDs so that they act like proper OK and Cancel buttons. Conversely, any control with those IDs had better be proper OK and Cancel buttons. |
Comments (13)
Comments are closed. |
Every time I see something obvious like this, I have to remind myself that it’s probably there because somebody did it the wrong way.
So Raymond, how often does do you see this?
So why did MFC introduce ID_HELP instead of reusing IDHELP for help buttons in dialogs?
Cooney: Often enough that I’m tired of telling each person individually. Now I can tell everybody at once.
GregM: Because time travel has yet to be perfected. MFC (released in 1993) couldn’t reuse something that didn’t exist (IDHELP didn’t show up until 1995).
"The dialog manager assumes that a control whose ID is IDOK is an OK button. If the user hits Enter, the default button will be pushed; if no default button can be found, then the OK button is pushed. Similarly, a control whose ID is IDCANCEL is assumed to be a Cancel button. If the user hits ESC or clicks the X button in the corner, then the Cancel button is pushed. "
Do any of the other ID’s you list have different behavior?
Back in the day, It took me a while to figure out the significance of IDOK and IDCANCEL.
On an application I used to work on, we’d get complaints from users that their settings weren’t sticking when they edited them with the preference dialogs. We could never reproduce the problem.
Through a miraculous set of coincidences, we discovered that the customers with this problem were all former Macintosh users who believed that the little close box in the corner was the equivalent of OK rather than Cancel. (We had a significant number of converts because the Mac version of our popular product had been discontinued.)
Tech support costs were a huge priority, so we made WM_CLOSE map to OK instead of Cancel. We were careful to ensure the Escape key still did a cancel, and Tech Support never logged another complaint on this issue.
Raymond wrote: "If the user hits Enter, the default button will be pushed; if no default button can be found, then the OK button is pushed."
One bit of information that was omitted: This rule does not apply when an edit control with an ES_WANTRETURN style has the input focus (this is often used with the ES_MULTILINE style). Pressing Enter in this situation causes a carriage return to be issued to the edit control instead of causing a button to be pushed.
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_editctls.asp
Norman:
Keep in mind that Raymond is only talking about dialog boxes here (or for message loops that use the IsDialogMessage() API) — in other words, only for UIs that use the dialog manager.
An application that isn’t using the dialog manager will not behave this way unless it was explicitly coded by someone to do so.
In the project I’m currently working on, one of the specs is that the Enter key has a meaning. Therefore we have to make sure that the Enter key *doesn’t* map onto an OK button, and we have to play a lot of other obscene tricks in programming in order to make sure that the program gets the Enter key instead of some control getting it.
While typing this response, I hit the Enter key twice between "it." and "While". Fortunately that didn’t do an OK operation in Internet Explorer.
In Outlook Express the Enter key usually doesn’t do an OK operation, but sometimes it does when I didn’t want it to. For example when typing a Subject line in Japanese, after hitting the Enter key to confirm a Kanji selection, another press of the Enter key causes the message to get sent. Sometimes the extra press of the Enter key is unintended, sometimes it’s intended because it looks like the first press hadn’t made it through to the IME, etc. After all there are enough cases where Outlook Express loses input keystrokes or loses input mouse clicks, it seems natural to hit Enter again after 10 seconds or so. Of course Outlook Express’s option to refrain from sending until clicking the main send/receive button is valuable, but it’s still a nuisance to change folders and open up the message again and find where the latest intended edit was. OK, sorry this is too long, but nonetheless there are places where we sure wish the Enter key didn’t do an OK.
Norman: The Outlook Express composer window is not a dialog so if Enter maps to Send that’s a UI error in OE and not in the dialog manager. In OE 6 pressing Enter while editing the Subject field does nothing. (The keyboard shortcut for Send is Ctrl-Enter.) But perhaps the IME can trigger some unusual case in which just Enter is enough.
I like feedback from buttons (maybe because I was raised on Mac). Even Petzold has few lines about it. That’s why I have some extra code
to make OK and Cancel buttons blink when Return or Esc are
pressed. Something like this:
SendMessage (btnHwnd, BM_SETSTATE, TRUE, 0);
SleepEx (100, TRUE);
SendMessage (btnHwnd, BM_SETSTATE, FALSE, 0);
SendMessage (parentHwnd, WM_COMMAND, MAKELONG(btnID, BN_CLICKED), (LPARAM)btnHwnd);
It work’s (button blinks) on Win98, but it doesn’t work on XP (styles turned ON).
Raymond, I’d say that’s a good reason. :) (You didn’t say *when* they’d been introduced.)
carlso: Yup, I already discussed it so many times I didn’t feel it necessary to mention WM_GETDLGCODE **again**. Apparently I have to repeat myself so here goes:
http://weblogs.asp.net/oldnewthing/archive/2004/08/02/205624.aspx#206624
http://weblogs.asp.net/oldnewthing/archive/2004/08/02/205624.aspx#206876
http://weblogs.asp.net/oldnewthing/archive/2003/11/26/55872.aspx
GregM: I didn’t say when they were introduced because I figured people who were sufficiently interested could figure it out very easily.
#if(WINVER >= 0x0400)
#define IDCLOSE 8
#define IDHELP 9
#endif /* WINVER >= 0x0400 */
WINVER 0x0400 is Windows 95.
I agree with the other comments that Outlook Express does not seem to have the UI misdesign that I attributed to it. I’m not sure but might have misremembered events in Internet Explorer, in which the UI misdesign was surely in the web page rather than Windows buttons. Now I can only wonder if it was Outlook Web Access, since I don’t have an environment now in which to test this possible recollection. Anyway I apologize for blaming Outlook Express.
Outlook Express did lose an inordinate amount of input from keystroke and mouse buttons though, requiring reinput of the lost items. The most recent patch to Outlook Express might have fixed that, and I hope to get some feeling for this possibility after a few more weeks. Windows Explorer and Internet Explorer sometimes lose keystrokes too, just not as often. (For example in Windows Explorer, Ctrl-A Ctrl-C and notice that everything was indeed selected, move to another folder and do Ctrl-V but the copied items are either nothing or something repeated from an earlier Ctrl-C.) I am sure that I’ve unintendedly sent e-mail as a result of reinputting an Enter key and then finding that the first press had not been lost after all.