Simple Grid - A Win32 message based grid control






4.92/5 (68 votes)
A simple to use grid control for Windows SDK C applications.
- Download SimpleGrid DLL project - 140.1 KB
- Download source - 37.6 KB
- Download MSVC version project - 54.2 KB
- Download demo - 115.2 KB
Figure1 Original Baby Grid Demo
Figure2 New Columns
Table of Contents
- Introduction
- Background
- Using Simple Grid
- Public data structures
- SGCOLUMN
- SGITEM
- Messages and Macros
- SimpleGrid_AddColumn
- SimpleGrid_AddRow
- SimpleGrid_AddRowData
- SimpleGrid_Enable
- SimpleGrid_EnableEdit
- SimpleGrid_ExtendLastColumn
- SimpleGrid_GetColCount
- SimpleGrid_GetColumnHeaderText
- SimpleGrid_GetColumnHeaderTextLen
- SimpleGrid_GetColumnType
- SimpleGrid_GetColWidth
- SimpleGrid_GetCursorCol
- SimpleGrid_GetCursorRow
- SimpleGrid_GetHeaderRowHeight
- SimpleGrid_GetImageColumnImageList
- SimpleGrid_GetItemData
- SimpleGrid_GetItemText
- SimpleGrid_GetItemDataLen
- SimpleGrid_GetItemProtection
- SimpleGrid_GetRowCount
- SimpleGrid_GetRowHeaderText
- SimpleGrid_GetRowHeaderTextLen
- SimpleGrid_GetRowHeight
- SimpleGrid_GetTitle
- SimpleGrid_GetTitleLength
- SimpleGrid_RefreshGrid
- SimpleGrid_ResetContent
- SimpleGrid_SelectCell
- SimpleGrid_SetAllowColResize
- SimpleGrid_SetColAutoWidth
- SimpleGrid_SetColsNumbered
- SimpleGrid_SetColumnHeaderText
- SimpleGrid_SetColWidth
- SimpleGrid_SetCursorPos
- SimpleGrid_SetDoubleBuffer
- SimpleGrid_SetEllipsis
- SimpleGrid_SetGridLineColor
- SimpleGrid_SetHeaderRowHeight
- SimpleGrid_SetHeadingFont
- SimpleGrid_SetHilightColor
- SimpleGrid_SetHilightTextColor
- SimpleGrid_SetImageColumnImageList
- SimpleGrid_SetItemData
- SimpleGrid_SetItemText
- SimpleGrid_SetItemTextAlignment
- SimpleGrid_SetItemTextAlignmentEx
- SimpleGrid_SetItemProtection
- SimpleGrid_SetItemProtectionEx
- SimpleGrid_SetProtectColor
- SimpleGrid_SetRowHeaderText
- SimpleGrid_SetRowHeaderWidth
- SimpleGrid_SetRowHeight
- SimpleGrid_SetRowsNumbered
- SimpleGrid_SetSelectionMode
- SimpleGrid_SetTitle
- SimpleGrid_SetTitleFont
- SimpleGrid_SetTitleHeight
- SimpleGrid_ShowIntegralRows
- SimpleGrid_InsertRow
- SimpleGrid_DeleteRow
- Notifications
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:41pmI 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()
.
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.
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.
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.
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: EditGCT_COMBO
- Column type: Dropdown listGCT_BUTTON
- Column type: ButtonGCT_CHECK
- Column type: Check boxGCT_LINK
- Column type: LinkGCT_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
andGCT_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.
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
andGCT_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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
.
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
.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 usingDrawFrameControl()
. 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.
- Added message
- 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 macroSimpleGrid_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