The grid offers an interface to customize data presentation. Everything (colors, fonts, images, selection, focusing, etc.) can be customized. The grid itself draws nothing. Instead, it asks the drawing interface to do painting. Therefore, the programmer has full control of data painting. This drawing interface is called
ICustomDraw. There is default implementation of this interface:
CCustomDraw. If you don't set your own implementation, the grid will use the default implementation.
The best way to configure painting is to derive from CCustomDraw class and set your implementation to the grid by calling:
class CMyCustomDraw : public Dapfor::GUI::CCustomDraw
{
....
virtual void DrawCell(Dapfor::GUI::CGridCell& cell, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter);
}
CMyCustomDraw* customDraw = new CMyCustomDraw(...);
m_Grid.SetCustomDraw(customDraw);
To understand how drawing works we will describe the drawing workflow. When WM_PAINT comes, the grid looks for implementation of the painting interface (or takes the default one) and then calls ICustomDraw::DrawLine function. This function is called with three parameters:
- parameters related to a line (bounds, placement, fonts, colors, business data object pointer, etc...)
- the second contains general information about CDC, has reference to the grid, header and other static information.
- the filter, which prevents drawing of some elements (selection, hierarchical lines, icons), etc.
CCustomDraw default implementation doesn't do the drawing. It looks for ILinePaintFormat implementation or takes the default one implemented in CLinePaintFormat class, and forwards the call to the line paint format. The default implementation of this format draws nothing, but it takes all header's columns, constructs CGridCell object with cell dimension and appearance and calls ICustomDraw::DrawCell with these parameters.
The next step is to find ICellPaintFormat default implementation. First, CCustomDraw looks for the format in CColumn. If the column does not have format, CCellPaintFormat default implementation will be taken. Then, CCustomDraw calls ICellPaintFormat::DrawCell of the found object. Finally, the cell format performs all drawing in the specified bounds with the specified appearance.
So, ICustomDraw interface is called twice:
- To draw the line
- To draw cells
ICustomDraw interface is the best point to define drawing behaviour. For example at any moment you can change foreground or background colors:
Another example can give some ideas how to merge cells and draw text in the whole line:
void CMyCustomDraw::DrawLine(Dapfor::GUI::CGridLine& line, const Dapfor::GUI::CPaintContext& paintContext, UINT paintFilter)
{
...
paintFilter &= paintFilter^(Dapfor::GUI::drawText|Dapfor::GUI::drawImage);
BaseClass::DrawLine(line, paintContext, paintFilter);
int oldMode = paintContext.GetDC().GetBkMode();
paintContext.GetDC().SetBkMode(TRANSPARENT);
CString s(_T("This text is drawn in the whole line"));
CRect rc(&line.GetPaintInfo().GetVisibleRect());
paintContext.GetDC().DrawText(s, rc, DT_CENTER|DT_END_ELLIPSIS);
paintContext.GetDC().SetBkMode(oldMode);
}
Note that this implementation can be easily put to ILinePaintFormat custom implementation