Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The Ultimate Grid Cell Types

0.00/5 (No votes)
25 Aug 2007 1  
An introduction to using built-in and custom cell types with the Ultimate Grid

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

Introduction


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).

Available Cell Types

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_DROPLISTSELECTUGCT_DROPLISTSELECTEXUGCT_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

Using Cell Types

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: 
     //****** Create the New Object and reserve an index member

     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()
{
     ...
     //Spin Button cell type

     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;    
// get the cell we want

GetCell(1,row+2,&cell);                       

// could also use cell.SetNumber()

cell.SetText("1");
                  
// tell the cell to draw and interact using the celltype at this 

// index (spin type)          

cell.SetCellType(m_nSpinIndex);                

// optional - spin buttons will be hidden until cell has focus

cell.SetCellTypeEx(UGCT_SPINBUTTONHIDEBUTTON) 

// extra info can be stored in the param member of the cell 

cell.SetParam(SPIN_TYPE1);                    

// set the cell data back to the grid

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  //  UGCT_SPINBUTTONDOWN

           {
                num--;
           }
     }
     // cell.SetNumber would work as well...

     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;
          // Change bool cell types to check box.

          if ((CUGDAODataSource*)GetDataSource(
              GetDefDataSource())->GetColType(col, &type) == UG_SUCCESS)
          {
               switch (type) {
               case 1: // boolean

                    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.

Creating Custom Cell Types

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:

//general purpose routines

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.

History

Initial CodeProject release August 2007.

Comments

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()
{
     ...
     //add the standard cell types


     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 :

//Normal CellType/CellType Ex Values - most other cell types 

//also use these values, so bits 1-8 are reserved generally reserved

#define UGCT_NORMAL 0

#define UGCT_NORMALSINGLELINE BIT0 
#define UGCT_NORMALMULTILINE BIT1
#define UGCT_NORMALELLIPSIS BIT2
#define UGCT_NORMALLABELTEXT BIT3

//Droplist CellType


#define UGCT_DROPLIST 1
//CheckBox CellType

#define UGCT_CHECKBOX 2
//Arrow CellType

#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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here