Numeric edit and numeric spin controls

In my application I needed an edit control which accepts only numeric numbers. In many science applications this is indispensable, but it is actually not implemented in MS-Visual C/C++. It is not difficult to implement this control and I see that some people implemented it. In my own code, some new features were enriched as error messages and range defines, etc.
Note: to use the CNumEdit class properly, the ES_NUMBER, ES_MULTILINE must not be set.

Another control added in my work is CNumSpinCtrl which enables using a spin control as a numeric one which is also not implemented in MFC.

Note: to use the CNumSpinCtrl class properly, the ES_AUTOBUDDY, ES_SETBUDDYINTEGER must not be set.

Your suggestions are appreciated. Enjoy!


class CNumEdit : public CEdit
{
	DECLARE_DYNAMIC(CNumEdit)
public:
	CNumEdit();
	virtual ~CNumEdit();
	enum {VALID = 0x00, OUT_OF_RANGE = 0x01, INVALID_CHAR = 0x02};
	virtual void ChangeAmount(int step);
	virtual float GetDelta();
	virtual void SetDelta(float delta);
	virtual void GetRange(float &min, float &max)const; 
	virtual void SetRange(float min, float max);
	virtual void Verbose(BOOL v);
	virtual BOOL Verbose()const; 
	virtual int IsValid()const; 
	virtual int IsValid(const CString &str)const; 
	virtual BOOL SetValue(float val);
	virtual float GetValue()const; 
protected:
	virtual CString& ConstructFormat(CString &str, float num);
	BYTE m_NumberOfNumberAfterPoint;
	BOOL m_Verbose;
	float m_Delta, m_MinValue, m_MaxValue;
	DECLARE_MESSAGE_MAP()
};

class CNumSpinCtrl : public CSpinButtonCtrl
{
	DECLARE_DYNAMIC(CNumSpinCtrl)
public:
	CNumSpinCtrl();
	virtual ~CNumSpinCtrl();
	virtual void SetDelta(float delta);
	virtual float GetDelta();
	virtual void SetBuddy(CNumEdit *edit);
	virtual CNumEdit* GetBuddy() const;
	virtual void GetRange(float &lower, float& upper ) const;
	virtual void SetRange(float nLower, float nUpper );
	virtual float GetPos();
	virtual void SetPos(float val);
};



Download demo project - 16 KB

Date Last Updated: May 17, 1999



Comments

  • Float edit control in C#

    Posted by yagnesh on 01/20/2005 04:27am

    How to make my own float edit text box in c#. It should work based on masking provided. e.g. if ####.## is a mask then 1234.56 should accept not 12.3345. Plz mail me the solution on yagneshpatel.windowmaker.com

    Reply
  • how to use

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

    Originally posted by: Julia

    Do you mind telling me how to use your class in viewform?

    Thank you very much,

    Julia

    Reply
  • Thank's

    Posted by Legacy on 12/21/2000 12:00am

    Originally posted by: Flo

    Great code !!!
    
    

    Thank's for your code and thank's Codeguru team!

    Reply
  • Numeric edit and numeric spin controls

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

    Originally posted by: Pilar Garc�a

    Excellent! I have tried with usual Edit and CSpinButtonCtrl controls but your classes are much better. With the first, the edit box must be "only read", for example.

    I�m learning much with codeguru. Thank you very much!

    Reply
  • /editctrl/NumericSpin.shtml

    Posted by Legacy on 06/10/1999 12:00am

    Originally posted by: Julie Dinh

    Hi!! I was looking at codeguru and found your article...
    I am sorry but "are u vietnames???" ...your name kindda looks like one....anyway...back to the question...
    "how do u disable a CEdit"...that is you have a small edit
    box....if the edit box is not in used...i want to disable it or greyed it out...but i don't know how...so ....heeeeelp...

    your reply is truly appreciated....
    Julie

    Reply
  • Modification for wrap, minus, and decimal

    Posted by Legacy on 04/29/1999 12:00am

    Originally posted by: Corey McKenzie

    These modifications allow you to enter a decimal as the first character (it already accepted it after a
    number), a minus sign, and to support Wrap on the spin control.
    
    

    In NumEdit.cpp:
    int CNumEdit::IsValid() const
    {
    CString str;
    GetWindowText(str);
    return IsValid( str );
    }

    int CNumEdit::IsValid(const CString &str) const
    {
    int res = VALID;
    float f;
    char lp[10];
    // need this to accept a minus sign.
    if( str.GetLength() == 1 && (str[0] == '-' || str[0] == '.'))
    return VALID;
    if (sscanf(str, "%f%s", &f, lp) != 1) res = INVALID_CHAR;
    if (f > m_MaxValue && f < m_MinValue) res = OUT_OF_RANGE;
    if (m_Verbose && res != VALID)
    {
    CString msg;
    msg.Empty();
    if (res & OUT_OF_RANGE) msg += _T("Given value is out of range.\n");
    if (res & INVALID_CHAR) msg += _T("Characters must be a number.\n");
    AfxMessageBox(str, MB_OK | MB_ICONSTOP);
    }
    return res;
    }

    void CNumEdit::ChangeAmount(int step, BOOL bWrap)
    {
    float fDelta = step*m_Delta;
    float f = GetValue();
    // This messy bit of code gets around a floating point resolution problem.
    // For example, if your step is -1 and m_Delta is .1, you would end up
    // with -1.49xxx e-9 and it would never set the control to zero. The old
    // 0 != 0 problem.
    if( f == -fDelta )
    f = 0;
    else
    f += fDelta;
    if (f > m_MaxValue)
    {
    if( bWrap )
    f = m_MinValue;
    else
    f = m_MaxValue;
    }
    else if (f < m_MinValue)
    {
    if( bWrap )
    f = m_MaxValue;
    else
    f = m_MinValue;
    }
    SetValue(f);
    }

    In NumEdit.h
    virtual void ChangeAmount(int step, BOOL bWrap);

    In NumSpinCtrl.cpp
    void CNumSpinCtrl::OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult)
    {
    NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
    DWORD bWrap = (GetStyle() & UDS_WRAP);
    if ((pNMUpDown->iPos <= pNMUpDown->iDelta) ||
    (pNMUpDown->iPos >= 1000 - pNMUpDown->iDelta)) pNMUpDown->iPos = 500;
    CNumEdit *m_Edit = GetBuddy();
    if (m_Edit)
    if (m_Edit->IsKindOf(RUNTIME_CLASS(CNumEdit)))
    m_Edit->ChangeAmount(pNMUpDown->iDelta, bWrap);
    *pResult = 0;
    }


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

Top White Papers and Webcasts

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • Live Webinar Tuesday, August 26, 2014 1:00 PM EDT Customers are more empowered and connected than ever, and the customer's journey has grown more complex. Their expectations are growing and trust is diminishing as they may interact with multiple brands through web, mobile and social channels. Considering 70% of the buying process in a complex sale is already complete before prospects are willing to engage with a live salesperson -- it's critical to understand your customers and anticipate their needs.* …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds