zoukankan      html  css  js  c++  java
  • 判断一个窗口是否被挂起(发WM_NULL消息,或者调用IsHungAppWindow API进行测试)

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

    [cpp] view plain copy
     
    1. // 判断一个窗口是否已经停止响应了(超时0.5秒)  
    2. DWORD_PTR dwResult = 0;  
    3. LRESULT lr = ::SendMessageTimeout(g_hWin, WM_NULL, 0, 0, SMTO_ABORTIFHUNG | SMTO_BLOCK, 500, &dwResult);  
    4. if (lr)  
    5. {  
    6.     // 还可以响应  
    7. }  
    8. else  
    9. {  
    10.     // 已经停止响应了(俗话说的窗口挂死了)  
    11. }  

          后来在(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来实现了……

    http://blog.csdn.net/magictong/article/details/7296250

  • 相关阅读:
    HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
    如何制作一个没有任何窗体的,隐藏在后台的程序
    ActiveMQ持久化消息(转)
    ActiveMQ发布订阅模式(转)
    .Net平台下ActiveMQ入门实例(转)
    SQL重复记录查询的几种方法(转)
    XML 解析中,如何排除控制字符
    事件委托
    margin重叠
    office web apps 部署-搭建域控服务器
  • 原文地址:https://www.cnblogs.com/findumars/p/6143423.html
Copyright © 2011-2022 走看看