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


Comments

  • Lazy way to do this

    Posted by Legacy on 07/01/2002 12:00am

    Originally posted by: Kehlar

    I found a lazy way to capture the return key in an editbox inside a dialog so that the OK button doesn't get pressed. This will work for non-MFC projects as well. In your OnOK function do the following:
    
    

    HWND hWnd = GetFocus();
    if (hWnd == myeditbox.m_hWnd)
    {
    //... do my thing.
    return 0;
    }

    Obvious this means the OK button only gets processed if another control on the dialog is in focus or if the OK button is clicked with the mouse.

    Reply
  • convert RETURN to TAB

    Posted by Legacy on 08/19/2001 12:00am

    Originally posted by: cmoc

    You can do this way:
    set edit control to muti-line and want-return
    void CMyEdit::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags)
    {
    if (nChar==VK_RETURN)
    {
    PostMessage(WM_KEYDOWN,VK_TAB);
    return;
    }
    CEdit::OnKeyDown(nChar,nRepCnt,nFlags);
    }

    Reply
  • Just change to tab...

    Posted by Legacy on 05/30/2001 12:00am

    Originally posted by: Jon Erdman

    I was using this in a CPropertySheet, so was unable to use
    
    the nice GotoDlgItem() function to make the selection and
    such act as if the user had hit tab. also,

    anyway, it occured to me to just let the framework take
    care of it by simply changing the keycode if the edit
    control tests are passed.

    basically, change the return to a tab, then let MFC do the
    rest:

    BOOL CMySheet::PreTranslateMessage(MSG* pMsg)
    {
    if (pMsg->message == WM_KEYDOWN)
    {
    if ((int)pMsg->wParam == VK_RETURN)
    {
    CString classname;
    CWnd *pwnd = FromHandle(pMsg->hwnd);

    if (GetClassName(pwnd->GetSafeHwnd(),classname.GetBuffer(20),20) != 0)
    if (classname == "Edit")
    pMsg->wParam = VK_TAB;
    }
    }

    return CPropertySheet::PreTranslateMessage(pMsg);
    }

    Reply
  • Thanks

    Posted by Legacy on 11/07/2000 12:00am

    Originally posted by: Zeeshan Razzaque

    This really made my day..

    Reply
  • Slightly different version than Mark Johnson's which handles focus like an actual tab stroke

    Posted by Legacy on 01/07/1999 12:00am

    Originally posted by: Shannon O'Brien


    // This is just a different twist on Mark Johnson's approach
    // it handles focus like an actual tab stroke would by placing focus
    // rect around controls like command buttons

    void CMyDlg::OnOK ( void )
    {
    CWnd *pCurWnd = GetFocus ( );

    UpdateData(TRUE);

    // I check the type of control first using CObject's IsKindOf
    // member function
    if ( pCurWnd->IsKindOf ( RUNTIME_CLASS ( CEdit ) ) ||
    pCurWnd->IsKindOf ( RUNTIME_CLASS ( CComboBox ) ) ||
    ( pCurWnd->IsKindOf ( RUNTIME_CLASS ( CButton ) ) &&
    pCurWnd->GetDlgCtrlID ( ) == IDC_ISACTIVE ) )
    {
    // if we aren't on the OK button fake a tab
    CWnd *pNextWnd = GetNextDlgTabItem( pCurWnd );

    // This next line of code will make sure that the
    // focus rectangle surrounds the next control...
    // good in the case of fake tabbing from say a
    // CEdit control to a CButton control...
    // Just calling SetFocus does not do this
    GotoDlgCtrl ( GetDlgItem ( pNextWnd->GetDlgCtrlID ( ) ) );

    return;
    }
    else
    {
    // Call some other handler function here
    // for your specific needs
    }

    return;
    }

    Reply
  • Even Simpler...?

    Posted by Legacy on 12/22/1998 12:00am

    Originally posted by: Mark Johnson

    Typically, i want the enter key to act like the tab key because it's so natural, or sometimes I want the
    enter key to invoke a special process which isn't actviated by a tab involving OnKillfocusXXXX().  
    
    

    #define WM_VALIDATEFORM WM_APP + 101
    #define IsKeyDown(key) (::GetKeyState(key) & 0x1000)
    #define IsKeyUp(key) !IsKeyDown(key)

    void CMyDlg::OnOK()
    {
    UpdateData(TRUE);

    if( GetFocus() != GetDlgItem(IDOK) )
    {
    // if we aren't on the OK button fake a tab
    GetNextDlgTabItem(GetFocus(), IsKeyDown(VK_SHIFT))->SetFocus();
    return;
    }

    CDialog::OnOK();
    }

    void CMyDlg::OnKillfocusUserSelection()
    {
    if( IsKeyDown(VK_RETURN) )
    PostMessage(WM_VALIDATEFORM, ED_USERSELECT, 0L);
    }


    Reply
  • Simpler Option (?)

    Posted by Legacy on 11/27/1998 12:00am

    Originally posted by: Shankar

    Iam just a beginner at MFC & had the same problem in my application. 
    
    This is how I got around it.Maybe some beginners might find it useful.
    First I added a handler to the BNCLICKED message of the OK button,
    which, if u use the classWizard, would be OnOK(). This function did
    nothing.
    CMyDialog::OnOK()
    {
    //Note: I dont have the call to the base class function.
    }

    Then I went ahead and changed the ID of the OK button.
    ( say IDCLICKEDOK ). Add a handler to that using the classWizard, which
    gives you CMyDialog::OnClickedOK(). Then I called the base class OnOK()
    from this.
    CMyDialog::OnClickedOK()
    {
    CDialog::OnOK();
    }
    Then, finally, in the properties box for the OK button, uncheck the
    'default button' check box. That takes care of eveything.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • You may already know about some of the benefits of Bluemix, IBM's open platform for developing and deploying mobile and web applications. Check out this webcast that focuses on building an Android application using the MobileData service, with a walk-through of the real process and workflow used to build and link the MobileData service within your application. Join IBM's subject matter experts as they show you the way to build a base application that will jumpstart you into building your own more complex app …

  • Agile methodologies give development and test teams the ability to build software at a faster rate than ever before. Combining DevOps with hybrid cloud architectures give teams not just the principles, but also the technology necessary to achieve their goals. By combining hybrid cloud and DevOps: IT departments maintain control, visibility, and security Dev/test teams remain agile and collaborative Organizational barriers are broken down Innovation and automation can thrive Download this white paper to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds