Win32API:如何确定EN_CHANGE是否是因为用户操作而不是软件操作?

时间:2010-02-05 16:20:54

标签: c++ windows mfc winapi notifications

我发现这种情况时有发生,我似乎从来没有一个非常强大的通用解决方案。

我有一个控件 - 在这个例子中是一个对话框的EDIT控件。我想采取某些行动来回应用户 - 只有用户 - 修改编辑控件的内容。

可以通过编程方式设置编辑控件 - 例如在设置对话框时,可能会在编辑字段中放置初始值。或者当用户从列表视图中选择一个项目时,该选择的文本可能就是放置在编辑字段中的内容。

但是当 用户 修改了编辑字段的内容时,我需要知道并回复(在这种情况下,我想清除选择中的内容)相应的列表视图)。

我目前正在查看哪些控件具有焦点,并且只有在编辑控件具有焦点时才将“EN_CHANGE”视为“来自用户”。

这在Windows 7下运行得非常好。这个在XP下失败(我还没有测试过Vista)。

在XP中,如果编辑字段具有焦点,但是用户单击列表视图,并且列表视图告诉编辑控件设置其内容,那么我从编辑控件获得声明仍然具有的通知focus(:: GetFocus()==编辑控件的HWND)。但是在Win7中不会出现这种不正确的状态。

这是一个分层界面,所以我无法修改列表视图通知处理程序。它会进行选择更改,并在没有我参与的情况下更新编辑字段或能够进行真正的干预,而不是从两者中获取通知。

有关如何一般性地永久解决“这个控制通知是否真的来自用户”这一难题的想法?

2 个答案:

答案 0 :(得分:1)

您随时可以跟踪LVM_ITEMCHANGINGLVM_ITEMCHANGEDEN_MSGFILTER消息。如果在LVM_ITEMCHANGINGLVM_ITEMCHANGED之间修改了编辑框,而中间没有EN_MSGFILTER,那么您可能会认为用户没有修改该项目。或者只是检查在EN_CHANGE触发时是否选择了任何项目,如果没有,或者文本与所选项目不匹配,则假设它是用户编辑。

或使用ES_MULTILINE(来自EN_CHANGE文档):

  

未发送EN_CHANGE通知   使用ES_MULTILINE样式时   并通过发送文本   WM_SETTEXT。

答案 1 :(得分:1)

我建议使用正确的信息。 EN_CHANGE过于通用,您想知道用户是键入还是粘贴了文本。那么为什么不对控件进行子类化并观察WM_KEYPRESS消息呢?

或者,您可以在其他代码中设置标记以设置编辑控件内容。您可以假设任何使您的wndproc可重入的内容代表程序化更改。

你不是在寻找真正安全的东西,不是吗?如果您只想排除相当简单的设置内容调用。如果要区分用户操作和用户按键的编程模拟,这是一个更难的问题。