MFC:在派生的 CEdit 中没有收到 EN_CHANGE 消息
Posted
技术标签:
【中文标题】MFC:在派生的 CEdit 中没有收到 EN_CHANGE 消息【英文标题】:MFC: Didn't get EN_CHANGE message within derived CEdit 【发布时间】:2016-01-06 13:15:25 【问题描述】:我看到 CEdit 的行为非常奇怪。在我从 CEdit 控件派生的类中,我需要捕获文本更改事件。我通过ON_CONTROL_REFLECT_EX
进行操作
class CSomeDerivedEdit : public CEdit
DECLARE_DYNAMIC(CSomeDerivedEdit )
public:
CSearchEditCtrl();
protected:
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEnChange();
...
;
在cpp中
IMPLEMENT_DYNAMIC(CSomeDerivedEdit , CEdit)
BEGIN_MESSAGE_MAP(CSomeDerivedEdit , CEdit)
ON_CONTROL_REFLECT_EX(EN_CHANGE, &CSomeDerivedEdit::OnEnChange)
END_MESSAGE_MAP()
我在某个列表控件中创建的这个控件作为子窗口,当我创建它并作为父窗口指针传递给列表控件时,一切正常,我得到 EN_CHANGE 事件但是当我作为列表控件事件的父窗口标题控件传递时没有'不反抗。
m_someEdit.Create( WS_CHILDWINDOW|WS_VISIBLE, rcRect, this, IDC_EDIT);
这里一切正常
m_someEdit.Create( WS_CHILDWINDOW|WS_VISIBLE, rcRect, GetHeaderCtrl(), IDC_EDIT);
这里的控件创建也很好,我看到了,但是当我输入编辑控件时没有调用 on_control_reflect。
【问题讨论】:
所以我再次发现了一个非常奇怪的解决方案,我派生了自己的 CHeaderCtrl 类并将其子类化为列表控件,之后我开始进入它的子编辑控件 EN_CHANGE 事件。但是为什么它是这样工作的,我还是不明白:) 【参考方案1】:只有当 WM_COMMAND 消息的接收者在 MFC 中也是子类时,ON_CONTROL_REFLECT_EX 才能工作。如果它是纯 Windows 控件并且没有使用 MFC 子类化,则 WM_COMMAND 消息永远不会反映给任何子控件。
记住:反射起作用,因为 MFC 首先处理来自父级中的子级的 WM_COMMAND 消息,然后将其返回给子级控件。如果不处理 WM_COMMAND 消息,则在父级内部处理。标准窗口控件不知道反射,总是自己处理 WM_COMMAND 消息....
因此,如果 MFC 未对标头控件进行子类化,则反射将不起作用。
【讨论】:
那么是子类化虚拟标题控件的正确解决方案,还是有其他方法可以在编辑控件类中获取文本更改事件? 我的问题是:你为什么使用标题作为父级。 edit 将在 header 控件上打开,就像在列表控件中快速搜索一样,当用户开始键入时,edit 将在 header 控件上打开并带有搜索字符串。使其成为标题的子窗口,它将防止任何 Z 顺序问题或兄弟问题,编辑将只是具有剪辑子样式的标题的子窗口。 我认为使用列表控件本身没有问题。但是子类标题控件只是为了使反射工作就足够了。好好记录一下。这是一些人很快就会忘记的事情。【参考方案2】:我认为你应该阅读 MSDN。当您派生类CEdit
时,您应该将ON_EN_CHANGE
消息处理程序放在BEGIN_MESSAGE_MAP()
和END_MESSAGE_MAP()
宏之间。另一方面,OnEnChange
函数,其声明为:
afx_msg void OnEnChange();
不返回BOOL
值。 ON_EN_CHANGE
消息处理程序应该是这样的(来自 MSDN):
BEGIN_MESSAGE_MAP()
ON_EN_CHANGE(ID_OF_THIS_CONTROL,OnEnChange)
END_MESSAGE_MAP()
希望这会对你有所帮助。
【讨论】:
以上是关于MFC:在派生的 CEdit 中没有收到 EN_CHANGE 消息的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在不使用 /UNICODE 编译的情况下使用 MFC 的 CEdit 函数“ShowBalloonTip”?
使用 MFC,如何为带有圆角和阴影的 CEdit 控件设置样式?