Click here to Skip to main content
11,932,103 members (61,845 online)
Click here to Skip to main content
Add your own
alternative version


25 bookmarked

CGridCellNumeric - A numeric cell class for the MFC Grid

, 22 Sep 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
A locale aware, editable, self validating numeric cell class for the MFC Grid. Configurable for integers, floating point, or currencies.


I currently have had a need for a decent grid control that has the ability to edit and display numbers, among other things. The best one that I could come up with within my price range (free) was Chris Maunder's MFC Grid 2.25 [^]. But unfortunately, for me it needed some modifications to get it to work the way I wanted. The one modification I present here is the CGridCellNumeric class, which is used to display and edit numbers and currencies. This class is a severe modification of the CGridCellNumeric class that is included with the MFC Grid. The class uses the computer's locale settings to display the numbers, but does provide a way for you to override those settings. The numbers, if you set the cell to use floating point, will be kept to an accuracy of nine decimal places, even if they are only displayed to two. The full nine decimal digits are shown, if needed, in the edit control part of the cell.

Input validation is done on the fly as the user is typing. All validation is done in the EN_UPDATE message handler, so any cut/copy and paste operations are immediately validated. If the user deletes the text in the cell, the value is set to zero.

Using the CGridCellNumeric class

Download and unzip the file, and save the CPP and header file into the "GridCtrl/NewCellTypes" folder. They can replace the existing GridCellNumeric files already there. I used those existing files as the starting point for this code.

To add a CGridCellNumeric cell to the grid, simply add it as you would any other cell type:

m_Grid.SetCellType(1,1, RUNTIME_CLASS(CGridCellNumeric));

and you are ready to go. To set the options for the numerical cell, you have to get a pointer to it, and call one of its member functions.

CGridCellNumeric *pCell = (CGridCellNumeric *)m_Grid.GetCell(1, 1);
pCell->SetFlags(CGridCellNumeric::Currency | CGridCellNumeric::Negative);

The CGridCellNumeric class is derived from CGridCell, and the edit control class (CInPlaceNumEdit) is derived from CInPlaceEdit, so other than the API functions listed below, you can use this cell the same as any other editable cell that is available for the MFC Grid.

Important changes to class CInPlaceEdit

There is one small, but very important change that has to be made to the CInPlaceEdit class. You must move the CRect m_Rect variable from being a private member to being a protected member of the CInPlaceEdit class. This has to done so that the derived CInPlaceNumEdit class can reset the initial size of the edit box if needed, and it needs access to the m_Rect member in order to do so. So in the InPlaceEdit.h file, make the following changes:

class CInPlaceEdit : public CEdit

    CRect m_Rect;   // Add this line

//  CRect m_Rect; // comment out, or remove, this line

Also, but not as important, as it is more a cosmetic thing than anything else, is to change the size of the space buffer that CInPlaceEdit uses to calculate the new size of the edit control as you are typing. Go to the file InPlaceEdit.cpp, in the function CInPlaceEdit::OnChar(), line 178, and change the size of the buffer from two spaces to six spaces:

// change from:
//  str += _T("  ");
//  to
    str += _T("      ");

This change will prevent the edit control from scrolling the text to the left before it resizes the window.

CGridCellNumeric Class API functions

  • DWORD SetFlags (DWORD dwFlags)

    Sets the flags that controls how the cell operates. Possible flags are:

    • CGridCellNumeric::Integer - The cell handles only integers, no floating point numbers can be displayed or entered.
    • CGridCellNumeric::Real - The cell handles floating point numbers.
    • CGridCellNumeric::Currency - The cell handles currency numbers.

      Please note that these first three values are mutually exclusive, and if they are not specified when you place a call to SetFlags, the CGridCellNumeric::Integer flag is assumed by default.

    • CGridCellNumeric::Negative - The cell can handle negative numbers. If this flag is not specified, the cell will handle positive numbers only.
    • CGridCellNumeric::Silent - If this flag is not set, the edit control associated with the CGridCellNumeric cell will emit a warning beep if an invalid entry is made. Use this flag to silence that beep.

    Return Value:

    A DWORD containing the previous flags, -1 if the new flags could not be set.

  • DWORD GetFlags()

    Gets the current flags. See SetFlags above for possible values.

    Return Value:

    A DWORD containing the current flags.

  • BOOL SetNumber (double Number)

    Sets the value of the number displayed in the cell. Even though it is stored as a double, the accuracy is guaranteed to only nine decimal points. Unless specified by SetNumberFmt() or SetCurrencyFmt() functions (see below), the numbers will be displayed according to the computer's locale settings, but the accuracy of the internal number is guaranteed to nine decimal points, and those decimal points are all shown in the edit control.

    Return Value:

    TRUE if the number was successfully set. FALSE if not.

  • double GetNumber()

    Gets the number currently stored in the cell. This number is guaranteed accurate to nine decimal points.

    Return Value:

    A double containing the number in the cell.

  • void SetNumberFmt (LPNUMBERFMT lpNumberFmt)

    Use this function if you want to override the computer's default settings for how integers and floating point numbers are displayed. You can pass in a pointer to a NUMBERFMT structure that is used by the GetNumberFormat() function. Look up GetNumberFormat() and NUMBERFMT in MSDN for more information.

  • void SetCurrencyFmt (LPCURRENCYFMT lpCurrencyFmt)

    Use this function if you want to override the computer's default settings for how currencies are displayed. You can pass in a pointer to a CURRENCYFMT structure that is used by the GetCurrencyFormat() function. Look up GetCurrencyFormat() and CURRENCYFMT in MSDN for more information.


Don't know if I will ever get to it, but I think it would be cool if the cell supported different based numbers other than just base 10. Another possibility is to support exponential format. But that is probably going to be more work than what I am willing to put out.


  • Chris Maunder for his excellent grid control.
  • Andrew Truckle for his original CGridCellNumeric class that this class is based on.


  • Sept 15, 2004 - released into the wild.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

PJ Arends
Canada Canada
No Biography provided

You may also be interested in...

Comments and Discussions

Questionimplied decimal for numeric field Pin
Ian Sutcliffe15-Oct-15 13:46
memberIan Sutcliffe15-Oct-15 13:46 
AnswerRe: implied decimal for numeric field Pin
PJ Arends16-Oct-15 8:49
professionalPJ Arends16-Oct-15 8:49 
Questionaccess violation after SetNumberFmt() and SetNumber() Pin
wiwi6222-Jan-13 0:29
memberwiwi6222-Jan-13 0:29 
Hello all,
I just used this greatful class to handle floats within a grid.
I am working under German locale, but the numbers in my spreadsheet should be displayed in "-123.45" form. Thus I defined
nf.Grouping      = 0;
nf.LeadingZero   = 1;
nf.lpDecimalSep  = _T(".");
nf.lpThousandSep = _T(",");
nf.NegativeOrder = 1;
nf.NumDigits     = 2;
pg->SetCellType(i, j, RUNTIME_CLASS(CGridCellNumeric));
CGridCellNumeric *pCell = (CGridCellNumeric *)pg->GetCell(i, j);
pCell->SetFormat(2);  // 0 = left, 1 = center, 2 = right (settings all guessed)

// and now the access violation:
What's wrong in my code?
Kind Regards

AnswerRe: access violation after SetNumberFmt() and SetNumber() Pin
wiwi6222-Jan-13 0:53
memberwiwi6222-Jan-13 0:53 
QuestionSetNumberFmt Pin
Ian Sutcliffe26-Jun-12 17:59
memberIan Sutcliffe26-Jun-12 17:59 
AnswerRe: SetNumberFmt Pin
PJ Arends27-Jun-12 7:03
memberPJ Arends27-Jun-12 7:03 
GeneralRe: SetNumberFmt Pin
Ian Sutcliffe27-Jun-12 12:36
memberIan Sutcliffe27-Jun-12 12:36 
GeneralExcellent! Pin
urb012330-May-07 9:10
memberurb012330-May-07 9:10 
GeneralEdit cells in virtual mode Pin
anaigir6-Apr-07 3:38
memberanaigir6-Apr-07 3:38 
GeneralVisual Studio 2005 compile error Pin
WhiTeWo1F24-Nov-05 23:27
memberWhiTeWo1F24-Nov-05 23:27 
GeneralRe: Visual Studio 2005 compile error Pin
PJ Arends25-Nov-05 8:19
memberPJ Arends25-Nov-05 8:19 
GeneralRe: Visual Studio 2005 compile error Pin
WhiTeWo1F25-Nov-05 10:31
memberWhiTeWo1F25-Nov-05 10:31 
GeneralRe: Visual Studio 2005 compile error Pin
urb012330-May-07 9:25
memberurb012330-May-07 9:25 
GeneralCrash when deleting Pin
WhiTeWo1F19-Nov-05 14:40
memberWhiTeWo1F19-Nov-05 14:40 
GeneralRe: Crash when deleting Pin
PJ Arends19-Nov-05 15:47
memberPJ Arends19-Nov-05 15:47 
GeneralMath problem Pin
pank0076-Sep-05 4:08
memberpank0076-Sep-05 4:08 
AnswerRe: Math problem Pin
PJ Arends6-Sep-05 6:37
memberPJ Arends6-Sep-05 6:37 
GeneralComma as decimal separator doesn't work Pin
Anonymous2-Oct-04 12:21
memberAnonymous2-Oct-04 12:21 
GeneralRe: Comma as decimal separator doesn't work Pin
PJ Arends2-Oct-04 17:47
memberPJ Arends2-Oct-04 17:47 
GeneralRe: Comma as decimal separator doesn't work Pin
A. N.2-Oct-04 22:44
memberA. N.2-Oct-04 22:44 
GeneralRe: Comma as decimal separator doesn't work Pin
PJ Arends4-Oct-04 11:31
memberPJ Arends4-Oct-04 11:31 
GeneralRe: Comma as decimal separator doesn't work Pin
rm22-Dec-04 0:12
memberrm22-Dec-04 0:12 
GeneralRe: Comma as decimal separator doesn't work Pin
PJ Arends2-Dec-04 11:03
memberPJ Arends2-Dec-04 11:03 
GeneralRe: Comma as decimal separator doesn't work Pin
ABuenger22-Mar-05 6:53
memberABuenger22-Mar-05 6:53 
GeneralRe: Comma as decimal separator doesn't work Pin
PJ Arends22-Mar-05 9:19
memberPJ Arends22-Mar-05 9:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.151126.1 | Last Updated 23 Sep 2004
Article Copyright 2004 by PJ Arends
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid