Thread: int value from CEdit

  1. #1
    Registered User skillet's Avatar
    Join Date
    Feb 2002
    Posts
    20

    int value from CEdit

    MS Visual C++ 6.0...

    I am trying to get a simpy dialog based program running, but
    I am having difficulty getting an integer value out of an edit box.

    It takes two values out of an edit box and then returns the area of a rectangle with those lengths in a third edit box.

    I have associated an integer variable with the edit box control, but it doesn't get updated when the number in the box changes. This box is buddied with a spin control, so I can either type in a number or inrement it with the spinner.

    I have tried adding the "UpdateData()" function inside the "onChange" call for the edit box, but that causes an assertion error when running in debug.

    ideas?

  2. #2
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    So you have a dialog and an edit control in the dialog, and you want to retrieve the value of the edit control? If so try this:
    Code:
    int buffer,maxLen;   //set maxLen to max characters to retrieve
    BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) //Just the dialog procedure
    {
    switch(msg)
    {
    case WM_INITDIALOG:
    return true;
    break;
    case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDOK:
    GetDlgItemText(hwnd,IDC_EDIT,(LPTSTR)buffer,maxLen); //Retrieves the text inside the dialog edit control labelled IDC_EDIT
    break;
    case IDCANCEL:
    EndDialog(hwnd,IDCANCEL);
    break;
    }
    default:
    return false;
    break;
    }
    return true;
    }
    You don't have to use that Dialog procedure but the part I want you to see is the GetDlgItemText() function. This retrieves the text inside the edit control and stores it into the variable buffer. So you said you set a number for the edit control? You can just replace IDC_EDIT with that number. Ok is that what you wanted or do you have a problem with the data in the box being updated?
    Last edited by jmd15; 09-10-2005 at 09:31 AM.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  3. #3
    Registered User skillet's Avatar
    Join Date
    Feb 2002
    Posts
    20
    I am haveing some luck with "GetDlgItemInt"... I want to get a numeric value from the edit box, not a string. When I use the class wizard and make a new integer value for the edit box Control, what use is that value? Shouldn't it reflect the number typed into the edit box?

    Now the catch is that I'd like the output box to update automatically, instead of when an "OK" type button is pressed. I tried making a function using the EN_CHANGE message on the input boxes and put in a SetWindowText function for the output edit box, but it gives an assertion error at runtime. I'm not sure why.

  4. #4
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Well if you set your edit control to only accept numeric values your "string" will be a number. If not then you could use atoi(). As a number set for you edit control I mean an ID number. You know how you define an ID don't you, or what one is right? For your update automatically what specifications? Like every 5 seconds or what? You could use GetTickCount() for the timing but if I am misunderstanding you about the updating it automatically please correct me.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  5. #5
    Registered User skillet's Avatar
    Join Date
    Feb 2002
    Posts
    20
    I'll make this my last post in this thread, but I'd love any further input. I hope it is some help to others later.

    I'm learning--but that's the whole point, isn't it? I had been using "atoi" previously, but I thought there should be a better way to get an integer value out of the edit box. By defining it's value as an integer, it will only allow integer inputs, but I still had to pick up the contents as a string and then convert it.

    The value associated with an edit box is only updated when the dialog is initialized and when the dialog is closed (look up "DoDataExchange"). That works fine for pop-up dialog boxes that set values within other programs, but for a dialog based app it isn't real useful to have the edit box contents never update the associated variable until you close the dialog.

    Here's the story behind my self-imposed homework. My mother has just bought an oval mirror for her bathroom. The mounting brackets didn't give what weight they were recommended for, but gave the dimensions of a rectangle mirror they would support. My mother wanted to know if her oval mirror was too big. We want to compare the area of the mirrors--which should be a good approximation to comparing weights.

    I have defined my own member variables for the values I need, and am setting them with " GetDlgItemInt" when the edit box contents change, instead of looking for the variable associated with the edit box. I then calculate the new area of the rectangle and call a function that writes out the results to my ouput edit box. The "SetWindowText" function in the output is causing an assertion error when I run the debug application. I'm sure there is a good reason, but I havn't figured it out yet.

    I'm happy for now that the release version works. Here is the heart of the code, and I think enough for someone to figure out why I'm getting an assertion error. The error occurs in the "SetWindowText" call under "OutputArea".

    Code:
    class CMirrorDlg : public CDialog
    {
    // Construction
    public:
    	CMirrorDlg(CWnd* pParent = NULL);	// standard constructor
    
    // Dialog Data
    	//{{AFX_DATA(CMirrorDlg)
    	enum { IDD = IDD_MIRROR_DIALOG };
    	CEdit	m_RectAreaControl;
    	CEdit	m_OvalAreaControl;
    	CSpinButtonCtrl	m_spinRectWidth;
    	CSpinButtonCtrl	m_spinRectHeight;
    	CSpinButtonCtrl	m_spinOvalWidth;
    	CSpinButtonCtrl	m_spinOvalHeight;
    	//}}AFX_DATA
    
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CMirrorDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
    	//}}AFX_VIRTUAL
    
        void OutputArea(void);
    
    	//Variables
    	int m_nOvalHeight;
    	int m_nOvalWidth;
    	int m_nOvalArea;
    	
    	int m_nRectHeight;
    	int m_nRectWidth;
    	int m_nRectArea;
    
    // Implementation
    protected:
    	HICON m_hIcon;
    
    	// Generated message map functions
    	//{{AFX_MSG(CMirrorDlg)
    	virtual BOOL OnInitDialog();
    	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    	afx_msg void OnPaint();
    	afx_msg HCURSOR OnQueryDragIcon();
    	afx_msg void OnChangeOvalHeight();
    	afx_msg void OnChangeOvalWidth();
    	afx_msg void OnChangeRectHeight();
    	afx_msg void OnChangeRectWidth();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    
    
    
    void CMirrorDlg::OutputArea(void) 
    {
    	CString chBuffer;
    
        chBuffer.Format( "%d square inches", m_nOvalArea);
    	m_OvalAreaControl.SetWindowText(chBuffer);
    
        chBuffer.Format( "%d square inches", m_nRectArea);
    	m_RectAreaControl.SetWindowText(chBuffer);
    }
    void CMirrorDlg::OnChangeOvalHeight() 
    {
    	// TODO: If this is a RICHEDIT control, the control will not
    	// send this notification unless you override the CDialog::OnInitDialog()
    	// function and call CRichEditCtrl().SetEventMask()
    	// with the ENM_CHANGE flag ORed into the mask.
    	
    	// TODO: Add your control notification handler code here
    	m_nOvalHeight = GetDlgItemInt(IDC_OvalHeight);
    	m_nOvalArea = int(3.14159 * (m_nOvalHeight/2.0) * (m_nOvalWidth/2.0));
    	OutputArea();
    }
    
    void CMirrorDlg::OnChangeOvalWidth() 
    {
    	// TODO: If this is a RICHEDIT control, the control will not
    	// send this notification unless you override the CDialog::OnInitDialog()
    	// function and call CRichEditCtrl().SetEventMask()
    	// with the ENM_CHANGE flag ORed into the mask.
    	
    	// TODO: Add your control notification handler code here
    	m_nOvalWidth = GetDlgItemInt(IDC_OvalWidth);
    	m_nOvalArea = int(3.14159 * (m_nOvalHeight/2.0) * (m_nOvalWidth/2.0));
    	OutputArea();
    }
    
    void CMirrorDlg::OnChangeRectHeight() 
    {
    	// TODO: If this is a RICHEDIT control, the control will not
    	// send this notification unless you override the CDialog::OnInitDialog()
    	// function and call CRichEditCtrl().SetEventMask()
    	// with the ENM_CHANGE flag ORed into the mask.
    	
    	// TODO: Add your control notification handler code here
    	m_nRectHeight = GetDlgItemInt(IDC_RectHeight);
    	m_nRectArea = int(m_nRectHeight * m_nRectWidth);
    	OutputArea();
    }
    
    void CMirrorDlg::OnChangeRectWidth() 
    {
    	// TODO: If this is a RICHEDIT control, the control will not
    	// send this notification unless you override the CDialog::OnInitDialog()
    	// function and call CRichEditCtrl().SetEventMask()
    	// with the ENM_CHANGE flag ORed into the mask.
    	
    	// TODO: Add your control notification handler code here
    	m_nRectWidth = GetDlgItemInt(IDC_RectWidth);
    	m_nRectArea = int(m_nRectHeight * m_nRectWidth);
    	OutputArea();
    }

  6. #6
    Registered User skillet's Avatar
    Join Date
    Feb 2002
    Posts
    20
    ok.. one more, because I didn't answer your question about "automatically update" at all.

    When I type a number into the rectangle width box, I want the rectangle area to immediately show the new area. I don't want to have to use "enter" or a button to make the area re-calculate. My "OnChange" functions are called as soon as anything in the heighth or width edit boxes changes. The only (very minor) drawback to that is that if I put in "20" inches for one side, the area will calculate with "2" inches for one side when I type the first character, and then calculate again when I type the "0".

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    if I put in "20" inches for one side, the area will calculate with "2" inches for one side when I type the first character, and then calculate again when I type the "0".
    Well there's no way around that. Your program can't magically know whether the user intends for the rectangle to be 2 inches, or whether the user is going to enter in another digit afterwards. The only way you could get around this is to set a timer in your OnChange() function. When the timer expires, then change the height and width of the rectangle. If OnChange() is called before the timer expires, then you just reset the timer.

  8. #8
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Well you could poll for EN_CHANGE messages(do this by adding a case EN_CHANGE in the Dialog Proc) and whenever you receive an EN_CHANGE message you could get the int out of the edit control and do the calculations with it, then set the text to the value of the calculations. Then if they enter a 2 it will calculate and then if they enter a 0 it will calculate again but this time for the number 20 instead of 2. I'm pretty sure I get what you mean by updating it now. I could probably provide some source code if you asked me but I NEVER do MFC I just hate it, I'm Win32 all the way.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  9. #9
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Here is an example program I wrote IN Win32! It automatically multiplies the number you enter by 2 and writes it to the dialog box without hitting any buttons. I could make it do more complicated equations but just made it multiply by two. They are attached.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Well you could poll for EN_CHANGE messages
    He's already doing exactly what you are suggesting. In MFC OnChange() is the event handler for the EN_CHANGE notification message.

  11. #11
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Oh ok, but what does he want to do that isn't happening in my program?
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Replies: 2
    Last Post: 03-24-2006, 08:36 PM
  3. getting a headache
    By sreetvert83 in forum C++ Programming
    Replies: 41
    Last Post: 09-30-2005, 05:20 AM
  4. Quack! It doesn't work! >.<
    By *Michelle* in forum C++ Programming
    Replies: 8
    Last Post: 03-02-2003, 12:26 AM
  5. easy if you know how to use functions...
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 01-31-2002, 07:34 AM