在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()
刚才测试了一把,是你的消息框在作怪,因为你弹出消息框后,实际上是消息框获得了焦点,也就是说你的对话框此时整个失去焦点,有可能就触发了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重复 该咋办?
又不能让killfocus重复 该咋办?
#3
早上起来就一直在测试…………………………………………
#4
经过多次测试,我想真正的过程应该是这样的:
在消息响应函数OnKillFocus和OnSetFocus调用之前,KillFocus和SetFocus动作都已经执行成功,成功时调用前面两个消息响应函数,于是在你的Edit1的OnKillFocus函数中弹出那个消息框,但因为Edit2的SetFocus已经成功,所以现在焦点在Edit2上,如果此时弹出消息框,必定是让Edit2先KillFocus,也就调用了Edit2的OnKillFocus,所以在Edit1的消息框弹出之前,先弹出了Edit2的消息框
————这样给人感觉是先Edit2失去焦点,然后才是Edit1失去焦点,而实际上还是:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点
的这样的一个过程。
————上面是会出现你说的那种情况的真正原因
在消息响应函数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中带消息框等有可能会导致死循环的。
如果非要用,需要增加判断语句,你根据上面的原理,自己再好好调试,总结经验吧,我也还没有完全弄好,因为下午有会,等准备准备了,不好意思
经过多次测试得到如下结果,应该是你前面出现那种情况的真正原因:
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
我也知道是这种状况 就是不知道有什么好的办法来代替 killfocus 消息
加控制我也想过 可是太麻烦
(因为我要控制的太多 而且情况不一样)
总之 谢谢大哥了 hoho
#7
结贴了 hoho
不知有什么好办法代替 响应killfocus 消息么?
不知有什么好办法代替 响应killfocus 消息么?
#8
你把你的程序要实现的功能描述清楚一些,否则别人就都跟着你的思路走了,呵呵
还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com
还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com
#9
程序还没做 :)
就是这个问题解决不了
我就是在一个dialog上放几十个 ctrl 包括 edit combox tree list 等等
在这些 鼠标或者键盘操作 离开这些控件时
要做一些操作 比如 弹出一个子dialog 控制是否非空 combobox 的输代码选内容
还有一些综合控制 没难的东西
就是复杂...
代码有6000,7000行...
就是这个问题解决不了
我就是在一个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()
刚才测试了一把,是你的消息框在作怪,因为你弹出消息框后,实际上是消息框获得了焦点,也就是说你的对话框此时整个失去焦点,有可能就触发了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重复 该咋办?
又不能让killfocus重复 该咋办?
#3
早上起来就一直在测试…………………………………………
#4
经过多次测试,我想真正的过程应该是这样的:
在消息响应函数OnKillFocus和OnSetFocus调用之前,KillFocus和SetFocus动作都已经执行成功,成功时调用前面两个消息响应函数,于是在你的Edit1的OnKillFocus函数中弹出那个消息框,但因为Edit2的SetFocus已经成功,所以现在焦点在Edit2上,如果此时弹出消息框,必定是让Edit2先KillFocus,也就调用了Edit2的OnKillFocus,所以在Edit1的消息框弹出之前,先弹出了Edit2的消息框
————这样给人感觉是先Edit2失去焦点,然后才是Edit1失去焦点,而实际上还是:
Edit1失去焦点、Edit2得到焦点、Edit2失去焦点、Edit2得到焦点
的这样的一个过程。
————上面是会出现你说的那种情况的真正原因
在消息响应函数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中带消息框等有可能会导致死循环的。
如果非要用,需要增加判断语句,你根据上面的原理,自己再好好调试,总结经验吧,我也还没有完全弄好,因为下午有会,等准备准备了,不好意思
经过多次测试得到如下结果,应该是你前面出现那种情况的真正原因:
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
我也知道是这种状况 就是不知道有什么好的办法来代替 killfocus 消息
加控制我也想过 可是太麻烦
(因为我要控制的太多 而且情况不一样)
总之 谢谢大哥了 hoho
#7
结贴了 hoho
不知有什么好办法代替 响应killfocus 消息么?
不知有什么好办法代替 响应killfocus 消息么?
#8
你把你的程序要实现的功能描述清楚一些,否则别人就都跟着你的思路走了,呵呵
还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com
还不行,而且没有什么秘密的话,给我源代码,我看看,:),fqg76@163.com
#9
程序还没做 :)
就是这个问题解决不了
我就是在一个dialog上放几十个 ctrl 包括 edit combox tree list 等等
在这些 鼠标或者键盘操作 离开这些控件时
要做一些操作 比如 弹出一个子dialog 控制是否非空 combobox 的输代码选内容
还有一些综合控制 没难的东西
就是复杂...
代码有6000,7000行...
就是这个问题解决不了
我就是在一个dialog上放几十个 ctrl 包括 edit combox tree list 等等
在这些 鼠标或者键盘操作 离开这些控件时
要做一些操作 比如 弹出一个子dialog 控制是否非空 combobox 的输代码选内容
还有一些综合控制 没难的东西
就是复杂...
代码有6000,7000行...