sdollins@yoyodyne.ncsa.uiuc.edu (Steven Dollins) (06/17/91)
Hi, all. The program I'm working on has a dialog box that contains an edit field. The edit field should only accept integers in a specified range. If the user enters a non-integer or an integer out of the specified range and then attempts to leave the edit control, the program pops up an error message box. When the user rids himself of the error message, I would like the input focus to return to the edit control, forcing the user to enter a valid number. Here's what I have so far: case IDSLICE_INDEX: /* ID for the edit field. */ if (HIWORD(lParam)==EN_KILLFOCUS) { iIndex = GetDlgItemInt(hwnd, IDSLICE_INDEX, &bErr, FALSE); if (!bErr || (iIndex>iMaxIndex)) { wsprintf(TextBuf, "The index must be between 1 and %d.", iMaxIndex); ErrMsg(TextBuf); return FALSE; } } break; Is there any simple way to put the input focus back if the user tries to TAB to another field or, in the worst case, tries to hit OK? The user should, on the other hand, have the option to "Cancel". Suggestions anyone? - Steven Dollins sdollins@ncsa.uiuc.edu "We have no theology. We have no philosophy. We dance."
bonneau@hyper.hyper.com (Paul Bonneau) (06/18/91)
In article <1991Jun17.005532.4543@ux1.cso.uiuc.edu> sdollins@yoyodyne.ncsa.uiuc.edu (Steven Dollins) writes: >Hi, all. > The program I'm working on has a dialog box that contains an edit >field. The edit field should only accept integers in a specified range. >If the user enters a non-integer or an integer out of the specified >range and then attempts to leave the edit control, the program pops up >an error message box. > When the user rids himself of the error message, I would like the >input focus to return to the edit control, forcing the user to enter a >valid number. Here's what I have so far: > > case IDSLICE_INDEX: /* ID for the edit field. */ > if (HIWORD(lParam)==EN_KILLFOCUS) { > iIndex = GetDlgItemInt(hwnd, IDSLICE_INDEX, &bErr, FALSE); > if (!bErr || (iIndex>iMaxIndex)) { > wsprintf(TextBuf, > "The index must be between 1 and %d.", iMaxIndex); > ErrMsg(TextBuf); > return FALSE; > } > } > break; > > Is there any simple way to put the input focus back if the user >tries to TAB to another field or, in the worst case, tries to hit OK? >The user should, on the other hand, have the option to "Cancel". > At first glance, one might be tempted to simply call SetFocus() at the end of the above code fragment. Unfortunately, this won't work. The reason is that the EN_KILLFOCUS is being sent in response to a WM_KILLFOCUS which is sent by the SetFocus() routine. But SetFocus() is yet to send a WM_SETFOCUS. So the problem is, you get the following sequence of events (assuming a tab): edit gets WM_KILLFOCUS app call SetFocus() tabbed-to control gets WM_KILLFOCUS edit gets WM_SETFOCUS edit gets WM_SETFOCUS What has happened is that a control which never had the focus, (the control the user tried to tab to) received a WM_KILLFOCUS. This can have the undesirable effect (depending on the control) that the cart is inverted, making a caret to appear in the tabbed-to control. So, an alternative is post a private message to yourself, upon receipt of which you set the focus back to the edit. Posting the message removes the recursion. However, you have to make sure that other wierd effects don't occur due to processing the messages that were already in the queue before the post (usually not too difficult). cheers - Paul Bonneau.