救助WM_KICKIDLE机制

dianhui 2011-03-21 10:58:34
最近在调试一个程序时,出现了一个较头痛的问题,大概是这样的:
一个框架主窗口,在主窗口内可以打开一些模态对话框,在测试运行中,发现程序所使用的CPU内存不断往上升(用系统的任务管理器查看到),而此时程序并没有做任何工作,仅起动了窗口界面而已,用SPY++查看发现,当程序在主窗口中打开一个子对话框窗口时,该子对话框窗口就不停的收到一个叫WM_KICKIDLE(仅只收到该消息,因为我没有做任何其它操作)的消息,使得该程序占用的CPU及内存资源都不断增加。
我再要说明一下,上面这种情况,并非测试该程序时总是出现,是有时出现,有时就没有出现!即有时主窗口打开子对话框窗口时,子窗口运行正常,CPU及内存资源占用也正常,而有时则是子对话框窗口不停的收到消息WM_KICKIDLE及至程序崩溃。注:两种情况程序都是一样,没有做过改动!
我在网上找查一些关于WM_KICKIDLE消息相关知识,发现少之又少,只是说该消息是用于空闲时处理,不明白?难道是我的程序没有做任何操作时,系统就向我发送不停的发送WM_KICKIDLE消息,而且要命的是,我收到该消息后却使程序占用大量的CPU资源?我想应该不是这样的,因为我在写其它程序时并没有这样的不停的收到WM_KICKIDLE消息啊!
没有办法,那位高人有对该消息撑握的指点一下,我的程序怎么会这样,感激不尽!
...全文
758 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
dianhui 2011-04-04
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 opqit 的回复:]

兄弟,不用找了。code量大的话很难中的。
直接上调试器吧,立马就能找到的。用我上面讲的方法。

其实你说内存一直涨,在RTLallocateHeap这个函数上下断点是能找到内存泄露的。(当然我这里说的是code用C++的new来分配的内存)
[/Quote]

感谢你提醒,说真的,Windbg我没用过,现在要学习用用,不懂再向你请教!
schlafenhamster 2011-04-04
  • 打赏
  • 举报
回复
//
So, how do you handle idle processing in a dialog-based app where the dialog has no parent window? Fortunately, it's trivial. The MFC developers provided a hook: WM_KICKIDLE. RunModalLoop sends this MFC-private message repeatedly when there are no messages in your dialog's queue just the way CWinThread::Run calls OnIdle. RunModalLoop even passes a counter and increments it for you. In effect, WM_KICKIDLE is the dialog equivalent of OnIdle. (Historical note: earlier versions of MFC did the modal/modeless swap and WM_KICKIDLE thing for property sheets. Apparently it worked so well they decided to make all modal dialogs modeless.)

opqit 2011-03-28
  • 打赏
  • 举报
回复
兄弟,不用找了。code量大的话很难中的。
直接上调试器吧,立马就能找到的。用我上面讲的方法。

其实你说内存一直涨,在RTLallocateHeap这个函数上下断点是能找到内存泄露的。(当然我这里说的是code用C++的new来分配的内存)
dianhui 2011-03-28
  • 打赏
  • 举报
回复
感谢大家,我再找找看!
opqit 2011-03-28
  • 打赏
  • 举报
回复
上调试器(Windbg),看看这个消息是从哪里来的。
你可以对kernel32!PostmessageA and kernel32!SendmessagA for MSCB,或者kernel32!PostmessageW and kernel32!SendmessagW for unicode版本设置断点,看看哪个时候的堆栈信息,就能知道这个消息是从哪里来的了。
许文君 2011-03-28
  • 打赏
  • 举报
回复
问题应该出在消息循环,可以检查下其他消息,是否有消息未返回等问题导致。
枫桦沐阳 2011-03-28
  • 打赏
  • 举报
回复
那是真不知道了,肯定是你代码出问题了。
出现这种现象,正常情况下,只可能是WM_KICKIDLE的处理函数返回了TRUE.
难不能你把系统默认的处理都改了?
dianhui 2011-03-25
  • 打赏
  • 举报
回复
dianhui 2011-03-25
  • 打赏
  • 举报
回复
dianhui 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ynb119 的回复:]

引用 12 楼 dianhui 的回复:
我没有添加过WM_KICKIDLE消息,说实在,如果不是在这里出现这么个问题,我还不知道有这么个消息!


你所说的一直出现是不是鼠标在画面移动的时候,如果鼠标不在画面内。不会有WM_KICKIDLE消息吧?
[/Quote]
鼠标不在画面移动,我没有对程序做任何操作,包括鼠标在画面移动!上张截图给大家看吧!那有这样不停的收到WM_KICKIDLE消息的!
枫桦沐阳 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 dianhui 的回复:]
收到WM_KICKIDLE是正常的,可是我这儿是不停的收到WM_KICKIDLE消息,及至程序崩溃!
[/Quote]

你程序中是不是添加了WM_KICKIDLE消息?

系统默认该消息就是返回FALSE,如果你添加了该消息但是却没有返回FALSE的话,也会出现你所说的现象。

本来该消息就是在画面收到了正常的消息以后,如果之后有空闲就发给画面一个WM_KICKIDLE,因为系统默认处理消息WM_KICKIDLE的返回值是FALSE,所以之后下一个正常消息来之前,即便是空闲也不再发了。

如果你添加了WM_KICKIDLE但是却没有返回FALSE,如果你的画面什么都没做,那就没有其他正常消息,总是处于空闲,系统自然就会一直不停的给画面发WM_KICKIDEL消息。

WM_KICKIDLE里边有个参数,WM_KICKIDLE发送的次数,如果你真需要处理空闲时间,那就再根据次数适当的时候返回FALSE。但不能总是返回TRUE.
枫桦沐阳 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 dianhui 的回复:]
我没有添加过WM_KICKIDLE消息,说实在,如果不是在这里出现这么个问题,我还不知道有这么个消息!
[/Quote]

你所说的一直出现是不是鼠标在画面移动的时候,如果鼠标不在画面内。不会有WM_KICKIDLE消息吧?
dianhui 2011-03-23
  • 打赏
  • 举报
回复
我没有添加过WM_KICKIDLE消息,说实在,如果不是在这里出现这么个问题,我还不知道有这么个消息!
TandyT 2011-03-22
  • 打赏
  • 举报
回复
没遇到这情况,而且是有时会出现有时不会出现的。。。。一般调用模态对话框,没试过会导致 CPU 占用超标的。。。。。应该还是代码的问题而不是因为弹出了模态对话框就导致这样。
  • 打赏
  • 举报
回复



学习
aiwnx 2011-03-22
  • 打赏
  • 举报
回复

// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
{
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
}
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
{
// stop idle processing next time
bIdle = FALSE;
}


摘自RunModalLoop()中的一段代码
楼主如果想深究其原因也很简单,使用调试器在出现问题的时候attach到程序上,查看此时主线程的调用堆栈,就能找到罪魁祸首了
dianhui 2011-03-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 aiwnx 的回复:]

在WM_KICKIDLE的处理函数里return FALSE;就不会导致CPU占用率上升了!
[/Quote]
你说的这个我知道,问是谁在写程序都在窗口类里映射该消息函数了?没有,很少有人去处理这个消息,所以我遇到这个消息跳出来占用CPU肯定是有原因的,我要找到根本原因,WM_KICKIDLE消息不停袭来的原因!
aiwnx 2011-03-22
  • 打赏
  • 举报
回复
在WM_KICKIDLE的处理函数里return FALSE;就不会导致CPU占用率上升了!
dianhui 2011-03-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 visualeleven 的回复:]

http://www.tek-tips.com/viewthread.cfm?qid=691609
[/Quote]

你给的这个网址进不去啊!期待大家关注……
加载更多回复(3)

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧