Objective Grid: Specifying cell formats

Article ID: 150
Last updated: 04 Jun, 2018
Article ID: 150
Last updated: 04 Jun, 2018
Revision: 3
Views: 6134
Posted: 11 Jan, 2001
by Meltreger B.
Updated: 04 Jun, 2018
by Meltreger B.

Problem


Is there a way to specify the format for cells?


Cause



Action


Objective Grid 6.0 introduces the new CGXStyle::SetFormat() for number formatting. Check out the class reference on this attribute. When using CGXStyle::SetFormat() make sure the value type for the cells that you want to format is GX_VT_NUMERIC. See CGXStyle::SetValueType().

Here is an example how to use this new attribute:

SetExpressionRowCol(nRow, 1, _T("General"));
SetExpressionRowCol(nRow+1, 1, _T("7777.77"));
SetStyleRange(CGXRange(nRow+1, 1), CGXStyle().SetFormat(GX_FMT_GEN).SetPlaces(15));
SetExpressionRowCol(nRow, 2, _T("Fixed"));
SetExpressionRowCol(nRow+1, 2, _T("7777.77"));
SetStyleRange(CGXRange(nRow+1, 2), CGXStyle().SetFormat(GX_FMT_FIXED).SetPlaces(4));
SetExpressionRowCol(nRow, 3, _T("Scientific"));
SetExpressionRowCol(nRow+1, 3, _T("7777.77"));
SetStyleRange(CGXRange(nRow+1, 3), CGXStyle().SetFormat(GX_FMT_FLOAT).SetPlaces(4));

Sometimes, you may be interested in formatting cells on your own without using the CGXStyle::SetFormat() attribute. You then have the option to a) override GetStyleRowCol() and StoreStyleRowCol() or b) to subclass a control from CGXEditControl.

You could override the GetStyleRowCol() method and change the value in your overridden method:

BOOL CMyGrid::GetStyleRowCol(ROWCOL nRow, ROWCOL nCol, CGXStyle& style,...)
{
if (!CGXGridCore::GetStyleRowCol(nRow, nCol, style, ...)
return FALSE;
if (nCol == yourSpecifcCol)
{
// get value with style.GetValueRef()
char s[20];
wsprint(s, "$%g", value);
style.SetValue(s);
}

return TRUE;

}

BOOL CMyGrid::StoreStyleRowCol(ROWCOL nRow, ROWCOL nCol, const CGXStyle* pStyle,...)
{

if (nCol == yourSpecifcCol && pStyle->GetIncludeValue())
{
CGXStyle style = *pStyle;
CString s = style.GetValueRef();

// remove $ from value
style.SetValue(s);

return CGXGridCore::StoreStyleRowCOl(nRow, nCol, &style,..);

}

return CGXGridCore::StoreStyleRowCOl(nRow, nCOl, pStyle, ...);

}

You can derive a class from CGXEditControl and format the value as it should be displayed in the cell. The format can be stored in a user attribute.

If you implement the following class CNumericEditControl:

// header (.h) file

class CNumericEditControl: public CGXEditControl
{

DECLARE_CONTROL(CNumericEditControl)
public:
// Constructor & Destructor
CNumericEditControl(CGXGridCore* pGrid, UINT nID);
protected:
// Overrides
BOOL GetControlText(CString& strResult, ROWCOL nRow, ROWCOL nCol, LPCTSTR pszRawValue, const CGXStyle& style);

BOOL ValidateString(const CString& sEdit);

// Generated message map functions
//{{AFX_MSG(CNumericEditControl)
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

// implementation (.cpp) file
///////////////////////////////////////////////////////////////////

// CNumericEditControl control

IMPLEMENT_CONTROL(CNumericEditControl, CGXEditControl)

CNumericEditControl::CNumericEditControl(CGXGridCore* pGrid, UINT nID)

: CGXEditControl(pGrid, nID)
{

}

BEGIN_MESSAGE_MAP(CNumericEditControl, CGXEditControl)

//{{AFX_MSG_MAP(CNumericEditControl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// GetControlText
//
// Convert the value which is stored in the style object into
// the text which should be displayed in the cell.
//
BOOL CNumericEditControl::GetControlText(CString& sResult, ROWCOL nRow, ROWCOL nCol, LPCTSTR pszRawValue, const CGXStyle& style)
{

// base class version will store current text in sResult
if (!CGXEditControl::GetControlText(sResult, nRow, nCol, pszRawValue, style))
return FALSE;
if (!sResult.IsEmpty())
{
// gather information

// ... value
double d = atof(style.GetValueRef());

// ... format
CString sFormat;
style.GetUserAttribute(IDS_UA_NUMEDITFORMAT, sFormat);

// Now, format the text
_stprintf(sResult.GetBuffer(128), sFormat, d);
sResult.ReleaseBuffer();

}

return TRUE;

}

BOOL CNumericEditControl::ValidateString(const CString& sEdit)
{

// cycle through string and check each character if it is a digit
for (int n = 0; n < sEdit.GetLength(); n++)
{
if (!isdigit(sEdit[n]) && sEdit[n] != '.')
return FALSE;
}

return TRUE;

}

You can register the control and user attribute in the OnInitialUpdate() routine of your grid class

// Register all controls and user attributes for the view
// IDS_CTRL_NUMEDIT and IDS_UA_NUMEDITFORMAT are string resource
// ids you have to add to your application.
RegisterControl(IDS_CTRL_NUMEDIT, new CNumericEditControl(this, IDS_CTRL_NUMEDIT));

GetParam()->GetStylesMap()->AddUserAttribute(IDS_UA_NUMEDITFORMAT);

and later apply it to cells with

SetStyleRange(CGXRange(4,3,10,5),
CGXStyle()
.SetControl(IDS_CTRL_NUMEDIT)
.SetUserAttribute(IDS_UA_NUMEDITFORMAT, "%.3f")
.SetHorizontalAlignment(DT_RIGHT)
);

The user can also change the numeric formatting of cells with the Format|Cells dialog if he clicks on the "User" property sheet.

See also the date control in the dbfbrows sample. It implements a date control for international dates.

If you want the full number to be displayed when the cell is in edit mode, you should also override SetValue(). For example if the cell is formatted to show 2 decimal place. When user input 1.23456 and hit enter, the cell should show 1.23. When the user edit that cell (by F2 or click on the text in the cell), 1.23456 (the full number) should be displayed.

void CNumericEditControl::SetValue(LPCTSTR pszRawValue)
{
// Convert the value to the text which should be
// displayed in the current cell and show this
// text.
if (m_hWnd)
SetWindowText(pszRawValue);
}

This article was:   Helpful | Not helpful
Report an issue
Article ID: 150
Last updated: 04 Jun, 2018
Revision: 3
Views: 6134
Posted: 11 Jan, 2001 by Meltreger B.
Updated: 04 Jun, 2018 by Meltreger B.

Others in this category