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

CGridCellNumeric - MFC 网格的数字单元格类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (9投票s)

2004年9月15日

CPOL

5分钟阅读

viewsIcon

109757

downloadIcon

3741

一个具有区域感知、可编辑、自验证功能的数字单元格类,用于 MFC 网格。可配置为整数、浮点数或货币。

引言

我目前需要一个体面的网格控件,它具有编辑和显示数字等功能。在我能承受的价格范围(免费)内,我认为最好的就是 Chris Maunder 的 MFC Grid 2.25 [^]。但不幸的是,对我来说,它需要一些修改才能达到我想要的效果。我在这里提出的一个修改是 CGridCellNumeric 类,它用于显示和编辑数字和货币。这个类是 MFC Grid 中包含的 CGridCellNumeric 类的严重修改版本。该类使用计算机的区域设置来显示数字,但提供了一种让你覆盖这些设置的方式。如果你将单元格设置为使用浮点数,即使只显示两位,数字的精度也将保持在九位小数。如果需要,将在单元格的编辑控件部分显示完整的九位小数。

输入验证是在用户键入时即时进行的。所有验证都在 EN_UPDATE 消息处理程序中完成,因此任何剪切/复制和粘贴操作都会立即得到验证。如果用户删除单元格中的文本,则值将设置为零。

使用 CGridCellNumeric 类

下载并解压文件,将 CPP 和头文件保存到“GridCtrl/NewCellTypes”文件夹中。它们可以替换其中已有的 GridCellNumeric 文件。我使用了现有的文件作为此代码的起点。

要将 CGridCellNumeric 单元格添加到网格中,只需像添加任何其他单元格类型一样添加它

m_Grid.SetCellType(1,1, RUNTIME_CLASS(CGridCellNumeric));

然后您就可以开始了。要设置数字单元格的选项,您必须获取它的指针,并调用它的成员函数之一。

CGridCellNumeric *pCell = (CGridCellNumeric *)m_Grid.GetCell(1, 1);
pCell->SetFlags(CGridCellNumeric::Currency | CGridCellNumeric::Negative);
pCell->SetNumber(125.36);

CGridCellNumeric 类派生自 CGridCell,而编辑控件类 (CInPlaceNumEdit) 派生自 CInPlaceEdit,因此除了下面列出的 API 函数外,您可以像使用 MFC Grid 提供的任何其他可编辑单元格一样使用此单元格。

对 CInPlaceEdit 类的重要更改

CInPlaceEdit 类有一个小的但非常重要的更改。您必须将 CRect m_Rect 变量从私有成员移至 CInPlaceEdit 类的保护成员。这样做是为了让派生的 CInPlaceNumEdit 类能够根据需要重置编辑框的初始大小,并且需要访问 m_Rect 成员才能做到这一点。因此,在 InPlaceEdit.h 文件中,进行以下更改

class CInPlaceEdit : public CEdit
{
    ...

protected:
    CRect m_Rect;   // Add this line
    ...

private:
    ...
//  CRect m_Rect; // comment out, or remove, this line
};

同样,但不如上面重要,因为它更多的是一个外观上的东西,而不是其他任何东西,那就是更改 CInPlaceEdit 用于计算您键入时编辑控件新大小的空间缓冲区的大小。转到 InPlaceEdit.cpp 文件,在 CInPlaceEdit::OnChar() 函数的第 178 行,将缓冲区大小从两个空格更改为六个空格

// change from:
//  str += _T("  ");
//  to
    str += _T("      ");

此更改将防止编辑控件在调整窗口大小之前将文本向左滚动。

CGridCellNumeric 类 API 函数

  • DWORD SetFlags (DWORD dwFlags)

    设置控制单元格如何操作的标志。可能的标志有:

    • CGridCellNumeric::Integer - 单元格只处理整数,不能显示或输入浮点数。
    • CGridCellNumeric::Real - 单元格处理浮点数。
    • CGridCellNumeric::Currency - 单元格处理货币数字。

      请注意,这前三个值是相互排斥的,如果在使用 SetFlags 调用时未指定它们,则默认假定 CGridCellNumeric::Integer 标志。

    • CGridCellNumeric::Negative - 单元格可以处理负数。如果未指定此标志,单元格将只处理正数。
    • CGridCellNumeric::Silent - 如果未设置此标志,CGridCellNumeric 单元格关联的编辑控件将在输入无效条目时发出警告蜂鸣声。使用此标志可以使蜂鸣声静音。

    返回值

    一个包含先前标志的 DWORD,如果新标志未能设置,则为 -1。

  • DWORD GetFlags()

    获取当前标志。有关可能值,请参见上面的 SetFlags

    返回值

    一个包含当前标志的 DWORD

  • BOOL SetNumber (double Number)

    设置单元格中显示的数字的值。尽管它存储为 double,但精度仅保证到小数点后九位。除非通过 SetNumberFmt()SetCurrencyFmt() 函数(见下文)指定,否则数字将根据计算机的区域设置显示,但内部数字的精度保证为小数点后九位,并且这些小数位全部显示在编辑控件中。

    返回值

    如果数字已成功设置,则为 TRUE。否则为 FALSE

  • double GetNumber()

    获取当前存储在单元格中的数字。此数字保证精确到小数点后九位。

    返回值

    一个包含单元格中数字的 double

  • void SetNumberFmt (LPNUMBERFMT lpNumberFmt)

    如果要覆盖计算机关于整数和浮点数显示方式的默认设置,请使用此函数。您可以传递一个指向 NUMBERFMT 结构的指针,该结构由 GetNumberFormat() 函数使用。有关更多信息,请在 MSDN 中查找 GetNumberFormat()NUMBERFMT

  • void SetCurrencyFmt (LPCURRENCYFMT lpCurrencyFmt)

    如果要覆盖计算机关于货币显示方式的默认设置,请使用此函数。您可以传递一个指向 CURRENCYFMT 结构的指针,该结构由 GetCurrencyFormat() 函数使用。有关更多信息,请在 MSDN 中查找 GetCurrencyFormat()CURRENCYFMT

待办事项

不知道我是否会做到,但我认为如果单元格支持除基 10 之外的不同基数,那将是很酷的。另一种可能性是支持指数格式。但这可能比我愿意付出的工作量还要多。

致谢

  • Chris Maunder,感谢他出色的网格控件。
  • Andrew Truckle,感谢他最初的 CGridCellNumeric 类,这个类就是在此基础上构建的。

更新

  • 2004 年 9 月 15 日 - 正式发布。
© . All rights reserved.