Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Objective-C

Simple Grid - A Win32 message based grid control

4.92/5 (69 votes)
8 Mar 2016CPOL16 min read 256.4K   18.1K  
A simple to use grid control for Windows SDK C applications.

Figure1

Figure1 Original Baby Grid Demo

Figure2

Figure2 New Columns

Table of Contents

Introduction

Periodically a C programmer will ask around the web for a grid that can be used in a non-MFC project. Usually (s)he will be referred to one or both of two published projects. The first from back in 2002 is Win32 Grid Control with Low Overhead (BABYGRID) [^] by David Hillard. The second is my own adaptation of the List view which I initially published in 2009 Win32 SDK Data Grid View Made Easy [^] which better fit my needs at the time than Mr. Hillard's grid.

Now let's face it, it's a sad state of affairs if that is all one has to choose from for use in a Win32/64 C based application. It's been a while since I published anything new and I was ready for a challenge and so decided it was time to tackle BABYGRID by fixing some known deficiencies and adding a few features. It turned out to be somewhat more work than I anticipated but take it all together it was an enjoyable hobby project, somewhere along the way I even began to feel like a coder again!

Background

I first encountered BABYGRID in 2004 or 2005 and used it in an Engineering Automated Test application I wrote for the QA department where I worked. The grid looked and behaved reasonably well for that application but had some limitations and it was difficult to modify the grid as it had been written. Meanwhile the author realized this and, having gained some experience in writing UI elements, wrote a second, better grid, ZEEGrid which he sold for a reasonable price from his web site for a while. Eventually ZEEGrid disappeared from the web along with the author's website.  BREAKING NEWS! ZEEGrid is back and is being made available again by the author, David Hillard, at no cost.  You can get ZeeGrid from http://www.kycsepp.com, head on over and check it out.

Here is an excerpt from the legacy comments associated with the BABYGRID article on Code Guru. The new version of BABYGRID he mentions here was released as ZEEGrid.

New version of BABYGRID coming soon! Posted by DHillard on 08/11/2004 01:41pm

I have been working on a new version of this grid for several months now.

The new version will be implemented as a DLL with mostly the same programming interface (SendMessage) as this grid. This will allow for easier access to programmers using other languages besides C/C++.

The new version is being developed from the ground up, using a grid engine for direct access to the grid cell contents. This replaces the binary lookup used in this grid. It also draws and displays MUCH faster than BABYGRID using a backbuffer the create the grid display in memory, then bitblting it to the screen.

It also has these features:

  • REAL incell editing (using an edit control)
  • Merging cells of rows with identical data
  • Column reordering
  • Search Grid or Search Column
  • Sort by Column
  • 127 Color Pallette
  • 127 Font Pallette
  • Protected cells
  • Export grid contents to CSV file
  • Print grid
  • 9 point cell justification
  • Cell left and right indents
  • Individual cell background, foreground colors
  • Column resizing/hiding
  • Fixed columns
  • No limit on number of columns (other than available memory)
  • No limit on rows (also... available memory)
  • 127 icon pallette, Can combine cell text with graphic (icon)

(Essentially fixing all the annoying things with BABYGRID).

Sounds pretty good doesn't it? However duplicating Mr. Hillard's efforts would have me biting off more than I could chew at this time and so I focused instead on the following modest improvements to the original grid concept:

  • Organize the source into an easily maintainable and understandable format.
  • Document and provide macros for all messages to make it easier to use.
  • Grid instances created, stored, and destroyed in the manner common to Win32 applications, thus no artificial limits on the number of grids one can create.
  • Rewrite portions of the grid to support Unicode.
  • Employ optional double buffering (Simple Grid is double buffered by default).
  • Replace the storage list box + binary lookup mechanism with a list of vectors for fast access to cell data.
  • Provide several different types of columns for editing and displaying data, namely: text, combobox, link, image, button, and checkbox.
  • Unlimited rows, 475255 columns (memory permitting of course.)
  • Column resizing/hiding and cell protection were preserved from the original BABYGRID code
  • In cell justification options: Left, Right, or General (if General set then numeric content is automatically Right justified while alpha content is automatically left justified.)

Using Simple Grid

To begin, include the SimpleGrid control's header file in the project:

#include "SimpleGrid.h"

The SimpleGrid control is a message based, custom control, and as such must be initialized before use. One way to handle this is to call the initializer in the WinMain() method of the application just after the call to InitCommonControlsEx().

C++
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
           LPSTR lpszCmdLine, int nCmdShow)
{
    INITCOMMONCONTROLSEX icc;
    WNDCLASSEX wcx;

    ghInstance = hInstance;

    /* Initialize common controls. Also needed for MANIFEST's */

    icc.dwSize = sizeof(icc);
    icc.dwICC = ICC_WIN95_CLASSES/*|ICC_COOL_CLASSES|ICC_DATE_CLASSES|
                   ICC_PAGESCROLLER_CLASS|ICC_USEREX_CLASSES*/;
    InitCommonControlsEx(&icc);

   InitSimpleGrid(hInstance);

To make things simple though, I combined this step in the control's pseudo constructor. It is called only once, the first time a new SimpleGrid control is instantiated.

C++
HWND New_SimpleGrid(HWND hParent, DWORD dwID)
{
    static ATOM aControl = 0;
    static HWND hControl;

    HINSTANCE hinst;

    //Get hinstance if this code is compiled into and called from a dll 
    // as well as if it were compiled into the executable.  (XP and later)
    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
     (LPCTSTR)New_SimpleGrid, &hinst);

    //Only need to register the property grid once
    if (!aControl)
        aControl = InitSimpleGrid(hinst);

    hControl = CreateWindowEx(0, WC_SIMPLEGRID, _T(""), WS_CHILD | 
      WS_TABSTOP, 0, 0, 0, 0, hParent, (HMENU)dwID, hinst, NULL);

    return hControl;
}

The demo code provides several examples of the different ways data can be entered into the grid for display and manipulation. The following snippet shows how to load the grid with columns of various types and then add and set row data accordingly.

C++
void LoadGrid4(HWND hGrid)
{
    //
    // Create image list
    //
    INT iImages[] = { IDR_BMP_OFF,
                      IDR_BMP_ON};

    HIMAGELIST hImageList = ImageList_Create(32, 32, ILC_COLOR32, NELEMS(iImages), 1);
    for(int i = 0; i < NELEMS(iImages); ++i){
        HBITMAP hbmp = (HBITMAP)LoadImage(ghInstance, MAKEINTRESOURCE(iImages[i]), IMAGE_BITMAP, 32, 32,
               LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
        ImageList_Add(hImageList, hbmp, NULL);
    }

    // Set Row height to accommodate the graphics
    SimpleGrid_SetRowHeight(hGrid,34);

    //
    // Create Columns
    //

    // Column type
    // Column header text
    // Optional data (ex: combobox choices)
    SGCOLUMN lpColumns[] = {
        GCT_COMBO,  _T("Combo Column"),  
          _T("Ford\0Chevy\0Zaparozhets\0Volkswagen\0Toyota\0Honda\0Citroen\0Fiat\0Volvo\0"),
        GCT_BUTTON, _T("Button Column"), NULL, 
        GCT_IMAGE, _T("Image Column"),  hImageList,
        GCT_LINK, _T("Link Column"), NULL
    };

    // Add the columns
    for(int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
    {
        SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
        SimpleGrid_SetColWidth(hGrid, m, 100);
    }

    //
    // Add some rows
    //
    for(int i = 0; i < 2; ++i) 
        SimpleGrid_AddRow(hGrid, _T("")); //Don't care about row header text

    //
    // Set cells to data
    //

    // Column number
    // Row number
    // Item (cell) value
    SGITEM lpItems[] = {
        // Combo column
        0, 0, (LPARAM)_T("Zaparozhets"),
        0, 1, (LPARAM)_T("Citroen"),

        // Button column
        1, 0, (LPARAM)_T("#1 On"),
        1, 1, (LPARAM)_T("#2 On"),

        // Image column
        2, 0, (LPARAM) 0,
        2, 1, (LPARAM) 0,

        // Link column
        3, 0, (LPARAM)_T("The Code Project\0http:\\\\www.codeproject.com\0"),
        3, 1, (LPARAM)_T("The Daily WTF: Curious Perversions in " 
          "Information Technology\0http:\\\\www.thedailywtf.com\0"),
    };

    for(int i = 0; i < NELEMS(lpItems); ++i)
    {
        SimpleGrid_SetItemData(hGrid, &lpItems[i]);
    }

}

Note: Columns of type GCT_COMBO store a list of choices (a double null terminated list of strings) that is shared by each cell in the column. Likewise columns of type GCT_IMAGE store a handle to an image list shared by each cell in that column. Items in columns of type GCT_LINK however, take a two item list comprised of link text and URL (also double null terminated list of strings.)

What follows is a programming reference for the SimpleGrid control class.

Public data structures

SGCOLUMN

The SGCOLUMN structure specifies or receives attributes for a SimpleGrid column.

C++
typedef struct tagSGCOLUMN {
    DWORD dwType;
    LPTSTR lpszHeader;
    LPVOID pOptional;
} SGCOLUMN, *LPSGCOLUMN;

Members

  • dwType: The column type identifier. The value may be one of the following:
    • GCT_EDIT - Column type: Edit
    • GCT_COMBO - Column type: Dropdown list
    • GCT_BUTTON - Column type: Button
    • GCT_CHECK - Column type: Check box
    • GCT_LINK - Column type: Link
    • GCT_IMAGE - Column type: Image
  • lpszHeader: The column header text.
  • pOptional: The column optional parameter. The data type depends on the item type as follows:
    • GCT_EDIT, GCT_BUTTON, GCT_CHECK and GCT_LINK - NULL (not used).
    • GCT_COMBO - A double null terminated list of strings (combo items) shared by each cell in column.
    • GCT_IMAGE - The handle to an image list shared by each cell in column.

SGITEM

The SGITEM structure specifies or receives attributes for a SimpleGrid item or cell.

C++
typedef struct tagSGITEM{
    int col;
    int row;
    LPARAM lpCurValue;
} SGITEM, *LPSGITEM;

Members

  • col: The column index of the item.
  • row: The row index of the item.
  • lpCurValue: The item value. The data type depends on the item type as follows:
    • GCT_EDIT, GCT_BUTTON and GCT_COMBO - item text displayed in the cell (or button text.)
    • GCT_CHECK - A boolean TRUE or FALSE.
    • GCT_IMAGE - An integer, the index of the image displayed.

Messages and Macros

Configure the control to do what you want using Windows messages. To make this easy and as a way of documenting the messages, I created macros for each message. If you prefer to call SendMessage() or PostMessage() explicitly, please refer to the macro defs in the header for usage.

Note: If a message returns SG_ERROR use GetLastError() to discover details of the error.

SimpleGrid_AddColumn

Add a column to the grid.

C++
INT SimpleGrid_AddColumn(
     HWND hGrid
     LPSGCOLUMN lpColumn
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
lpColumn
     Pointer to a SimpleGrid column.

Return Values
The zero-based index of the added column if successful, otherwise SG_ERROR.
*/

SimpleGrid_AddRow

Add a column to the grid.

C++
INT SimpleGrid_AddRow(
     HWND hGrid
     LPTSTR lpszHeader
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
lpszHeader
     The row header text string.

Return Values
The zero-based index of the added row if successful, otherwise SG_ERROR
*/

SimpleGrid_AddRowData

Add a row of data to the grid. (This combines SimpleGrid_AddRow(), SimpleGrid_SetItemData(), and SimpleGrid_SetItemTextAlignment() into one convenient macro.

C++
VOID SimpleGrid_AddRowData(
     HWND hGrid
     LPTSTR szHeader
     DWORD dwAlignment
     LPARAM aryData
     INT count
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
szHeader
     The row header text string.
dwAlignment
     The desired text alignment flag: GSA_LEFT, GSA_GENERAL,
     or GSA_RIGHT.
aryData
     An array of values.
count
     The number of elements in aryData.

Return Values
The return value is not meaningful.
*/

SimpleGrid_Enable

Enables or disables mouse and keyboard input to the specified grid.

C++
BOOL SimpleGrid_Enable(
     HWND hGrid
     BOOL fEnable
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fEnable
     TRUE to allow input, otherwise FALSE.
     
Return Values
TRUE If the window was previously disabled, otherwise false.
*/

SimpleGrid_EnableEdit

Enable or disable editing in the grid.

C++
VOID SimpleGrid_EnableEdit(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
     TRUE to enable editing in grid, FALSE to disable.

Return Values
The return value is not meaningful.
*/

SimpleGrid_ExtendLastColumn

Set the grid to extend the last column to the end of the client area.

C++
VOID SimpleGrid_ExtendLastColumn(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
     TRUE to extend the last column, otherwise FALSE.

Return Values
The return value is not meaningful.
*/

SimpleGrid_GetColCount

Get the number of columns in grid.

C++
INT SimpleGrid_GetColCount(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The column count.
*/

SimpleGrid_GetColumnHeaderText

Get the text displayed in the column header.

C++
INT SimpleGrid_GetColumnHeaderText(
     HWND hGrid
     INT iCol
     LPTSTR lpszBuf
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The number of the column.
lpszBuf
     A buffer to receive the column header text.

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_GetColumnHeaderTextLen

Retrieve the length of a string of column header text.

C++
INT SimpleGrid_GetColumnHeaderTextLen(
     HWND hGrid
     INT iCol
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The number of the column.

Return Values
The length of the string, in characters, excluding the terminating null character  if 
successfull, othewise SG_ERROR
*/

SimpleGrid_GetColumnType

Get the type of data represented in this cell.

C++
DWORD SimpleGrid_GetColumnType(
     HWND hGrid
     INT iCol
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The number of the column.

Return Values
One of the following column types: GCT_EDIT, GCT_COMBO, 
GCT_BUTTON, GCT_CHECK, GCT_LINK, or GCT_IMAGE, 
otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_GetColWidth

Get the width (in pixels) of a column.

C++
INT SimpleGrid_GetColWidth(
     HWND hGrid
     INT iCol
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The number of the column.

Return Values
The width of the desired column (in pixels), otherwise SG_ERROR if desired column 
is out of bounds.
*/

SimpleGrid_GetCursorCol

Get the column of the cursor.

C++
INT SimpleGrid_GetCursorCol(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The number of the column the cursor currently occupies.
*/

SimpleGrid_GetCursorRow

Get the column of the cursor.

C++
INT SimpleGrid_GetCursorRow(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The number of the row the cursor currently occupies.
*/

SimpleGrid_GetHeaderRowHeight

Get the height of the header row.

C++
INT SimpleGrid_GetHeaderRowHeight(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The height (in pixels) of the header row.
*/

SimpleGrid_GetImageColumnImageList

Get the image list associated with an image column.

C++
HIMAGE SimpleGrid_GetImageColumnImageList(
     HWND hGrid
     INT iCol
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The number of the column.

Return Values
The image list associated with the column if successful, otherwise NULL.
*/

SimpleGrid_GetItemData

Get the content of an individual item (cell).

C++
INT SimpleGrid_GetItemData(
     HWND hGrid
     LPSGIETEM pItem
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
pItem
     A pointer to a SGIETEM struct.

Return Values
ERROR_SUCCESS, otherwise SG_ERROR if desired cell is out of bounds
*/

SimpleGrid_GetItemText

Get the text of an individual item.

Note: If the item belongs to a column of type GCT_EDIT, GCT_COMBO, or GCT_BUTTON, the buffer will be filled with the item text. If the item belongs to a column of type GCT_LINK the buffer will be filled with a contiguous array buffer consisting of an array of two strings: display text and link URL.

C++
VOID SimpleGrid_GetItemText(
     HWND hGrid
     INT iCol
     INT iRow
     LPTSTR pszText
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.
pszText
     Pointer to a buffer to recieve text.

Return Values
The return value is not meaningful.
*/

SimpleGrid_GetItemDataLen

Retrieve the length of data associated with a grid item.

Note: If the item belongs to a column of type GCT_EDIT, GCT_COMBO, or GCT_BUTTON the returned value is the length of the item text. If the item belongs to a column of type GCT_LINK the returned value is the length of the contiguous array buffer consisting of an array of two strings: display text and link URL. If the item belongs to a column of type GCT_CHECK or GCT_IMAGE then 0 is returned since this data is not a string.

C++
INT SimpleGrid_GetItemDataLen(
     HWND hGrid
     INT iCol
     INT iRow
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.

Return Values
The length of the data, in characters, excluding the terminating null character 
if successfull, othewise SG_ERROR.
*/

SimpleGrid_GetItemProtection

Get the item's (cell's) protection flag.

C++
INT SimpleGrid_GetItemProtection(
     HWND hGrid
     INT iCol
     INT iRow
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.

Return Values
SG_ERROR if desired cell is out of bounds, TRUE if it is protected, otherwise FALSE.
*/

SimpleGrid_GetRowCount

Get the number of rows in grid.

C++
INT SimpleGrid_GetRowCount(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The row count.
*/

SimpleGrid_GetRowHeaderText

Get the text displayed in the row header.

C++
INT SimpleGrid_GetRowHeaderText(
     HWND hGrid
     INT iRow
     LPTSTR lpszBuf
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iRow
     The number of the row.
lpszBuf
     A buffer to receive the row header text.

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_GetRowHeaderTextLen

Retrieve the length of a string of row header text.

C++
INT SimpleGrid_GetRowHeaderTextLen(
     HWND hGrid
     INT iRow
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iRow
     The number of the row.

Return Values
The length of the string, in characters, excluding the terminating null character  if 
successfull, othewise SG_ERROR
*/

SimpleGrid_GetRowHeight

Get the height (in pixels) of the rows.

C++
INT SimpleGrid_GetRowHeight(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The height (in pixels) of the rows
*/

SimpleGrid_GetTitle

Get the title text of the grid.

C++
INT SimpleGrid_GetTitle(
     HWND hGrid
     INT lpch
     LPTSTR cchMax
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
lpch
     The address of a character buffer for text.
cchMax
     The maximum number of characters to copy.
     
Return Values
If the function succeeds, the return value is the length, in characters, 
of the copied string, not including the terminating null character. If the 
window has no title bar or text, if the title bar is empty, or if the window 
or control handle is invalid, the return value is zero.
*/

SimpleGrid_GetTitleLength

Get the length, in characters, of the grid's title bar text.

C++
INT SimpleGrid_GetTitleLength(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
If the function succeeds, the return value is the length, 
in characters, of the text otherwise 0. 
*/

SimpleGrid_RefreshGrid

Cause the grid to redraw itself.

C++
VOID SimpleGrid_RefreshGrid(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The return value is not meaningful.
*/

SimpleGrid_ResetContent

Remove all data, rows, and columns from the grid.

C++
VOID SimpleGrid_ResetContent(
     HWND hGrid
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SelectCell

Select a cell and set the focus for editing it's contents.

C++
INT SimpleGrid_SelectCell(
     HWND hGrid
     INT iCol
     INT iRow
     INT fOverwritemode
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The col index of the cell.
iRow
     The row index of the cell.
fOverwritemode
     TRUE to overwrite cell contents, FALSE to edit the current contents of the cell.

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds
*/

SimpleGrid_SetAllowColResize

Configure column resizing.

C++
VOID SimpleGrid_SetAllowColResize(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
     fSet TRUE for resizeable columns, FALSE locks in column widths.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetColAutoWidth

Configure grid columns to auto adjust to fit contents.

Note: This should be set before adding data to the grid.

C++
VOID SimpleGrid_SetColAutoWidth(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
     fSet TRUE to autosize columns to updated content, 
     otherwise FALSE.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetColsNumbered

Sets what is displayed in the Column headers.

C++
VOID SimpleGrid_SetColsNumbered(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
    TRUE to display Column hexavigesimal digits, FALSE to display header text.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetColumnHeaderText

Set the text to be displayed in the column header.

C++
INT SimpleGrid_SetColumnHeaderText(
     HWND hGrid
     INT iCol
     LPTSTR lpszTex
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The index of the column.
lpszTex
     The text string to display.
     
Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_SetColWidth

Set the width (in pixels) of a given column.

C++
INT SimpleGrid_SetColWidth(
     HWND hGrid
     INT iCol
     INT nWidth
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The index of the column.
nWidth
     The desired width (in pixels) of the column.
     
Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired column is out of bounds.
*/

SimpleGrid_SetCursorPos

Set the cursor position (or currently selected cell) in the grid.

C++
INT SimpleGrid_SetCursorPos(
     HWND hGrid
     INT iCol
     INT iRow
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The col index of the cell.
iRow
     The row index of the cell.
     
Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_SetDoubleBuffer

Set Double buffer to reduce flicker in a grid with many columns.

Note: By default SimpleGrid uses double buffering.

C++
VOID SimpleGrid_SetDoubleBuffer(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
    fSet TRUE to use double buffering, FALSE turns double buffering off.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetEllipsis

Set the display of text in cell.

C++
VOID SimpleGrid_SetEllipsis(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
    TRUE to draw ellipsis, FALSE to truncate text in short cell.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetGridLineColor

Sets the color of the gridlines.

C++
VOID SimpleGrid_SetGridLineColor(
     HWND hGrid
     COLORREF clrGrdLine
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
clrGrdLine
    A COLORREF value. 

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetHeaderRowHeight

Set the height (in pixels) of the header row.

C++
VOID SimpleGrid_SetHeaderRowHeight(
     HWND hGrid
     INT iHeight
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iHeight
    The desired height (in pixels) of the header row. 

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetHeadingFont

Set the font used in the grid headers.

C++
VOID SimpleGrid_SetHeadingFont(
     HWND hGrid
     HFONT hFont
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
hFont
    The handle to a font. 

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetHilightColor

Sets the background color of highlighted cells.

C++
VOID SimpleGrid_SetHilightColor(
     HWND hGrid
     COLORREF clrHilt
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
clrHilt
    A COLORREF value. 

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetHilightTextColor

Sets the text color of highlighted cells.

C++
VOID SimpleGrid_SetHilightTextColor(
     HWND hGrid
     COLORREF clrHlText
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
clrHlText
    A COLORREF value.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetImageColumnImageList

Set the image list associated with an image column.

C++
HIMAGELIST SimpleGrid_SetImageColumnImageList(
     HWND hGrid
     INT icol
     HIMAGELIST himl
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
icol
    The index of a column of type GCT_IMAGE. 
himl
    The handle to the image list. 

Return Values
The previous image list associated with the column if successful, otherwise NULL.
*/

SimpleGrid_SetItemData

Set the content of an individual cell.

C++
INT SimpleGrid_SetItemData(
     HWND hGrid
     LPSGITEM pItem
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
pItem
    A pointer to a SGIETEM struct. 

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_SetItemText

Set the text of an individual item (cell).

Note: If the item belongs to a column of type GCT_EDIT, GCT_COMBO, or GCT_BUTTON the string should contain item text. If the item belongs to a column of type GCT_LINK the the string should be a contiguous array buffer (or double null terminated string) consisting of an array of two strings: display text and link URL.

C++
VOID SimpleGrid_SetItemText(
     HWND hGrid
     INT iCol
     INT iRow
     LPTSTR pszText
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.
pszText
     The text string.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetItemTextAlignment

Set text alignment of an item to left, general, or right.

Note: Setting the alignment to GSA_GENERAL (default) causes the grid to align text automatically based on content. Numeric data is right aligned while all other text is left aligned. Alignments only apply to columns of type GCT_EDIT.

C++
INT SimpleGrid_SetItemTextAlignment(
     HWND hGrid
     LPSGIETEM pItem
     DWORD dwAlign
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
pItem
     A pointer to a SGIETEM struct.
dwAlign
     One of the following alignments: GSA_LEFT, GSA_GENERAL, or GSA_RIGHT.

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds
*/

SimpleGrid_SetItemTextAlignmentEx

Set text alignment of an item to Left, general, or right.

Note: Setting the alignment to GSA_GENERAL (default) causes the grid to align text automatically based on content. Numeric data is right aligned while all other text is left aligned. Alignments only apply to columns of type GCT_EDIT.

C++
VOID SimpleGrid_SetItemTextAlignmentEx(
     HWND hGrid
     INT iCol
     INT iRow
     DWORD dwAlign
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.
dwAlign
     One of the following alignments: GSA_LEFT, GSA_GENERAL, or GSA_RIGHT.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetItemProtection

Set protection status of an individual cell.

C++
VOID SimpleGrid_SetItemProtection(
     HWND hGrid
     LPSGIETEM pItem
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
pItem
     A pointer to a SGIETEM struct.
fSet
     TRUE to protect cell FALSE to allow changes.

Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds
*/

SimpleGrid_SetItemProtectionEx

Set protection status of an individual cell.

C++
VOID SimpleGrid_SetItemProtectionEx(
     HWND hGrid
     INT iCol
     INT iRow
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iCol
     The column index of the item.
iRow
     The row index of the item.
fSet
     TRUE to protect cell FALSE to allow changes.

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetProtectColor

Sets the background color of protected cells.

C++
VOID SimpleGrid_SetProtectColor(
     HWND hGrid
     COLORREF clrProtect
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
clrProtect
     A COLORREF value. 

Return Values
The return value is not meaningful.
*/

SimpleGrid_SetRowHeaderText

Set the text to be displayed in the column header.

C++
INT SimpleGrid_SetRowHeaderText(
     HWND hGrid
     INT iRow
     LPTSTR lpszTex
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iRow
     The index of the row.
lpszTex
     The text string to display.
     
Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_SetRowHeaderWidth

Set the width (in pixels) of the row header column.

C++
INT SimpleGrid_SetRowHeaderWidth(
     HWND hGrid
     INT nWidth
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
nWidth
     The desired width (in pixels) of the row headers.
     
Return Values
ERROR_SUCCESS otherwise SG_ERROR if desired cell is out of bounds.
*/

SimpleGrid_SetRowHeight

Set the height (in pixels) of the rows.

C++
VOID SimpleGrid_SetRowHeight(
     HWND hGrid
     INT iHeight
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iHeight
     The desired height (in pixels) of the rows.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_SetRowsNumbered

Set whether the selected row will be highlighted.

C++
VOID SimpleGrid_SetRowsNumbered(
     HWND hGrid
     BOOL fSet
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fSet
     TRUE to display row numbers, FALSE to display header text.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_SetSelectionMode

Set whether and how the selected row will be highlighted.

C++
VOID SimpleGrid_SetSelectionMode(
     HWND hGrid
     INT iMode
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iMode
     iMode One of the following selection mode options: GSO_ROWHEADER, GSO_CELL, or GSO_FULLROW.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_SetTitle

Set the text of the grid title.

C++
BOOL SimpleGrid_SetTitle(
     HWND hGrid
     LPTSTR lpsz
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
lpsz
     The title text.
     
Return Values
TRUE if successful, otherwise FALSE.
*/

SimpleGrid_SetTitleFont

Set the font used to display the grid title.

C++
VOID SimpleGrid_SetTitleFont(
     HWND hGrid
     HFONT hFont
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
hFont
     The handle to a font.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_SetTitleHeight

Set the height of the grid title.

C++
VOID SimpleGrid_SetTitleHeight(
     HWND hGrid
     INT iHeight
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
iHeight
     The desired height (in pixels) of the title text.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_ShowIntegralRows

Set how the grid displays the top and bottom visible rows.

C++
VOID SimpleGrid_ShowIntegralRows(
     HWND hGrid
     BOOL fShow
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
fShow
     TRUE to display bottom visible row at integral height, FALSE allows the display of 
     a partial row.
     
Return Values
The return value is not meaningful.
*/

SimpleGrid_InsertRow

Add a row to the grid at a given position.

C++
VOID SimpleGrid_InsertRow(
     HWND hGrid
     INT position
     LPTSTR lpszHeader 
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
position
     The position to insert row (0 = begin, GetRowCount() = end).
lpszHeader
     The row header text string
     
Return Values
The zero-based index of the inserted row if successful, otherwise SG_ERROR.
*/

SimpleGrid_DeleteRow

Add a row to the grid at a given position.

C++
VOID SimpleGrid_DeleteRow(
     HWND hGrid
     INT position
     );
/*Parameters
hGrid
     Handle to the SimpleGrid control.
position
     The position of the row to delete (0 = begin, GetRowCount() = end).
     
Return Values
The total number of rows if successful, otherwise SG_ERROR.
*/

Notifications

SimpleGrid provides notifications via WM_NOTIFY. The lParam parameter of these notification messages points to one of several notification data structures. In order to simplify documentation the structure and associated messages are grouped together here.

NMGRID

The NMGRID structure contains information for most SimpleGrid notifications.

C++
typedef struct tagNMGRID {
    NMHDR hdr;
    INT col;
    INT row;
    DWORD dwType;
} NMGRID, *LPNMGRID;

/*Members
hdr
     Specifies an NMHDR structure. The code member of the NMHDR structure identifies 
     the notification being sent.
col
     The column index of the item.
row
     The row index of the item.
dwType
     Column type (thus cell type) identifier.

Remarks
     The address of this structure is specified as the lParam parameter of the 
     WM_NOTIFY message for most SimpleGrid control notification messages.*/

SGN_SELCHANGE

The SGN_SELCHANGE notification message notifies a simple grid control's parent window that an edit operation was initiated in an editable item. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_SELCHANGE 
pnm = (NMGRID *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMGRID structure containing notification data.

Return Values
No return value.*/

SGN_EDITBEGIN

The SGN_EDITBEGIN notification message notifies a simple grid control's parent window that an edit operation was initiated in an editable item. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_EDITBEGIN 
pnm = (NMGRID *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMGRID structure containing notification data.

Return Values
No return value.*/

SGN_EDITEND

The SGN_EDITEND notification message notifies a simple grid control's parent window that an edit operation was compleated in an editable item. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_EDITEND 
pnm = (NMGRID *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMGRID structure containing notification data.

Return Values
No return value.*/

SGN_ITEMCLICK

The SGN_ITEMCLICK notification message notifies a simple grid control's parent window that an item in the received a mouse click. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_ITEMCLICK 
pnm = (NMGRID *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMGRID structure containing notification data.

Return Values
No return value.*/

NMSGKEYDOWN

The NMSGKEYDOWN structure contains information for the SGN_KEYDOWN notification.

C++
typedef struct tagNMSGKEYDOWN {
    NMHDR hdr;
    int col;
    int row;
    DWORD dwType;
    WORD wVKey;
} NMSGKEYDOWN, *LPNMSGKEYDOWN;

/*Members
hdr
     Specifies an NMHDR structure. The code member of the NMHDR structure identifies 
     the notification being sent.
col
     The column index of the item.
row
     The row index of the item.
dwType
     Column type (thus cell type) identifier.
wVKey
     Virtual key code.

Remarks
     The address of this structure is specified as the lParam parameter of the 
     WM_NOTIFY message for the SGN_KEYDOWN notification message.*/

SGN_KEYDOWN

The SGN_KEYDOWN notification message notifies a simple grid control's parent window that a key has been pressed. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_KEYDOWN 
pnm = (NMSGKEYDOWN *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMSGKEYDOWN structure containing notification data.

Return Values
No return value.*/

NMSGFOCUS

The NMSGFOCUS structure contains information for the SGN_GOTFOCUS and SGN_LOSTFOCUS notifications.

C++
typedef struct tagNMSGFOCUS {
    NMHDR hdr;
    int col;
    int row;
    DWORD dwType;
    HWND hFocus;
} NMSGFOCUS, *LPNMSGFOCUS;

/*Members
hdr
     Specifies an NMHDR structure. The code member of the NMHDR structure identifies 
     the notification being sent.
col
     The column index of the item.
row
     The row index of the item.
dwType
     Column type (thus cell type) identifier.
hFocus
     Handle of window receiving or loosing focus.

Remarks
     The address of this structure is specified as the lParam parameter of the 
     WM_NOTIFY message for SGN_GOTFOCUS and SGN_LOSTFOCUS 
     notification messages.*/

SGN_GOTFOCUS

The SGN_GOTFOCUS notification message notifies a simple grid control's parent window that the grid now has keyboard and mouse focus. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_GOTFOCUS 
pnm = (NMSGFOCUS *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMSGFOCUS structure containing notification data.

Return Values
No return value.*/

SGN_LOSTFOCUS

The SGN_LOSTFOCUS notification message notifies a simple grid control's parent window that the grid no longer has keyboard and mouse focus. This notification code is sent in the form of a WM_NOTIFY message.

C++
SGN_LOSTFOCUS 
pnm = (NMSGFOCUS *) lParam; 
 
/*Parameters
pnm
     Pointer to an NMSGFOCUS structure containing notification data.

Return Values
No return value.*/

Things to do someday

Make SimpleGrid theme compliant:

  • In a previous article [^] I discussed a simple method to make the editor controls borderless. Since then, I moved to Windows 7 and noticed that this didn't always achieve the desired result in a themed window. I took the lazy way out and employed SetWindowTheme(hwnd, L" ", L" ") in the editor constructor for the button and combobox. This, in effect, forces these controls to be drawn unthemed while not affecting the rest of the grid. As far as the inactive cells go, The buttons and checks are drawn using DrawFrameControl(). Theming doesn't seem to extend to them. This gives the grid a rather utilitarian look and feel in a vista/win7 environment.

Final Comments

I documented this source with Doxygen [^] comments for those that might find it helpful or useful. Your feedback is appreciated.

History

  • November 13, 2013: Version 1.0.0.0. - Initial Release
  • November 15, 2013: Version 1.1.0.0. - Bug Fix
  • November 16, 2013: Version 1.2.0.0. - Fixed potential bug condition under X64 operation
  • March 06, 2014 Version 1.3.0.0. - Fixed Bug where SG_RESETCONTENT message handled incorrectly.
  • March 07, 2014 Version 1.4.0.0. - Fixed Bug where an active in-cell editor wasn't removed when the grid content was reset.
  • March 27, 2014 Version 1.5.0.0. - Several Modifications and Bug fixes:
    • Added message SG_SELECTCELL and macro def. SimpleGrid_SelectCell().
    • Renumbered messages.
    • Redefined message SG_SETCURSORPOS and macro def. SimpleGrid_SetCursorPos() so that the column argument is passed as the WPARAM and row argument as LPARAM in order that they might be consistent with the rest of the messages.
    • Changed the behavior of the grid so that it doesn't initiate a cell edit if just any key is pressed. (Now if the windows key is pressed the selected cell will not go into edit mode when the windows menu launches.)
    • Fixed the Factory method New_SimpleGrid() so that it should work if it is compiled into a DLL.
    • Fixed bug where mousing away from a cell during edit resulted in the cell not being updated.
  • April 7, 2014 Version 1.6.0.0. - Added an option to the SG_SELECTCELL message to Select Cell for either editing or overwriting. This better duplicates a behavior available in spreadsheet software. The macro SimpleGrid_SelectCell() also reflects this change.
  • April 8, 2014 Version 1.7.0.0. - Improved the behavior of an in cell edit when SimpleGrid_SelectCell()is called with edit mode enabled. Now the left and right arrow keys navagate the in-cell text instead of causing a jump to the next cell.
  • April 8, 2014 Version 1.8.0.0. - Fixed a bug introduced into the demo by the refactored changes in Version 1.5.0.0. Also refactored notification methods in SimpleGrid.c
  • May 6, 2014 Version 1.9.0.0. - Several Modifications and Bug fixes:
    • Fixed bug where edited text would be reset after resizing a column.
    • Refactored portions to make source easier to port to MSVC++. (For the rest see: Adapting C99 code to MSVC.)
    • Editor and button fonts now set to parent grid font.
  • January 22, 2015 Version 2.0.0.0 - Fixed a bug introduced in 1.9 where button not destroyed  when resizing a button column.
  • February 26, 2016 Version 2.1.0.0 - Added two new messages SimpleGrid_InsertRow and SimpleGrid_DeleteRow.  Special thanks to Ferenc Hechler for contributing the code to insert a row into the grid.
  • March 28, 2016 Version 2.2.0.0 - Fixed the macroes SimpleGrid_GetRowHeaderText and SimpleGrid_GetRowHeaderTextLen.
  • June 24, 2018 Version 2.2.1.0 (MSVC project only) - Fixed truncated text bug in MSVC project - Special thanks to Hans-Peter Kalb

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)