Visit the Ultimate Grid main page for an overview and configuration guide to the Ultimate Grid library.
Source code and project files for this sample are included in the Demos\Cell types directory of the sample projects download.
Contents
Cell types...
...and more cell types.
The display and interaction properties of a cell are handled through the assignment of cell type classes to individual cell objects. These cell types can be built-in types or add-ons (either your own derived cell type classes or one of a selection of additional types provided in the CellTypes directory of the source code download).
There are a number of pre-built cell types that ship with the Ultimate Grid. Built-in types are selectable through #defined
values passed to CUGCell::SetCellType
or CUGCtrl::QuickSetCellType
. Some cell types also have extended cell type #defines that can be used to modify their behavior through calls to CUGCell::QuickSetCellTypeEx
or CUGCtrl::QuickSetCellTypeEX
.
Many cell types also provide for special notification codes which are sent to the grid's virtual OnCellTypeNotify
function (e.g. the drop list type will send UGCT_DROPLISTSTART
and UGCT_DROPLISTSELECT
.
Note that most cell types will use the default CEdit
derived edit class for text editing, but that other edit controls may be selected as well.
Here is a brief overview of the major cell types that ship with the Ultimate Grid and their extended and notification codes:
Built-in types |
Built in types can be selected into the cell through the use of #defined values. |
Normal text
|
Built-in type #define: UGCT_NORMAL (the default cell type for the grid)
Extended #defines: (note that the normal cell type is the base class for all others, so these CellTypeEx attributes can be applied to most cell types that display text) UGCT_NORMALSINGLELINE<br />UGCT_NORMALMULTILINE<br />UGCT_NORMALELLIPSIS<br />UGCT_NORMALLABELTEXT
|
Drop list
|
Built-in type #define: UGCT_DROPLIST
Extended #defines:
UGCT_DROPLISTHIDEBUTTON
Notification #defines:
UGCT_DROPLISTSTART
UGCT_DROPLISTSELECT UGCT_DROPLISTSELECTEX UGCT_DROPLISTPOSTSELECT
|
Check box
|
Built-in type #define: UGCT_CHECKBOX
Extended #defines:
UGCT_CHECKBOXFLAT
UGCT_CHECKBOXCROSS
UGCT_CHECKBOX3DRECESS
UGCT_CHECKBOX3DRAISED UGCT_CHECKBOXCHECKMARK<br /><code> UGCT_CHECKBOXROUND
UGCT_CHECKBOXUSEALIGN
UGCT_CHECKBOX3DSTATE
UGCT_CHECKBOXDISABLED
Notification #defines:
UGCT_CHECKBOXSET
|
Arrow
|
Built-in type #define: UGCT_ARROW
Extended #defines:
UGCT_ARROWRIGHT
UGCT_ARROWLEFT
UGCT_ARROWDRIGHT
UGCT_ARROWDLEFT
|
Additional types |
Add-on types must be added to the grid through the CUGCtrl::AddCellType function, and set to the cell using the index returned. |
Auto font
|
Will automatically size the font of any cell so that all of the text will be visible. |
Button
|
Simulates a standard windows push button control.
Extended #defines:
UGCT_BUTTONNOFOCUS
Notification #defines:
UGCT_BUTTONCLICK
UGCT_BUTTONDOWN
UGCT_BUTTONUP
|
Auto size
|
Extends the standard cell type providing functionality to size its cell to make sure that cell's data is visible in full. It will not make columns or rows smaller, but it will enlarge them whenever needed. |
Date time picker
|
Displays a button along with a cell that can be used to activate a full featured Date-Time picker.
Notification #defines:
UGCT_CONVERTDATE
UGCT_DISPLAYMONTHCAL
|
Drop grid
|
The CUGCTDropGrid cell type was created to provide users with ability to show a popup window containing a grid, just like a drop list. By default an instance of the CDropDownCug will be created and used as the grid control within the popup window, but it can be replaced with any <code> CDropDownCug derived class through the OnCellTypeNotify notification.
Extended #defines:
UGCT_SHOWASPOPUPWND
Notification #defines:
UGCT_SHOWDROPGRID
UGCT_CLOSEDROPGRID
UGCT_SELECTEDITEM
|
Outlook header
|
Provides gradient drawing of cells for an 'Outlook' style headers. |
Ellipsis
|
Draws the cells value as text. Plus adds a ellipsis button on the right hand side of the cell. This button when clicked will fire a notification.
Extended #defines:
UGCT_ELLIPSISHIDEBUTTON
Notification #defines:
UGCT_ELLIPSISBUTTONCLICK
|
Expand
|
Expanding/collapsing cell type. This cell type displays a button which, when pressed, will expand or collapse a group of rows under it, up until the next cell of the same type. |
Labeled
|
Can display a label as well as cell text in the same cell. |
Marquee
|
Displays text in a horizontally scrolling 'marquee' style. |
Multi font
|
Can display text using multiple fonts in the same cell. |
Note
|
A note type cell will display an indicator when text is set to the label - this text will display when the mouse is over the cell in a multi-line, note window (note - this is in addition to any text displayed as a tooltip in the OnHint override). |
Pie chart
|
Displays a pie chart in a cell.
Extended #defines:
UGTC_PIECHARTSEPARATE
UGTC_PIECHARTPERCENT
UGTC_PIECHARTDATA
UGTC_PIECHARTDATALEFT
UGTC_PIECHARTDATARIGHT
|
Progress / Advanced progress
|
Progress bar cell types that can display different types of bars.
For the CUGProgress type the UGCT_PROGRESSUSELABEL extended flag is available.
For the CUGAdvProgressType :
Extended #defines:
UGCT_PROGRESS_NORMAL
UGCT_PROGRESS_ALERT
UGCT_PROGRESS_RAINBOW
UGCT_PROGRESS_TOP
UGCT_PROGRESS_LEFT
UGCT_PROGRESS_RIGHT
UGCT_PROGRESS_BOTTOM
|
Radio
|
Can display a group of radio buttons.
Notification #define:
UGCT_RADIOBUTTONSELECTED
|
Slider
|
Displays a slider like control in a cell.
Notification #define:
UGCT_SLIDER_MOVED
|
Sort arrow
|
Displays an up or down sort arrow in a (typically) header cell in response to a user click.
Notification #defines:
UGCT_SORTARROWUP
UGCT_SORTARROWDOWN
|
Spin button
|
Allows spin button control over cell values.
Extended #define:
UGCT_SPINBUTTONHIDEBUTTON
Notification #defines:
UGCT_SPINBUTTONUP
UGCT_SPINBUTTONDOWN
|
The code that follows is typical of code you would add to your derived CUGCtrl
class to create and use a simple cell type. We provide a MyCug
class skeleton that you can copy to your project to get started - we'll use that class here.
For each non-built-in type you'll need to add the CPP file for that type to your project. Cell type code files live in the CellTypes directory. Include the header file for that type and create a member variable and index in your MyCug.h
header:
#include "ugctrl.h"
#include "resource.h"
#include "UGCTSpin.h" // include header for spin type
class MyCug: public CUGCtrl
{
public:
CUGSpinButtonType m_spin;
int m_nSpinIndex
Next, the new cell type needs to be added to the grid's array of available types. This is typically done along with other initialization in the OnSetup
member of the derived grid control:
void MyCug::OnSetup()
{
...
m_nSpinIndex = AddCellType(&m_spin);
...
Next, assuming we've set some rows and columns to the grid, we can add code either in OnSetup
or OnReset
to set the spin type as the controlling type for one or more cells. In the following code (taken from the Cell Types demo in the Demos directory) the param
member of the cell is also set with an app defined constant that serves to differentiate a number of cells that are using this cell type in different ways (displaying text or numeric values, e.g.):
CUGCell cell;
GetCell(1,row+2,&cell);
cell.SetText("1");
cell.SetCellType(m_nSpinIndex);
cell.SetCellTypeEx(UGCT_SPINBUTTONHIDEBUTTON)
cell.SetParam(SPIN_TYPE1);
SetCell(1,row+2,&cell);
So, at this point we have a cell controlled by the CUGSpinButtonType
. When the user interacts with the up or down spin buttons, we'll receive notifications in our derived grid controls OnCellTypeNotify
method:
int CCellTypeDemoGrid::OnCellTypeNotify(long ID,int col,long row,long msg,
long param)
{
CUGCell cell;
long num;
GetCell(col,row,&cell);
cell.GetNumber(&num);
if(ID == m_nSpinIndex)
{
if(msg == UGCT_SPINBUTTONUP)
{
num++;
}
else
{
num--;
}
}
CString str;
str.Format("%ld",num);
cell.SetText(str);
SetCell(col,row,&cell);
}
Et voila, the spin button can modify the cell data.
Cell Types and Virtual Loading
Cell types can also be used with data that is loaded from a custom datasource, with some limitations based on how much data can persist - typically, with a database oriented datasource like DAO or ODBC, the datasource's GetCell
function retrieves only the text/number associated with that datum, so things like the param
data of the cell cannot persist, but you can still vector the grid controls OnGetCell
notification to use custom types with a cell.
This snippet from the MyAccess datasource sample shows how a derived grid might override OnGetCell
to set a boolean cell to use a checkbox type:
void CUGAccessCtrl::OnGetCell(int col,long row,CUGCell *cell)
{
if (row < 0 )
cell->SetFont(&m_thFont);
if(-1 < row)
{
int type = 0;
if ((CUGDAODataSource*)GetDataSource(
GetDefDataSource())->GetColType(col, &type) == UG_SUCCESS)
{
switch (type) {
case 1:
cell->SetCellType(UGCT_CHECKBOX);
cell->SetCellTypeEx(UGCT_CHECKBOX3DRAISED) ;
break;
...
A spin type could work as well for numeric data, and might be handy if restricting input to certain stepped increments.
Again, depending on the nature of the datasource, some cell types will be problematic to use. Consider the drop list, note, and label types, which rely on the label text data of the cell - a db type datasource will typically persist only the text/number cell attribute back to the database, so values set with cell.SetLabelText
will be lost.
The CUGCellType
is a CObject
derived class that doubles as the default cell type and the base class for all grid cell types. Note that while some cell types — such as the note or calendar types — may have the capability of displaying a window in response to a user action, they are not CWnd
derivatives. The CUGGrid
member of the CUGCtrl
class is the active CWnd
for the control, and has the responsibility of relaying mouse, key, and paint messages to the cell type.
Here is a subset of the virtual message based methods most likely to be overridden in a new CUGCellType
derived class:
virtual BOOL OnLClicked(int col,long row,int updn,RECT *rect,POINT *point);
virtual BOOL OnRClicked(int col,long row,int updn,RECT *rect,POINT *point);
virtual BOOL OnDClicked(int col,long row,RECT *rect,POINT *point);
virtual BOOL OnKeyDown(int col,long row,UINT *vcKey);
virtual BOOL OnKeyUp(int col,long row,UINT *vcKey);
virtual BOOL OnCharDown(int col,long row,UINT *vcKey);
virtual BOOL OnMouseMove(int col,long row,POINT *point,UINT nFlags);
virtual void OnDraw(CDC *dc,RECT *rect,int col,long row,CUGCell *cell,int
selected,int current);
virtual BOOL OnDrawFocusRect(CDC *dc,RECT *rect,int col,int row);
And there are also general purpose overrides for common functionality:
virtual int DrawBitmap(CDC *dc,CBitmap * bitmap,RECT *rect,COLORREF backcolor);
virtual void DrawBorder(CDC *dc,RECT *rect,RECT *rectout,CUGCell * cell);
virtual void DrawText(CDC *dc,RECT *rect,int offset,int col,long row,
CUGCell *cell, int selected,int current);
virtual void DrawBackground(CDC *dc,RECT *rect,COLORREF backcolor,
int row = -1, int col = -1, CUGCell * cell = NULL, bool current = false,
bool selected = false);
virtual int GetCellOverlapInfo(CDC* dc,int col,long row,
int *overlapCol,CUGCell *cell);
bool DrawThemedText(HDC dc, int left, int top, RECT* rect, LPCTSTR string,
int stringLen, DWORD textFormat, UGXPCellType cellType, UGXPThemeState
state);
See the documentation and Include\ugceltyp.h file for more on the available overrides.
Probably the simplest cell type to create would involve only an override to OnDraw
, and draw a colored circle.
You may or may not need to create a new cell type, but it can be an excellent way to add custom functionality to the grid. In many cases, you may find it's enough to modify an existing type to get the particular drawing or interactive quality that is required.
Initial CodeProject release August 2007.
The add-on cell types listed above have evolved over several years/releases but remained as add-on types. One of the original goals of the Ultimate Grid design was maintaining a small footprint with respect to code size, and incorporating cell types on an 'as needed' basis was part of that philosophy.
Some users, notably those using the static lib build of the grid, might like to modify the code base to incorporate one or more add-on cell types into the control as built-in types. This can be done by modifying the CUGCtrl
class to accommodate the types in the same way as it does the current built in types. You'll find the code that calls AddCellType
for the built-in types in the constructor of CUGCtrl
:
CUGCtrl::CUGCtrl()
{
...
AddCellType(&m_normalCellType);
AddCellType(&m_dropListType);
AddCellType(&m_checkBoxType);
AddCellType(&m_arrowType);
...
The indices returned from these calls correspond to the #defines declared in Include\UGDefine.h :
#define UGCT_NORMAL 0
#define UGCT_NORMALSINGLELINE BIT0
#define UGCT_NORMALMULTILINE BIT1
#define UGCT_NORMALELLIPSIS BIT2
#define UGCT_NORMALLABELTEXT BIT3
#define UGCT_DROPLIST 1
#define UGCT_CHECKBOX 2
#define UGCT_ARROW 3
So, additional types could be added to CUGCtrl.h as member objects, added to the grid's available built-in types in the destructor, and the corresponding additional built-in type #defines
added to ugdefine.h to add more built in types.