Simple Grid - 基于 Win32 消息的 Grid 控件






4.92/5 (68投票s)
一个易于使用的Windows SDK C应用程序网格控件。
图1 原始 Baby Grid 演示
图2 新增列
目录
- 引言
- 背景
- 使用 Simple Grid
- 公共数据结构
- SGCOLUMN
- SGITEM
- 消息和宏
- 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
简介
C 语言程序员在网上寻求一个可用于非 MFC 项目的网格控件时,通常会(被)推荐一到两个已发布的项目。第一个是2002年由 David Hillard 发布的 Win32 Grid Control with Low Overhead (BABYGRID) [^]。第二个是我自己在2009年发布的,对 List view 的改进版本 Win32 SDK Data Grid View Made Easy [^],当时它比 Hillard 先生的网格更符合我的需求。
现在,我们不得不承认,如果一个 Win32/64 C 应用程序只能在这两个项目之间选择,那真是一种悲哀。我发布新东西已经有一段时间了,我也准备好接受挑战,所以决定着手改进 BABYGRID,修复一些已知缺陷并增加一些功能。结果比我预期的要花费更多精力,但总的来说,这是一个令人愉快的业余项目,期间我甚至重新找回了作为一名程序员的感觉!
背景
我在2004年或2005年第一次接触到 BABYGRID,并将其用于我为工作单位的 QA 部门编写的一个工程自动化测试应用程序中。对于那个应用程序来说,该网格的外观和行为都还不错,但存在一些局限性,而且由于其代码编写方式,修改起来很困难。与此同时,作者也意识到了这一点,并在编写 UI 元素方面积累了一些经验后,编写了第二个、更好的网格 ZEEGrid,并从他的网站上以合理的价格出售了一段时间。最终 ZEEGrid 和作者的网站一起从网上消失了。 最新消息! ZEEGrid 已回归,作者 David Hillard 再次免费提供。您可以从 http://www.kycsepp.com 下载 ZeeGrid,快去看看吧。
这是 Code Guru 上 BABYGRID 文章附带的旧评论摘录。他提到这里的 BABYGRID 新版本已作为 ZEEGrid 发布。
BABYGRID 新版本即将发布! 发布者 DHillard 于 2004/11/08 01:41pm我一直在为这个网格开发新版本几个月了。
新版本将实现为一个 DLL,其编程接口(SendMessage)与此网格基本相同。这将使非 C/C++ 语言的程序员更容易访问。
新版本是全新的,使用了一个网格引擎来直接访问网格单元格的内容。这取代了此网格中使用的二进制查找。它还通过使用后备缓冲区在内存中创建网格显示,然后将其位图绘制到屏幕上,从而比 BABYGRID 快得多。
它还具有以下功能:
- 真正的单元格内编辑(使用编辑控件)
- 合并具有相同数据的行中的单元格
- 列重排
- 搜索网格或搜索列
- 按列排序
- 127 种颜色调色板
- 127 种字体调色板
- 受保护的单元格
- 将网格内容导出到 CSV 文件
- 打印网格
- 9 种单元格对齐方式
- 单元格左缩进和右缩进
- 单个单元格的背景色、前景色
- 列大小调整/隐藏
- 固定列
- 列数无限制(除内存限制外)
- 行数无限制(同样,内存允许的情况下)
- 127 个图标调色板,可将单元格文本与图形(图标)结合
(基本上修复了 BABYGRID 的所有恼人之处。)
听起来不错,对吧?然而,重复 Hillard 先生的工作对我来说将是力不能及,所以我专注于对原始网格概念进行以下一些适度的改进:
- 将源代码组织成易于维护和理解的格式。
- 记录并为所有消息提供宏,以便于使用。
- 以 Win32 应用程序的常见方式创建、存储和销毁网格实例,因此对可以创建的网格数量没有人工限制。
- 重写网格的部分代码以支持 Unicode。
- 采用可选的双缓冲(Simple Grid 默认使用双缓冲)。
- 用向量列表替换存储列表框+二进制查找机制,以实现对单元格数据的快速访问。
- 提供多种不同类型的列,用于编辑和显示数据,即:文本、组合框、链接、图像、按钮和复选框。
- 无限行,475255 列(当然,内存允许的话)。
- 列大小调整/隐藏和单元格保护功能保留自原始 BABYGRID 代码。
- 单元格内对齐选项:左对齐、右对齐或通用对齐(如果设置为通用,则数字内容自动右对齐,而字母内容自动左对齐)。
使用 Simple Grid
首先,在项目中包含 SimpleGrid 控件的头文件。
#include "SimpleGrid.h"
SimpleGrid 控件是基于消息的自定义控件,因此在使用前必须进行初始化。一种处理方法是在应用程序的 WinMain()
方法中,在调用 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);
为了简单起见,我将此步骤合并到控件的伪构造函数中。它仅在第一次实例化新的 SimpleGrid 控件时调用一次。
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;
}
演示代码提供了几种数据输入网格以供显示和操作的方法。以下代码片段展示了如何加载具有不同类型列的网格,然后相应地添加和设置行数据。
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]);
}
}
注意: 类型为 GCT_COMBO
的列存储了一组共享该列中每个单元格的选项(一个双空终止字符串列表)。同样,类型为 GCT_IMAGE
的列存储了一个共享该列中每个单元格的图像列表句柄。然而,类型为 GCT_LINK
的列中的项目采用一个由链接文本和 URL 组成的双元素列表(也是双空终止字符串列表)。
以下是 SimpleGrid 控件类的编程参考。
公共数据结构
SGCOLUMN
SGCOLUMN
结构指定或接收 SimpleGrid 列的属性。
typedef struct tagSGCOLUMN {
DWORD dwType;
LPTSTR lpszHeader;
LPVOID pOptional;
} SGCOLUMN, *LPSGCOLUMN;
成员
dwType
:列类型标识符。该值可以是以下之一:GCT_EDIT
- 列类型:编辑GCT_COMBO
- 列类型:下拉列表GCT_BUTTON
- 列类型:按钮GCT_CHECK
- 列类型:复选框GCT_LINK
- 列类型:链接GCT_IMAGE
- 列类型:图像
lpszHeader
:列标题文本。pOptional
:列可选参数。数据类型取决于项目类型,如下所示:GCT_EDIT
、GCT_BUTTON
、GCT_CHECK
和GCT_LINK
- NULL(未使用)。GCT_COMBO
- 一个双空终止字符串列表(组合框项),由该列中的每个单元格共享。GCT_IMAGE
- 一个图像列表句柄,由该列中的每个单元格共享。
SGITEM
SGITEM
结构指定或接收 SimpleGrid 项目或单元格的属性。
typedef struct tagSGITEM{
int col;
int row;
LPARAM lpCurValue;
} SGITEM, *LPSGITEM;
成员
col
:项目的列索引。row
:项目的行索引。lpCurValue
:项目值。数据类型取决于项目类型,如下所示:GCT_EDIT
、GCT_BUTTON
和GCT_COMBO
- 在单元格中显示的文本(或按钮文本)。GCT_CHECK
- 布尔值 TRUE 或 FALSE。GCT_IMAGE
- 一个整数,显示图像的索引。
消息和宏
使用 Windows 消息配置控件以满足您的需求。为了方便起见,并作为文档记录消息的一种方式,我为每条消息创建了宏。如果您更愿意显式调用 SendMessage()
或 PostMessage()
,请参阅头文件中的宏定义以了解用法。
注意: 如果消息返回 SG_ERROR
,请使用 GetLastError()
来查找错误的详细信息。
SimpleGrid_AddColumn
向网格添加一列。
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
向网格添加一列。
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
向网格添加一行数据。(此函数结合了 SimpleGrid_AddRow()
、SimpleGrid_SetItemData()
和 SimpleGrid_SetItemTextAlignment()
,是一个方便的宏。)
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
启用或禁用指定网格的鼠标和键盘输入。
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
启用或禁用网格中的编辑功能。
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
设置网格以使最后一列扩展到客户区末尾。
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
获取网格中的列数。
INT SimpleGrid_GetColCount(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The column count.
*/
SimpleGrid_GetColumnHeaderText
获取列标题中显示的文本。
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
检索列标题文本字符串的长度。
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
获取此单元格所代表的数据类型。
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
获取列的宽度(以像素为单位)。
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
获取光标所在的列。
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
获取光标所在的列。
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
获取标题行的行高。
INT SimpleGrid_GetHeaderRowHeight(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The height (in pixels) of the header row.
*/
SimpleGrid_GetImageColumnImageList
获取与图像列关联的图像列表。
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
获取单个项目(单元格)的内容。
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
获取单个项目的文本。
注意: 如果项目属于 GCT_EDIT
、GCT_COMBO
或 GCT_BUTTON
类型的列,则缓冲区将填充项目文本。如果项目属于 GCT_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
检索与网格项关联的数据长度。
注意: 如果项目属于 GCT_EDIT
、GCT_COMBO
或 GCT_BUTTON
类型的列,则返回的值是项目文本的长度。如果项目属于 GCT_LINK
类型的列,则返回的值是由两个字符串组成的连续数组缓冲区的长度:显示文本和链接 URL。如果项目属于 GCT_CHECK
或 GCT_IMAGE
类型的列,则返回 0,因为此数据不是字符串。
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
获取项目的(单元格的)保护标志。
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
获取网格中的行数。
INT SimpleGrid_GetRowCount(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The row count.
*/
SimpleGrid_GetRowHeaderText
获取行标题中显示的文本。
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
检索行标题文本字符串的长度。
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
获取行的(像素)高度。
INT SimpleGrid_GetRowHeight(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The height (in pixels) of the rows
*/
SimpleGrid_GetTitle
获取网格的标题文本。
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
获取网格标题栏文本的(字符)长度。
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
使网格重绘自身。
VOID SimpleGrid_RefreshGrid(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The return value is not meaningful.
*/
SimpleGrid_ResetContent
从网格中移除所有数据、行和列。
VOID SimpleGrid_ResetContent(
HWND hGrid
);
/*Parameters
hGrid
Handle to the SimpleGrid control.
Return Values
The return value is not meaningful.
*/
SimpleGrid_SelectCell
选择一个单元格并设置焦点以编辑其内容。
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
配置列大小调整。
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
配置网格列自动调整以适应内容。
注意: 这应该在添加数据到网格之前设置。
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
设置列标题中显示的内容。
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
设置要在列标题中显示的文本。
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
设置给定列的宽度(以像素为单位)。
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
设置网格中的光标位置(或当前选中的单元格)。
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
设置双缓冲以减少具有许多列的网格中的闪烁。
注意: 默认情况下,SimpleGrid 使用双缓冲。
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
设置单元格中文本的显示方式。
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
设置网格线的颜色。
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
设置标题行的高度(以像素为单位)。
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
设置用于网格标题的字体。
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
设置高亮显示单元格的背景颜色。
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
设置高亮显示单元格的文本颜色。
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
设置与图像列关联的图像列表。
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
设置单个单元格的内容。
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
设置单个项目(单元格)的文本。
注意: 如果项目属于 GCT_EDIT
、GCT_COMBO
或 GCT_BUTTON
类型的列,则字符串应包含项目文本。如果项目属于 GCT_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
将项目文本对齐方式设置为左对齐、通用对齐或右对齐。
注意: 将对齐方式设置为 GSA_GENERAL
(默认)会导致网格根据内容自动对齐文本。数字数据右对齐,所有其他文本左对齐。对齐方式仅适用于 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
将项目文本对齐方式设置为左对齐、通用对齐或右对齐。
注意: 将对齐方式设置为 GSA_GENERAL
(默认)会导致网格根据内容自动对齐文本。数字数据右对齐,所有其他文本左对齐。对齐方式仅适用于 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
设置单个单元格的保护状态。
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
设置单个单元格的保护状态。
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
设置受保护单元格的背景颜色。
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
设置要在列标题中显示的文本。
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
设置行标题列的宽度(以像素为单位)。
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
设置行的(像素)高度。
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
设置是否高亮显示选定行。
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
设置是否以及如何高亮显示选定行。
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
设置网格标题的文本。
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
设置用于显示网格标题的字体。
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
设置网格标题的高度。
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
设置网格如何显示顶部和底部可见行。
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
在给定位置向网格添加一行。
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
在给定位置向网格添加一行。
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.
*/
通知
SimpleGrid 通过 WM_NOTIFY
提供通知。这些通知消息的 lParam
参数指向多个通知数据结构之一。为了简化文档,结构和相关消息在此处分组。
NMGRID
NMGRID
结构包含大多数 SimpleGrid 通知的信息。
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
SGN_SELCHANGE
通知消息通知简单网格控件的父窗口,已在可编辑项中启动了编辑操作。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_SELCHANGE
pnm = (NMGRID *) lParam;
/*Parameters
pnm
Pointer to an NMGRID structure containing notification data.
Return Values
No return value.*/
SGN_EDITBEGIN
SGN_EDITBEGIN
通知消息通知简单网格控件的父窗口,已在可编辑项中启动了编辑操作。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_EDITBEGIN
pnm = (NMGRID *) lParam;
/*Parameters
pnm
Pointer to an NMGRID structure containing notification data.
Return Values
No return value.*/
SGN_EDITEND
SGN_EDITEND
通知消息通知简单网格控件的父窗口,已在可编辑项中完成了编辑操作。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_EDITEND
pnm = (NMGRID *) lParam;
/*Parameters
pnm
Pointer to an NMGRID structure containing notification data.
Return Values
No return value.*/
SGN_ITEMCLICK
SGN_ITEMCLICK
通知消息通知简单网格控件的父窗口,其中一个项目收到了鼠标单击。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_ITEMCLICK
pnm = (NMGRID *) lParam;
/*Parameters
pnm
Pointer to an NMGRID structure containing notification data.
Return Values
No return value.*/
NMSGKEYDOWN
NMSGKEYDOWN
结构包含 SGN_KEYDOWN
通知的信息。
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
SGN_KEYDOWN
通知消息通知简单网格控件的父窗口,已按下某个键。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_KEYDOWN
pnm = (NMSGKEYDOWN *) lParam;
/*Parameters
pnm
Pointer to an NMSGKEYDOWN structure containing notification data.
Return Values
No return value.*/
NMSGFOCUS
NMSGFOCUS
结构包含 SGN_GOTFOCUS
和 SGN_LOSTFOCUS
通知的信息。
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
SGN_GOTFOCUS
通知消息通知简单网格控件的父窗口,该网格现已获得键盘和鼠标焦点。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_GOTFOCUS
pnm = (NMSGFOCUS *) lParam;
/*Parameters
pnm
Pointer to an NMSGFOCUS structure containing notification data.
Return Values
No return value.*/
SGN_LOSTFOCUS
SGN_LOSTFOCUS
通知消息通知简单网格控件的父窗口,该网格不再具有键盘和鼠标焦点。此通知代码以 WM_NOTIFY
消息的形式发送。
SGN_LOSTFOCUS
pnm = (NMSGFOCUS *) lParam;
/*Parameters
pnm
Pointer to an NMSGFOCUS structure containing notification data.
Return Values
No return value.*/
一些待办事项
使 SimpleGrid 符合主题
- 在之前的 文章 [^] 中,我讨论了一种使编辑器控件无边框的简单方法。从那时起,我迁移到了 Windows 7,并注意到这在主题化窗口中并不总是能达到预期的效果。我偷懒了,在按钮和组合框的编辑器构造函数中使用了
SetWindowTheme(hwnd, L" ", L" ")
。这实际上迫使这些控件以非主题方式绘制,而不会影响网格的其余部分。至于非活动单元格,按钮和复选框使用DrawFrameControl()
绘制。主题化似乎并不适用于它们。这使得网格在 vista/win7 环境中看起来相当实用。
最后的评论
我用 Doxygen [^] 注释记录了此源代码,供可能发现它有用的人参考。感谢您的反馈。
历史
- 2013年11月13日:版本 1.0.0.0。- 初始发布
- 2013年11月15日:版本 1.1.0.0。- 错误修复
- 2013年11月16日:版本 1.2.0.0。- 修复了 X64 操作下可能出现的错误条件
- 2014年3月6日 版本 1.3.0.0。- 修复了
SG_RESETCONTENT
消息处理不正确的错误。 - 2014年3月7日 版本 1.4.0.0。- 修复了当重置网格内容时,活动的单元格内编辑器未被移除的错误。
- 2014年3月27日 版本 1.5.0.0。- 多项修改和错误修复
- 添加了消息
SG_SELECTCELL
和宏定义SimpleGrid_SelectCell()
。 - 重新编号了消息。
- 重新定义了消息
SG_SETCURSORPOS
和宏定义SimpleGrid_SetCursorPos()
,以便将列参数作为 WPARAM 传递,行参数作为 LPARAM 传递,以使其与其余消息保持一致。 - 更改了网格的行为,使其在按下任意键时不会启动单元格编辑。(现在,按下 Windows 键时,当 Windows 菜单启动时,选定单元格不会进入编辑模式。)
- 修复了 Factory 方法
New_SimpleGrid()
,使其在编译到 DLL 中时应该可以工作。 - 修复了编辑过程中鼠标移出单元格时单元格未更新的错误。
- 添加了消息
- 2014年4月7日 版本 1.6.0.0。- 向
SG_SELECTCELL
消息添加了一个选项,用于为编辑或覆盖选择单元格。这更好地复制了电子表格软件中的可用行为。宏SimpleGrid_SelectCell()
也反映了此更改。 - 2014年4月8日 版本 1.7.0.0。- 改进了调用
SimpleGrid_SelectCell()
(启用编辑模式)时单元格内编辑器的行为。现在,左右箭头键可以在单元格内文本中导航,而不是跳到下一个单元格。 - 2014年4月8日 版本 1.8.0.0。- 修复了版本 1.5.0.0 中重构的更改引入到演示中的一个错误。还重构了 SimpleGrid.c 中的通知方法。
- 2014年5月6日 版本 1.9.0.0。- 多项修改和错误修复
- 修复了调整列大小时编辑的文本会被重置的错误。
- 重构了部分代码,使源代码更容易移植到 MSVC++。(其余内容请参见:Adapting C99 code to MSVC。)
- 编辑器和按钮字体现设置为父网格字体。
- 2015年1月22日 版本 2.0.0.0 - 修复了 1.9 版本中引入的一个错误,即调整按钮列大小时按钮未被销毁。
- 2016年2月26日 版本 2.1.0.0 - 添加了两条新消息 SimpleGrid_InsertRow 和 SimpleGrid_DeleteRow。特别感谢 Ferenc Hechler 为向网格插入行贡献了代码。
- 2016年3月28日 版本 2.2.0.0 - 修复了宏 SimpleGrid_GetRowHeaderText 和 SimpleGrid_GetRowHeaderTextLen。
- 2018年6月24日 版本 2.2.1.0 (仅 MSVC 项目) - 修复了 MSVC 项目中的文本截断错误 - 特别感谢 Hans-Peter Kalb