Eating returns in a single line edit

I was quite frustrated in my app - I have a dialog with a few single-line edit controls; after updating the edits, when I pressed Enter the dialog was closed (IDOK was the default button). "Want return" option is unfortunately valid only for multiline edits.

Here is my fix:

I override PreTranslateMessage. If there is WM_KEYDOWN with VK_ENTER going to the edit, I set the focus to the default button and discard the message. If the dialog has no defualt button, I let VK_ENTER through - no problem this time.

I check if the window is an editbox by calling GetClassName and comparing the return value to "Edit". There are much more possibilities - comparing the FromHandle(hwnd) to array of CWnd*, to array of IDs (comparing to GetDlgItem() return values) etc.

For the code to be completely correct, it should check for the edit's windows style and it should not act if it is multi-line, want-return edit. [I haven't done that as I don't use multiline edits.]

1. To your override of CDialog, add the following method:


	virtual BOOL PreTranslateMessage(MSG *);

2. Implement this function, for example:


BOOL CMyDialog::PreTranslateMessage(MSG *pMsg)
{
	if (pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)
	{
		DWORD def_id=GetDefID();
		if (def_id!=0)
		{
			CWnd *wnd=FromHandle(pMsg->hwnd);
			// you may implement other ways of testing, e.g.
			//  comparing to array of CWnd*, comparing to array of IDs etc.
			char class_name[16];
			if (GetClassName(wnd->GetSafeHwnd(),class_name,sizeof(class_name))!=0)
			{
				if (strnicmp(class_name,"edit",5)==0)
				{
					GetDlgItem(LOWORD(def_id))->SetFocus();
					return TRUE;
					// discard the message!
				}
			}
		}
	}
	// be a good citizen - call the base class
	return CDialog::PreTranslateMessage(pMsg);
}