判断一个窗口是否被挂起【小记】?

      判断一个窗口是否被挂起了(就是没有响应了),在多窗口编程了经常会用到,在给别的窗口发消息前,为了目的窗口能确定收到消息,常常在之前先检测窗口是否被挂起了,我们以前常用的方式的是使用下面的方法:

// 判断一个窗口是否已经停止响应了(超时0.5秒)
DWORD_PTR dwResult = 0;
LRESULT lr = ::SendMessageTimeout(g_hWin, WM_NULL, 0, 0, SMTO_ABORTIFHUNG | SMTO_BLOCK, 500, &dwResult);
if (lr)
{
	// 还可以响应
}
else
{
	// 已经停止响应了(俗话说的窗口挂死了)
}
      后来在(http://blog.csdn.net/wingeek/article/details/3875903)看到一种使用IsHungAppWindow这个API来直接判断窗口是否挂起的的方法,从MSDN上面看(http://msdn.microsoft.com/en-us/library/ms633526.aspx),这个API从windows2000就已经开始提供了,但是直到windowsxp_sp1和windows2003开始才提供了SDK。开始猜测是不是内部就是使用SendMessageTimeout实现,实时跟踪了下,发现不是。下面就是IsHungAppWindow的实现代码:

      77D69C61 >  8BFF            MOV EDI,EDI
      77D69C63    55              PUSH EBP
      77D69C64    8BEC            MOV EBP,ESP
      77D69C66    6A 04           PUSH 4
      77D69C68    FF75 08         PUSH DWORD PTR SS:[EBP+8]
      77D69C6B    E8 6BEAFAFF     CALL USER32.77D186DB
      77D69C70    F7D8            NEG EAX
      77D69C72    1BC0            SBB EAX,EAX
      77D69C74    F7D8            NEG EAX
      77D69C76    5D              POP EBP
      77D69C77    C2 0400         RETN 4


      77D186DB    B8 E3110000     MOV EAX,11E3
      77D186E0    BA 0003FE7F     MOV EDX,7FFE0300
      77D186E5    FF12            CALL DWORD PTR DS:[EDX] ; ntdll.KiFastSystemCall
      77D186E7    C2 0800         RETN 8

      在IsHungAppWindow内部其实很简单,调用了USER32.77D186DB这个函数,这个函数其实就是NtUserQueryWindow(从后面可以看出77D186DB内部直接就调往内核了调用了,功能号EAX是11E3),其中7FFE0300既是KiFastSystemCall的地址,在看调用NtUserQueryWindow的地方,Push了两个参数,也就是NtUserQueryWindow(hwnd, 4),第一个参数是目的窗口的句柄,第二个参数是查询ID,也就是标明想查这个窗口的什么信息,4代表是查这个窗口是否挂起了,直接由ring0来实现了……

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值