fengqinggao大哥已经解决了我的问题 再问个 hoho

时间:2022-02-02 04:32:11
不知大家有没有发现
在Dialog 中 ctrl的WM_KILLFOCUS消息
有时会重复发送
例如
2个edit框 edit1, edit2
响应wm_killfocus小心
onkillfocusedit1()
{
AfxMessageBox("1");
}
onkillfocusedit2()
{
AfxMessageBox("2");
}

当光标焦点落在edit1 时 点edit2
俺道理系统应发送 edit 失去焦点 edit 获得焦点
但我实际测试发现 系统先发送edit2失去焦点 然后是edit1失去焦点 edit2得到焦点 为什么?
如何才能保证 从edit1 到 edit2 onkillfocusXXXX 函数只响应真正失去焦点的函数?

9 个解决方案

#1


老弟啊,你这个标题让我压力很大啊,如果没有解决,岂不是让我找地缝钻才行,呵呵。

刚才测试了一把,是你的消息框在作怪,因为你弹出消息框后,实际上是消息框获得了焦点,也就是说你的对话框此时整个失去焦点,有可能就触发了Edit2的KillFocus,你将这两个函数中的消息框分别改为:
CString sEdit1;
GetDlgItem(IDC_EDIT1)->GetWindowText(sEdit1);
GetDlgItem(IDC_EDIT1)->SetWindowText(sEdit1 + "1");//在原来的文本后面添加,便于查看;


CString sEdit2;
GetDlgItem(IDC_EDIT2)->GetWindowText(sEdit2);
GetDlgItem(IDC_EDIT1)->SetWindowText(sEdit1 + "2");

你就可以看到“实际”情况了,只有一个Edit1的KillFocus()和Edit2的GetFocus()

#2


那如果我需要在killfocus 中使用messagebox 
又不能让killfocus重复 该咋办?

#3


早上起来就一直在测试…………………………………………

#4


经过多次测试,我想真正的过程应该是这样的:
在消息响应函数OnKillFocus和OnSetFocus调用之前,KillFocus和SetFocus动作都已经执行成功,成功时调用前面两个消息响应函数,于是在你的Edit1的OnKillFocus函数中弹出那个消息框,但因为Edit2的SetFocus已经成功,所以现在焦点在Edit2上,如果此时弹出消息框,必定是让Edit2先KillFocus,也就调用了Edit2的OnKillFocus,所以在Edit1的消息框弹出之前,先弹出了Edit2的消息框

————这样给人感觉是先Edit2失去焦点,然后才是Edit1失去焦点,而实际上还是:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点
的这样的一个过程。

————上面是会出现你说的那种情况的真正原因

#5


刚才写了一大堆,因为CSDN速度太慢而全部没有上传上来,郁闷。只好再写

经过多次测试得到如下结果,应该是你前面出现那种情况的真正原因:

1、消息响应函数OnKillFocus和OnSetFocus都是KillFocus和SetFocus两个动作分别发出的,而且是成功以后发出的;
2、所以在Edit1的OnKillFocus之前,实际上Edit2已经得到了焦点,然后执行Edit1的KillFocus函数;
3、而执行这个函数时需要弹出消息框,这会导致消息框获得焦点,所以Edit2必然要先失去焦点,而且要失去焦点成功才行,一旦成功,Edit1的消息框还没有弹出的时候就必定会先执行Edit2的KillFocus函数;
3、而执行这个函数时就弹出了该函数中的消息框。
4、这样,Edit2的消息框就在Edit1的消息框之前弹出了。

所以给人感觉是先Edit2失去焦点再Edit1失去焦点
————注意:这只是给人感觉而已,实际上是这个顺序:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点



有了这个原理,应该就比较好解决了。
建议别用你说的这种机制,不好,KillFocus中带消息框等有可能会导致死循环的。
如果非要用,需要增加判断语句,你根据上面的原理,自己再好好调试,总结经验吧,我也还没有完全弄好,因为下午有会,等准备准备了,不好意思

#6


和我想的不谋而合 hoho
我也知道是这种状况 就是不知道有什么好的办法来代替 killfocus 消息
加控制我也想过 可是太麻烦
(因为我要控制的太多 而且情况不一样)
总之 谢谢大哥了 hoho

#7


结贴了 hoho
不知有什么好办法代替 响应killfocus 消息么?

#8


你把你的程序要实现的功能描述清楚一些,否则别人就都跟着你的思路走了,呵呵

还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com

#9


程序还没做 :)
就是这个问题解决不了
我就是在一个dialog上放几十个 ctrl 包括 edit combox tree list 等等
在这些 鼠标或者键盘操作 离开这些控件时
要做一些操作 比如 弹出一个子dialog 控制是否非空 combobox 的输代码选内容
还有一些综合控制 没难的东西
就是复杂...
代码有6000,7000行...

#1


老弟啊,你这个标题让我压力很大啊,如果没有解决,岂不是让我找地缝钻才行,呵呵。

刚才测试了一把,是你的消息框在作怪,因为你弹出消息框后,实际上是消息框获得了焦点,也就是说你的对话框此时整个失去焦点,有可能就触发了Edit2的KillFocus,你将这两个函数中的消息框分别改为:
CString sEdit1;
GetDlgItem(IDC_EDIT1)->GetWindowText(sEdit1);
GetDlgItem(IDC_EDIT1)->SetWindowText(sEdit1 + "1");//在原来的文本后面添加,便于查看;


CString sEdit2;
GetDlgItem(IDC_EDIT2)->GetWindowText(sEdit2);
GetDlgItem(IDC_EDIT1)->SetWindowText(sEdit1 + "2");

你就可以看到“实际”情况了,只有一个Edit1的KillFocus()和Edit2的GetFocus()

#2


那如果我需要在killfocus 中使用messagebox 
又不能让killfocus重复 该咋办?

#3


早上起来就一直在测试…………………………………………

#4


经过多次测试,我想真正的过程应该是这样的:
在消息响应函数OnKillFocus和OnSetFocus调用之前,KillFocus和SetFocus动作都已经执行成功,成功时调用前面两个消息响应函数,于是在你的Edit1的OnKillFocus函数中弹出那个消息框,但因为Edit2的SetFocus已经成功,所以现在焦点在Edit2上,如果此时弹出消息框,必定是让Edit2先KillFocus,也就调用了Edit2的OnKillFocus,所以在Edit1的消息框弹出之前,先弹出了Edit2的消息框

————这样给人感觉是先Edit2失去焦点,然后才是Edit1失去焦点,而实际上还是:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点
的这样的一个过程。

————上面是会出现你说的那种情况的真正原因

#5


刚才写了一大堆,因为CSDN速度太慢而全部没有上传上来,郁闷。只好再写

经过多次测试得到如下结果,应该是你前面出现那种情况的真正原因:

1、消息响应函数OnKillFocus和OnSetFocus都是KillFocus和SetFocus两个动作分别发出的,而且是成功以后发出的;
2、所以在Edit1的OnKillFocus之前,实际上Edit2已经得到了焦点,然后执行Edit1的KillFocus函数;
3、而执行这个函数时需要弹出消息框,这会导致消息框获得焦点,所以Edit2必然要先失去焦点,而且要失去焦点成功才行,一旦成功,Edit1的消息框还没有弹出的时候就必定会先执行Edit2的KillFocus函数;
3、而执行这个函数时就弹出了该函数中的消息框。
4、这样,Edit2的消息框就在Edit1的消息框之前弹出了。

所以给人感觉是先Edit2失去焦点再Edit1失去焦点
————注意:这只是给人感觉而已,实际上是这个顺序:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点



有了这个原理,应该就比较好解决了。
建议别用你说的这种机制,不好,KillFocus中带消息框等有可能会导致死循环的。
如果非要用,需要增加判断语句,你根据上面的原理,自己再好好调试,总结经验吧,我也还没有完全弄好,因为下午有会,等准备准备了,不好意思

#6


和我想的不谋而合 hoho
我也知道是这种状况 就是不知道有什么好的办法来代替 killfocus 消息
加控制我也想过 可是太麻烦
(因为我要控制的太多 而且情况不一样)
总之 谢谢大哥了 hoho

#7


结贴了 hoho
不知有什么好办法代替 响应killfocus 消息么?

#8


你把你的程序要实现的功能描述清楚一些,否则别人就都跟着你的思路走了,呵呵

还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com

#9


程序还没做 :)
就是这个问题解决不了
我就是在一个dialog上放几十个 ctrl 包括 edit combox tree list 等等
在这些 鼠标或者键盘操作 离开这些控件时
要做一些操作 比如 弹出一个子dialog 控制是否非空 combobox 的输代码选内容
还有一些综合控制 没难的东西
就是复杂...
代码有6000,7000行...