• 判断一个窗口是否被挂起(发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

  • 相关阅读:
    SpringMVC中静态获取request对象 Spring中获取 HttpServletRequest对象【转载】
    springcloud 的loadbalancer 轮询算法切换方法 2021.4.3
    springboot项目启动增加图标
    rabbitmq 端口作用以及修改方法
    centos8 安装rabbitmq
    springcloud config client Value获取不到信息的问题的处理方法
    springcloud config配置git作为数据源然后启动报错 If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
    Sublime Text的列模式如何操作
    centos8 安装redis
    jQuery简单的Ajax调用
  • 原文地址:https://www.cnblogs.com/findumars/p/6143423.html
Copyright © 2020-2023  润新知