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);
}

More by Author

Must Read