CGridCellNumeric - MFC 网格的数字单元格类
一个具有区域感知、可编辑、自验证功能的数字单元格类,用于 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 日 - 正式发布。