处理Wm_Killfocus消息时需要注意的地方

之前我在一篇文章中曾经提过,不应该利用 WM_KILLFOCUS 消息中对表单的字段进行有效性校验。 今天的文章,我将介绍另外一个反面例子,来表现当使用 WM_KILLFOCUS 消息处理焦点相关的问题时所带来的混乱。

创新互联是专业的新北网站建设公司,新北接单;提供做网站、网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行新北网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

假设,有一个编辑框控件使用了气球提示来显示反馈信息。举个例子,对于一个密码输入控件,当键盘上的 CapsLock 按键按下时,它会提示用户,以防止用户输入错误的密码。作为开发者,你可能希望,当用户将输入焦点从密码输入框移动到另外一个控件时,将气球提示移除,这是合情合理的。因为向用户给出一个他完全不会使用到的控件提示,会让用户感到莫名其妙。可以通过对输入控件子类化来实现上述的需求,如下图所示:

使用上面的代码进行初步测试,一切如预期般正常工作,只是有一个问题:当用户点击气球提示时,编辑框的输入光标会意外的消失,这是为啥?

发生的事情是,你通过破坏焦点要去的窗口来破坏焦点变化过程!焦点更改过程如下所示:

  • 将焦点移动至新的窗口。
  • 发送 WM_KILLFOCUS 消息给丢失焦点的窗口(如果有的话) 发送 WM_SETFOCUS 消息给新的焦点窗口(如果有的话)

但是在上面的第二步,我们销毁了新的窗口。当焦点窗口被销毁后,Windows 窗口管理器会尝试找另外一个焦点窗口,最终它将输入焦点设置到了输入框控件本身。这将启动一个递归式的焦点更改过程,告知编辑控件它现在再次具有输入焦点。

让我们看一下当用户单击工具提示窗口时焦点变化流程。

  • > 设置焦点到工具提示。
  • > 发送 WM_KILLFOCUS 消息到输入框。
  • > EditSubclass 销毁了工具提示窗口。
  • > Windows 窗口管理器将焦点设置到输入框。
  • > WM_KILLFOCUS 不会发送给任何窗口。
  • > 发送 WM_SETFOCUS 给输入框。
  • > EditSubclass 将 WM_SETFOCUS 消息传递给原始窗口过程。
  • > EditSubclass 将 WM_KILLFOCUS 传递给原始窗口过程。

你看到这里面的问题了吗?

下面是到达原始编辑框窗口过程的消息流程:

WM_SETFOCUS(源自嵌套的焦点变化过程) WM_KILLFOCUS(源自原始的焦点变化过程)

就编辑控件而言,它获得了焦点,然后失去了焦点。因此,它不会显示输入光标,因为编辑控件仅在具有焦点时才显示光标,并且递归焦点变化会导致编辑控件认为它没有焦点,即使它有焦点。

摆脱这种混乱的方法有很多。

首先,请注意,你不需要对编辑控件进行子类化,你可以对 EN_KILLFOCUS 通知做出反应。其次,你还可以通过向自己发布消息并在收到该发布消息后销毁工具提示来响应 EN_KILLFOCUS。通过发布的消息执行此操作,你可以避免递归焦点变化,因为你的工作现在正在焦点更改周期之外完成的。

总结 请不要忽视这些细枝末节的问题,资深用户会感受到你的程序里的各种细节。 如果是好的细节,你的程序会加分,万一是不那么好的细节,那就不是一件好玩的事儿了,你的用户会慢慢离你而去。

网页标题:处理Wm_Killfocus消息时需要注意的地方
本文网址:http://www.gawzjz.com/qtweb2/news46/196.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联