|
Hi PJ,
I need an implied decimal please.. ie if NumDigits = 2 and I enter 1234, I need the decimal to insert automatically and the number to display as 12.34
Thanks for a great class.
best
Ian
|
|
|
|
|
Adding this is not all that hard.
In CGridCellNumeric::Format() Find this section and add the following:
if (m_dwFlags & (Real | Currency))
{
str.Replace(cDecimal, _T('.'));
if (NULL != m_pNumberFmt && str.Find(_T('.'), 0) == -1)
{
for (int x = str.GetLength(); x < m_pNumberFmt->NumDigits; ++x)
str.Insert(0, _T('0'));
str.Insert(str.GetLength() - m_pNumberFmt->NumDigits, _T('.'));
}
sDigits += _T('.');
}
This code is for m_dwFlags set to Real and is not extensively tested but should give you an idea of how I would do it. It probably would also be a good idea to add another flag to m_dwFlags to control this feature.
Thanks for the query. It is always good to know that someone other than myself is still using this old code.
Within you lies the power for good - Use it!
|
|
|
|
|
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
NUMBERFMT nf;
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->SetNumberFmt(&nf);
pCell->SetFlags(CGridCellNumeric::Real);
pCell->SetFormat(2);
pCell->SetNumber(1.0);
What's wrong in my code?
Kind Regards
Peter
|
|
|
|
|
In my code snippet above I omitted some lines, so the mistake is not visible.
The "nf" was created on the stack and not existing any more when calling pCell->SetNumber().
I'm so stupid .
|
|
|
|
|
Can you give me an example of using SetNumberFmt please?
I need to display some numeric columns as integers, some with 2 decimals and some with 4 decimals.
Thanks
Ian
|
|
|
|
|
See MSDN[^]
I have this code in my derived grid control's constructor:
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILZERO | LOCALE_RETURN_NUMBER, (LPTSTR)&m_NumberFmt.LeadingZero, sizeof(UINT) / sizeof(TCHAR));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER, (LPTSTR)&m_NumberFmt.NegativeOrder, sizeof(UINT) / sizeof(TCHAR));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, DecimalSep, sizeof(DecimalSep));
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, ThousandSep, sizeof(ThousandSep));
m_NumberFmt.NumDigits = 1;
m_NumberFmt.Grouping = 3;
m_NumberFmt.lpDecimalSep = DecimalSep;
m_NumberFmt.lpThousandSep = ThousandSep;
And this in the InsertRow function of my derived grid control:
case ColumnBelow:
case ColumnAbove:
case ColumnMore:
case ColumnLess:
SetCellType(row, col, RUNTIME_CLASS(CGridCellNumeric));
CGridCellNumeric *pCell = dynamic_cast<CGridCellNumeric *>(GetCell(row, col));
if (pCell)
{
pCell->SetFlags(CGridCellNumeric::Real | CGridCellNumeric::Negative);
pCell->SetNumberFmt(&m_NumberFmt);
pCell->SetFormat(DT_RIGHT);
}
}
This sets each numeric cell to have one digit after the decimal point and groups of three before the decimal point.
eg: 1234567.89 would display as 1,234,567.9
Independent ACN Business OwnerMake toll free long distance calls from your smart phone with ACN Mobile World. When connected via wifi, calls will not use any of your minutes or data, nor will there be any roaming charges. Certain conditions apply. See my website for details.
Within you lies the power for good - Use it!
|
|
|
|
|
Thanks for your quick response PJ, works a treat. Fabulous article.
|
|
|
|
|
I thought I would have to do this to get what I wanted; to find someone else had already accomplished this work, and better implemented than I would have, was a very pleasant surprise. Well spelled out instructions on use too! 5 stars!
|
|
|
|
|
Hello:
I have a GridCtrl and I'm working in virtual mode.
I have tried to editing a cell as numeric but I can´t. I need help. What's wrong here??
void CGuardarShapeFileDlg::OnVirtualMode()
{
UpdateData();
.........
m_Grid.SetEditable(TRUE);
col = 1;
for (row = 1;row < m_nRows ;row++)
{
m_Grid.SetCellType(row , col, RUNTIME_CLASS(CGridCellNumeric));
}
Thanks
Ana
|
|
|
|
|
I get this error on vs2005
gridctrl\gridcellnumeric.cpp(798) : error C2440: 'initializing' : cannot convert from 'const char *' to 'TCHAR *'
Conversion loses qualifiers
GridCtrl.cpp
How can I fix this? Is it compiler settings?
|
|
|
|
|
I had a big explanation of the error all typed up and when I hit the "Post Message" button CP decided to crap out on me and the explanation was lost. I am not going to typ it out again. See here[^] and here[^].
Changing TCHAR *ptr to LPCTSTR ptr should fix the problem.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|
Thanx a lot, that got it fixed. Although I couldnt catch up with the explanation
|
|
|
|
|
The only time my wife ever swears is when that happens, and she outdoes me when she loses a post.
I don't blame you, wish I could have seen the long answer, but the short answer worked.
|
|
|
|
|
How do I delete a row? I have a grid in list mode with one column as currency, but when I try to delete the contents of the row (by selecting the row, then pressing DEL) the program crashes.
|
|
|
|
|
Calling CGridCtrl::DeleteRow() should be all it takes. What do you mean by "crashes"? Do you get an ASSERT in debug mode? Does the code throw an unhandled exception? Does the program just quit with no errors? Is it crashing in CGridCellNumeric 's code?
More info is needed if you want me to be able to help you.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|
I do not know how to do the math using this wonderful NumericGridCellCtr. Supposed I have three cells like cell1, cell2 and cell3, but I want cell3 as a result of cell1 + cell2. How to do that?
Thanx.
|
|
|
|
|
Unfortunately this cell is not a spreadsheet like cell, it does not take formulas. But what it does have is GetNumber() and SetNumber() members.
Something like this should do what you want:
CGridCellNumeric *pCell1 = dynamic_cast<CGridCellNumeric *>(GetCell(row1, col1));
CGridCellNumeric *pCell2 = dynamic_cast<CGridCellNumeric *>(GetCell(row2, col2));
CGridCellNumeric *pCell3 = dynamic_cast<CGridCellNumeric *>(GetCell(row3, col3));
if (pCell1 && pCell2 && pCell3)
{
pCell3->SetNumber(pCell1->GetNumber() + pCell2->GetNumber());
}
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|
I tried with locale set to english and it works. But when set to my local which uses comma as separator, cell rejects it.
|
|
|
|
|
What do you mean by "rejects it"? I have tried this cell with several locales (I will admit not all of them) and have had no problems. The only problem I have noticed is when I try to drag a value that has a comma in it. But that is because the gridctrl itself does not handle dragging cells with commas in them very well.
If you let me know which locale you are using I can maybe tell you what the problem is.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
My locale is set to Slovenian. In CGridCellNumeric.Format function you replace ',' with '.' in str and then call
double Number = _tcstod(str, &EndPtr);
I think _tcstod expects locale decimal separator.
|
|
|
|
|
According to MSDN it does, but when I set my machine to a locale that uses commas instead of periods (W2K via Control Panel->Regional Options) the _tcstod function fails if the string has a comma in it.
There must be something I am missing, I will more into it when I have the time.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
Yes, you are right, I have the same problem with
a German locale setting. The CGridCellNumeric.Format
function is buggy concerning this. Did you find a
solution meanwhile?
Raimund
|
|
|
|
|
Hey Raimund,
I think this locale aware stuff is a little bit more work than I had anticipated, but I do want to get it working. Can you try the following code and let me know if it works?
What I am now doing is replacing the user locale decimal point with the system decimal point, rather than with a period as was done previously.
BOOL CGridCellNumeric::Format(CString &TheString)
{
int count = 0;
CString str = TheString;
CString buffer;
CString sDigits;
TCHAR cDecimal = 0;
TCHAR cSystemDecimal = 0;
TCHAR cNegative = 0;
int iNegative = -1;
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SNATIVEDIGITS,
NULL,
0);
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SNATIVEDIGITS,
sDigits.GetBuffer(count),
count);
sDigits.ReleaseBuffer();
if (!count)
sDigits = _T("0123456789");
if (m_dwFlags & Currency)
{
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SMONDECIMALSEP,
NULL,
0);
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SMONDECIMALSEP,
buffer.GetBuffer(count),
count);
buffer.ReleaseBuffer();
cDecimal = count ? buffer[0] : _T('.');
sDigits += cDecimal;
count = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
LOCALE_SMONDECIMALSEP,
NULL,
0);
count = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
LOCALE_SMONDECIMALSEP,
buffer.GetBuffer(count),
count);
buffer.ReleaseBuffer();
cSystemDecimal = count ? buffer[0] : _T('.');
sDigits += cDecimal;
}
else
{
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SDECIMAL,
NULL,
0);
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SDECIMAL,
buffer.GetBuffer(count),
count);
buffer.ReleaseBuffer();
cDecimal = count ? buffer[0] : _T('.');
count = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
LOCALE_SDECIMAL,
NULL,
0);
count = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
LOCALE_SDECIMAL,
buffer.GetBuffer(count),
count);
buffer.ReleaseBuffer();
cSystemDecimal = count ? buffer[0] : _T('.');
}
if (m_dwFlags & Negative)
{
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SNEGATIVESIGN,
NULL,
0);
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SNEGATIVESIGN,
buffer.GetBuffer(count),
count);
buffer.ReleaseBuffer();
cNegative = count ? buffer[0] : _T('-');
sDigits += cNegative;
if (m_dwFlags & Currency)
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_INEGCURR | LOCALE_RETURN_NUMBER,
(LPTSTR)&iNegative,
sizeof(int) / sizeof(TCHAR));
else
count = GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
(LPTSTR)&iNegative,
sizeof(int) / sizeof(TCHAR));
if (!count)
iNegative = 1;
if (m_dwFlags & Currency)
{
if (iNegative == 0 || iNegative == 4 || iNegative == 14 || iNegative == 15)
sDigits += _T("()");
}
else if (iNegative == 0)
sDigits += _T("()");
}
if (m_dwFlags & (Real | Currency))
{
str.Replace(cDecimal, cSystemDecimal);
sDigits += cSystemDecimal;
}
if ((m_dwFlags & TypeMask) == Integer)
{
int pos = str.Find(_T('.'), 0);
if (pos != -1)
str.Delete(pos, str.GetLength() - pos);
}
LPCTSTR digits = sDigits;
for(int i = str.GetLength() - 1; i >= 0; --i)
{
TCHAR *ptr = _tcschr(digits, str[i]);
if (ptr == NULL)
str.Delete(i);
else
{
int diff = (int)(ptr - digits);
if (diff < 10 && (*ptr < _T('0') || *ptr > _T('9')))
{
TCHAR ch = (TCHAR)(0x30 + diff);
str.SetAt(i, ch);
}
}
}
if (m_dwFlags & Negative)
{
CString neg = (iNegative ? _T("") : _T("()"));
neg += cNegative;
if (str.FindOneOf(neg) != -1)
{
str.Remove(cNegative);
str.Remove(_T('('));
str.Remove(_T(')'));
str.Insert(0, _T('-'));
}
}
TCHAR *EndPtr = NULL;
double Number = _tcstod(str, &EndPtr);
str.Replace(cSystemDecimal, _T('.'));
if (*EndPtr == NULL)
{
CString Formatted;
if (m_dwFlags & Currency)
{
count = GetCurrencyFormat(LOCALE_USER_DEFAULT,
NULL,
str,
m_pCurrencyFmt,
NULL,
0);
count = GetCurrencyFormat(LOCALE_USER_DEFAULT,
NULL,
str,
m_pCurrencyFmt,
Formatted.GetBuffer(count),
count);
Formatted.ReleaseBuffer();
}
else
{
count = GetNumberFormat(LOCALE_USER_DEFAULT,
NULL,
str,
m_pNumberFmt,
NULL,
0);
count = GetNumberFormat(LOCALE_USER_DEFAULT,
NULL,
str,
m_pNumberFmt,
Formatted.GetBuffer(count),
count);
Formatted.ReleaseBuffer();
}
if (count)
{
if ((m_dwFlags & TypeMask) == Integer)
{
int pos = Formatted.Find(cDecimal, 0);
if (pos != -1)
{
Formatted.Delete(pos);
while (pos < Formatted.GetLength() && Formatted[pos] == sDigits[0])
Formatted.Delete(pos);
}
}
m_nNumber = Number;
TheString = Formatted;
return TRUE;
}
}
TRACE (_T("CGridCellNumeric::Format() - Failed to correctly format string."));
return FALSE;
}
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
I've just downloaded the sources and with my locale set to german it works perfectly with commas. Were any changes to the sources made after this discussion?
|
|
|
|
|
ABuenger wrote:
Were any changes to the sources made after this discussion?
No, I never heard anything back after I posted the proposed fix so I did not know if it was working or not, so I had nothing to update. The control works great for what I am using it for, but I am sure it could use a lot of improvement. I like to think that CP is about collaboration so if you (or anyone else who reads this) has any ideas or bug fixes, implement them and post the fixes on this forum. Together we can make great things;)
I am glad to hear that you have it working, thanks for letting me know
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it! Honoured as one of The Most Helpful Members of 2004
|
|
|
|
|