The best place for all customizations is the
ICustomDraw interface and its implementation in the
CCustomDraw class. To customize the drawing, you can derive from
CCustomDraw and then override the function
ICustomDraw::DrawCell.
In general, implementation of this interface is quite easy. For more details about drawing, please see the Drawing workflow. The CCustomDraw::DrawCell() function is called each time, when the grid paints a cell. In the overridden function you get all information about the row, column, business object, colors, fonts, etc. You can set the appropriate appearance for each cell at any moment. Below you find the basic implementation of the CCustomDraw interface:
CMyCustomDraw::CMyCustomDraw(bool autoDelete) : CCustomDraw(autoDelete)
{
}
void CMyCustomDraw::DrawCell(Dapfor::GUI::CGridCell& cell, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter)
{
BaseClass::DrawCell(cell, paintContext, paintFilter);
}
Finally, let's set the instance of this interface to the grid:
m_Grid.SetCustomDraw(new CMyCustomDraw(true));
You can change appearance by modifying the 'cell' value. For example, let's show how to modify the font:
void CMyCustomDraw::DrawCell(Dapfor::GUI::CGridCell& cell, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter)
{
CFont font;
if(CFont* initialFont = cell.GetPaintInfo().GetFont())
{
LOGFONT logFont;
initialFont->GetLogFont(&logFont);
if ( cell.GetColumn() != 0 &&
(cell.GetColumn()->GetFid() == COrder::FidProduct))
{
logFont.lfHeight = -MulDiv(12, GetDeviceCaps(paintContext.GetDC(), LOGPIXELSY), 72);
}
if( cell.GetColumn() != 0 &&
(cell.GetColumn()->GetFid() == COrder::FidUnitPrice))
{
TCHAR name[] = _T("Arial");
memcpy(logFont.lfFaceName, name, sizeof(name));
logFont.lfItalic = 1;
logFont.lfWeight = 600;
}
font.CreateFontIndirect(&logFont);
cell.GetPaintInfo().SetFont(&font);
}
BaseClass::DrawCell(cell, paintContext, paintFilter);
}
The following code demonstrates how to change the text color:
void CMyCustomDraw::DrawCell(Dapfor::GUI::CGridCell& cell, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter)
{
...
if(cell.GetColumn() && cell.GetGridLine().GetDataObject())
{
UINT color = cell.GetPaintInfo().GetForeColor();
switch(cell.GetGridLine().GetDataObject()->GetLong(COrder::FidStatus))
{
case COrder::Ordered: color = RGB(11, 146, 63); break;
case COrder::Payed: color = RGB(106, 120, 133); break;
case COrder::Refunded: color = RGB(162, 125, 157); break;
case COrder::Cancelled: color = RGB(165, 185, 21); break;
}
cell.GetPaintInfo().SetForeColor(color);
}
BaseClass::DrawCell(cell, paintContext, paintFilter);
}
If you have an image list, it is very easy to paint a custom icon in the cell. Moreover, you can ask the grid to repaint the cell in some milliseconds and in the next painting routine, you can set a new icon. So, you can show a small 'video' in the cell.
When the user double-clicks the column separator, the grid adjusts column size to the content. If you perform custom drawing, the grid can't detect the optimal size for the cell. Nevertheless, it probes the optimal size by calling
ICustomDraw::GetOptimalCellWidth() and
ICustomDraw::GetOptimalRowHeight() methods. When you customize the drawing, we recommend you to implement these functions too.
int CMyCustomDraw::GetOptimalCellWidth(Dapfor::GUI::CGridCell& cell, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter) const
{
CFont font;
if(CFont* initialFont = cell.GetPaintInfo().GetFont())
{
LOGFONT logFont;
initialFont->GetLogFont(&logFont);
if(cell.GetColumn() != 0 && (cell.GetColumn()->GetFid() == COrder::FidProduct))
{
logFont.lfHeight = -MulDiv(12, GetDeviceCaps(paintContext.GetDC(), LOGPIXELSY), 72);
}
if(cell.GetColumn() != 0 && (cell.GetColumn()->GetFid() == COrder::FidUnitPrice))
{
TCHAR name[] = _T("Arial");
memcpy(logFont.lfFaceName, name, sizeof(name));
logFont.lfItalic = 1;
logFont.lfWeight = 600;
}
font.CreateFontIndirect(&logFont);
cell.GetPaintInfo().SetFont(&font);
}
return BaseClass::GetOptimalCellWidth(cell, paintContext, paintFilter);
}
int CMyCustomDraw::GetOptimalRowHeight(CFont* font, CDC& dc) const
{
return 16;
}