我正在使用 MFC 做一个应用程序。我刚刚创建了一个从 CEdit 派生的类,因此我可以拦截 OnChar() 并进行数据验证。如何用我制作的派生控件替换应用程序中的编辑控件?
2 回答
不要使用!_GetDlgItem
GetDlgItem()
返回一个CWnd
-pointer,仅此而已。这意味着您有一个切片CMyCustomEdit
指针。当然,它适用于您的方法向底层发送消息的所有情况HWND
。但这只是纯粹的运气!您可以在此处阅读有关该问题的更多信息。
正确的解决方案是使用DDX_Control子类化您的编辑控件。
我找到了解决方案。我之所以这么难,是因为我没有使用类向导来创建新类,使事情变得非常复杂。如果您只是使用类向导,您可以选择将控制变量添加到派生类,就像它们是常规类一样,只要基类是您元素的正确类。不过,这不是必需的。您所要做的就是创建一个派生类类型的指针并转换您想要获取的项目,就像您通常对非派生类所做的那样。
使用派生自 CEdit 的类访问编辑控件的示例
CMyCustomEdit * editPtr = (CMyCustomEdit*)GetDlgItem(IDC_EDIT1);
正如另一位成员在下面提到的(谢谢),使用 GetDlgItem 不是一个好主意。实际上,在我的代码中,我最终对它进行了子类化,因此我可以将我的新类与我已经存在的编辑控件一起使用。如前所述,我不明白编辑控件不一定附加到 CEdit,因此上面的示例应该清楚地表明您的 IDC_EDIT 可以用作 CMyCustomEdit 以及 CWnd 等等;只要您使用正确的类引用它,它就会自然地运行。
现在进行子分类。如果你真的想让你的编辑控件总是在你的基类之前调用你的派生类,你必须让它成为一个子类。不要将其视为面向对象的概念,这只是消息(如 WN_CHAR)将首先通过您的派生类,然后调用基类。
在编辑控件上对 CMyCustomEdit 进行子类化的示例:
首先,您需要在对话框的 .cpp 和 .h 中包含新类的 .h 文件。这些通常与您的项目同名。这里将是 MyMainDialog。
#include "CMyCustomEdit.h"
在派生对话框类中包含一个新派生类类型的变量:
class MyMainDialog : public CDialogEx
{
protected:
CMyCustomEdit m_cmCEdit;
}
然后在您的派生对话框类 (MyMainDialog) 的 OnInitDialog() 子类中您的编辑控件。为了安全起见,在函数中的常规代码之后和返回之前添加这个(像往常一样):
m_cmCEdit.SubclassDlgItem(IDC_EDIT1, this);
完成此操作后,当您在 ID 为 IDC_EDIT1 的编辑控件中执行任何操作时,消息将在进入 CEdit 之前通过 CMyCustomEdit。当您需要覆盖来自基类的消息时,这通常是必要的。
希望它可以帮助任何有类似问题的人。