65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (68投票s)

2013年11月12日

CPOL

16分钟阅读

viewsIcon

270879

downloadIcon

18317

一个易于使用的Windows SDK C应用程序网格控件。

Figure1

图1 原始 Baby Grid 演示

Figure2

图2 新增列

目录

简介

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_EDITGCT_BUTTONGCT_CHECKGCT_LINK - NULL(未使用)。
    • GCT_COMBO - 一个双空终止字符串列表(组合框项),由该列中的每个单元格共享。
    • GCT_IMAGE - 一个图像列表句柄,由该列中的每个单元格共享。

SGITEM

SGITEM 结构指定或接收 SimpleGrid 项目或单元格的属性。

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

成员

  • col:项目的列索引。
  • row:项目的行索引。
  • lpCurValue:项目值。数据类型取决于项目类型,如下所示:
    • GCT_EDITGCT_BUTTONGCT_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_EDITGCT_COMBOGCT_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_EDITGCT_COMBOGCT_BUTTON 类型的列,则返回的值是项目文本的长度。如果项目属于 GCT_LINK 类型的列,则返回的值是由两个字符串组成的连续数组缓冲区的长度:显示文本和链接 URL。如果项目属于 GCT_CHECKGCT_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_EDITGCT_COMBOGCT_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_GOTFOCUSSGN_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_InsertRowSimpleGrid_DeleteRow。特别感谢 Ferenc Hechler 为向网格插入行贡献了代码。
  • 2016年3月28日 版本 2.2.0.0 - 修复了宏 SimpleGrid_GetRowHeaderTextSimpleGrid_GetRowHeaderTextLen
  • 2018年6月24日 版本 2.2.1.0 (仅 MSVC 项目) - 修复了 MSVC 项目中的文本截断错误 - 特别感谢 Hans-Peter Kalb
© . All rights reserved.