CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jul 2009
    Posts
    3

    MFC OnEnChange handler function - infinite loop

    Hi,

    (I'm using VS++2005)

    I put edit box control (with ID - ID_edit_box) on my dialog, and associate (with handler wizard) two varibles for it: control (c_editbox) and value (v_editbox) variable. Also I associate handler function OnEnChangeedit_box with that edit box control. Suppose that we may enter just one digit in edit box, and that digit can be 0 or 1. If we enter some other value - what I want is that content of that edit box is automaticaly cleared, so user can't see that he type anything (in other words user can not enter anything except 0/1 in edit box). I do that check in onEnChangeedit_box function. Here is the code:

    void CSDRDlg::OnEnChangeedit_box()
    {
    CWnd* pWnd;
    CString edit_box_temp;

    pWnd = GetDlgItem(ID_edit_box);
    pWnd->GetWindowText(edit_box_temp);

    if ((edit_box_temp == "0" || edit_box_temp == "1")
    {...do something - i.e. setfocus on some other edit box }
    else
    {
    pWnd->SetWindowText(""); // clear the content of edit box
    //... any other statement below will not be executed because the
    //above line cause again call of this function
    }
    }
    I debug and discover that line: "pWnd->SetWindowText("");" cause infinite loop because we change control content in this function which truggers again her call.

    But I change above code like this:
    void CSDRDlg::OnEnChangeedit_box()
    {
    UpdateData(TRUE);
    if ((v_editbox == "0" || v_editbox== "1")
    {...do something - i.e. setfocus on some other edit box }
    else
    {
    v_editbox = "";
    UpdateData(FALSE);
    }
    }

    and that works what I want but can someone explain to me why when we call
    v_editbox = "";
    UpdateData(FALSE);
    that dont cause infinite loop.

    Best regards

  2. #2
    Join Date
    Jul 2002
    Posts
    2,543

    Re: MFC OnEnChange handler function - infinite loop

    The answer can be found in UpdateData source code:

    Code:
    BOOL CWnd::UpdateData(BOOL bSaveAndValidate)
    {
    	ASSERT(::IsWindow(m_hWnd)); // calling UpdateData before DoModal?
    
    	CDataExchange dx(this, bSaveAndValidate);
    
    	// prevent control notifications from being dispatched during UpdateData
    	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
    	HWND hWndOldLockout = pThreadState->m_hLockoutNotifyWindow;
    	ASSERT(hWndOldLockout != m_hWnd);   // must not recurse
    	pThreadState->m_hLockoutNotifyWindow = m_hWnd;
    
    	BOOL bOK = FALSE;       // assume failure
    	TRY
    	{
    		DoDataExchange(&dx);
    		bOK = TRUE;         // it worked
    	}
    	CATCH(CUserException, e)
    	{
    		// validation failed - user already alerted, fall through
    		ASSERT(!bOK);											
    		// Note: DELETE_EXCEPTION_(e) not required
    	}
    	AND_CATCH_ALL(e)
    	{
    		// validation failed due to OOM or other resource failure
    		e->ReportError(MB_ICONEXCLAMATION, AFX_IDP_INTERNAL_FAILURE);
    		ASSERT(!bOK);
    		DELETE_EXCEPTION(e);
    	}
    	END_CATCH_ALL
    
    	pThreadState->m_hLockoutNotifyWindow = hWndOldLockout;
    	return bOK;
    }
    According to the notes, line
    pThreadState->m_hLockoutNotifyWindow = m_hWnd;
    prevents notifications. Since they use undocumented functions, we cannot do the same in our own code, and need to use some flag which must be checked in notification handler:
    Code:
    void CSDRDlg::OnEnChangeedit_box()
    {
         if ( m_bNotificationDisabled )
             return;
    
    
        m_bNotificationDisabled = TRUE;
        pWnd->SetWindowText(""); 
        m_bNotificationDisabled = FALSE;    // return to defaut
    }
    Another way is clearing editbox asynchronously. You can post user-defined message to the dialog (PostMessage, not SendMessage), and clear editbox in the message handler.
    Last edited by Alex F; July 27th, 2009 at 09:15 AM.

  3. #3
    Join Date
    Jan 2002
    Location
    Houston, TX
    Posts
    1,421

    Re: MFC OnEnChange handler function - infinite loop

    Another solution would be to check the length of the string:
    Code:
    pWnd = GetDlgItem(ID_edit_box);
    pWnd->GetWindowText(edit_box_temp);
    
    if (strlen(edit_box_temp)>0)
    {
        if ((edit_box_temp == "0" || edit_box_temp == "1")
        {
            ...do something - i.e. setfocus on some other edit box
        }
        else
        {
            pWnd->SetWindowText(""); // clear the content of edit box
            //... any other statement below will not be executed because the 
            //above line cause again call of this function
        }
    }
    Hope that helps.
    Be sure to rate those who help!
    -------------------------------------------------------------
    Karl - WK5M
    PP-ASEL-IA (N43CS)
    PGP Key: 0xDB02E193
    PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193

  4. #4
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: MFC OnEnChange handler function - infinite loop

    Quote Originally Posted by melinda123 View Post
    Suppose that we may enter just one digit in edit box, and that digit can be 0 or 1. If we enter some other value - what I want is that content of that edit box is automaticaly cleared, so user can't see that he type anything (in other words user can not enter anything except 0/1 in edit box).
    If this is really the case, and not just to explain the question, would it not be much clearer to the user to dispay a check box, instead of an edit box?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured