判断一个窗口是否被挂起【小记】?
2012-02-26 20:45
369 查看
判断一个窗口是否被挂起了(就是没有响应了),在多窗口编程了经常会用到,在给别的窗口发消息前,为了目的窗口能确定收到消息,常常在之前先检测窗口是否被挂起了,我们以前常用的方式的是使用下面的方法:
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来实现了……
// 判断一个窗口是否已经停止响应了(超时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来实现了……
相关文章推荐
- 判断一个窗口是否被挂起【小记】?
- 判断一个窗口是否被挂起【小记】?
- 判断一个窗口是否被挂起(发WM_NULL消息,或者调用IsHungAppWindow API进行测试)
- javascript如何判断一个对象是否是窗口
- 判断一个控件是否真正显示在主窗口
- 判断窗口是否挂起
- 如何判断一个窗口是否可以接受字符
- WinForm 判断一个窗口是否被打开
- MFC 判断一个窗口是否是可见状态
- 判断一个view是否在主窗口
- 判断特定窗口是否存在、线程中获取获得一个顶层窗口的句柄
- vc6代码实现: 怎样判断一个点是否在一个窗口(或对话框或控件)内?
- winform判断一个窗口是否打开并显示出来
- 请问如何判断一个窗口是否处于隐藏状态?
- 2.1: 判断一个正整数是否为质数的算法.
- 写一个函数判断一个数是否是2的乘方
- 判断Access中某个表是否已存在,不存在就创建一个
- 判断一个数是否是2的平方
- 一个高效判断字符串是否全数字的函数
- java判断文件是否是一个lnk快捷方式